I'm trying to send the bot a command with arguments via url I've seen solutions like this: https://t.me/_bot?start=my_data, but it doesn't work for me and just follows the link to the bot. Please write how to correctly generate the url for my task, and whether an additional handler is needed for this in the code
For t.me/<bot>
you can use only some values - like start=
, game=
See doc: Deep links - Bot links
If you use start=params
then it switches to your bot
and it executes command /start params
and it shows button START
which user has to click.
If you use empty start=
or start
then it switches to your bot
but it doesn't executes command /start
.
So you may need to put all information after start=
like
https://t.me/mybot?start=getreward-id_reward
and in command start
you can use -
to split getreward-id_reward
But... there is another problem. It allows only for some chars in parameters
- for example it doesn't allow for +
or space
- so it may need to convert data to string base64
(BTW: base64 allows to use +
but telegram
may have problem with +
so it may need to use urlsafe_b64encode()
instead of popular b64encode()
)
import base64
text = '++ hello world ++'
text_base64 = base64.urlsafe_b64encode(text.encode('utf-8')).decode('utf-8')
print(f'https://t.me/mybot?start={text_base64}')
and later
async def start(update: Update, context: ContextTypes.DEFAULT_TYPE):
#print('text:', update.message.text) # /start something
#print('args:', context.args) # ['something']
text_base64 = context.args[0]
text = base64.urlsafe_b64decode(text_base64.encode('utf-8')).decode('utf-8')
print('text:', text)
await context.bot.send_message(chat_id=update.effective_chat.id, text=f"start params: {text}")
If you want to send something more complex (like list
or dict
) then you may use json
import base64
import json
data = {'method': 'xyz', 'id': 1234}
text_json = json.dumps(data)
text_base64 = base64.urlsafe_b64encode(text_json.encode('utf-8')).decode('utf-8')
print(f'https://t.me/furasbot?start={text_base64}')
and later
async def start(update: Update, context: ContextTypes.DEFAULT_TYPE):
#print('text:', update.message.text) # /start something
#print('args:', context.args) # ['something']
text_base64 = context.args[0]
text_json = base64.urlsafe_b64decode(text_base64.encode('utf-8')).decode('utf-8')
data = json.loads(text_json)
print('data:', data)
print('keys:', data.keys())
print('method:', data['method'])
print(' id:', data['id'])
await context.bot.send_message(chat_id=update.effective_chat.id, text=f"start method: {data['method'}, id: {data['id']")
EDIT:
Minimal working code for tests (with python-telegram-bot
):
import os
import logging
from telegram import Update
from telegram.ext import filters, ApplicationBuilder, ContextTypes, CommandHandler, MessageHandler
import base64
import json
def generate_link(text=None, data=None, b64=True, botname='<bot_name>'):
if text:
if b64:
output = base64.urlsafe_b64encode(text.encode('utf-8')).decode('utf-8')
else:
output = text
print(f'text: https://t.me/{botname}?start={output}')
if data:
text = json.dumps(data)
output = base64.urlsafe_b64encode(text.encode('utf-8')).decode('utf-8')
print(f'data: https://t.me/{botname}?start={output}')
generate_link(botname='furasbot', text='hello-world', b64=False)
generate_link(botname='furasbot', text='hello world')
generate_link(botname='furasbot', data={'method': 'xyz', 'id': 1234})
# ----------------------------------
logging.basicConfig(
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
level=logging.INFO
)
async def start(update: Update, context: ContextTypes.DEFAULT_TYPE):
print('text:', update.message.text) # /start something
print('args:', context.args) # ['something']
#text = str(context.args)
text_base64 = context.args[0]
try:
text = base64.urlsafe_b64decode(text_base64.encode('utf-8')).decode('utf-8')
except Exception as e: # binascii.Error: Incorrect padding
print('Exception:', e)
text = text_base64
try:
data = json.loads(text)
except Exception as e: # json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
print('Exception:', e)
data = dict()
print('text:', text)
print('data:', data)
print('keys:', data.keys())
for key, val in data.items():
print(f'> {key} = {val}')
await context.bot.send_message(chat_id=update.effective_chat.id, text=f"start params: {text}")
if __name__ == '__main__':
TOKEN = os.getenv('TELEGRAM_TOKEN')
application = ApplicationBuilder().token(TOKEN).build()
start_handler = CommandHandler('start', start)
application.add_handler(start_handler)
application.run_polling()
Some links:
https://t.me/<bot_name>?start=hello-world
https://t.me/<bot_name>?start=aGVsbG8gd29ybGQ=
https://t.me/<bot_name>?start=eyJtZXRob2QiOiAieHl6IiwgImlkIjogMTIzNH0=