Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Telegram bot API edit InlineKeyboard with python-telegram-bot not working

I'm trying to create a menu where the user can navigate on it. This is my code:

MENU, HELP = range(2)

def start(bot, update):
    keyboard = [
                 [InlineKeyboardButton('Help', callback_data='help')]
               ]

    # Create initial message:
    message = 'Welcome.'

    update.message.reply_text(message, reply_markup=InlineKeyboardMarkup(keyboard))

def help(bot, update):

    keyboard = [
                 [InlineKeyboardButton('Leave', callback_data='cancel')]
               ]


    update.callback_query.edit_message_reply_markup('Help ... help..', reply_markup=InlineKeyboardMarkup(keyboard))

def cancel(bot, update):

    update.message.reply_text('Bye.', reply_markup=ReplyKeyboardRemove())

    return ConversationHandler.END     


# Create the EventHandler and pass it your bot's token.
updater = Updater(token=config.TELEGRAM_API_TOKEN)

# Get the dispatcher to register handlers:
dispatcher = updater.dispatcher

dispatcher.add_handler(CommandHandler('start', start))
dispatcher.add_handler(CallbackQueryHandler(help, pattern='help'))
dispatcher.add_handler(CallbackQueryHandler(cancel, pattern='cancel'))

updater.start_polling()

updater.idle()

As expected, at the /start the user gets the menu 'Help'. When the user clicks on it, the function help() is triggered as expected as well.

Based on my understanding of the python-telegram-bot documentation is was supposed to have the update.callback_query.inline_message_id populated, but its value is None.

I need the update.callback_query.inline_message_id to update my InlineKeyboard menu, right ? Why is the inline_message_id empty (None) ?

Python 3.6.7
python-telegram-bot==11.1.0

Best Regards. Kleyson Rios.

like image 910
Kleyson Rios Avatar asked Oct 17 '22 05:10

Kleyson Rios


1 Answers

I believe there are 2 problems in your code.

First. In your help function, you're trying to change both the text of the message and the markup of it. But the edit_message_reply_markup method only changes the markup. So instead of

update.callback_query.edit_message_reply_markup(
    'Help ... help..',
    reply_markup=InlineKeyboardMarkup(keyboard)
)

Do this:

bot.edit_message_text(
    text='Help ... help..',
    chat_id=update.callback_query.message.chat_id,
    message_id=update.callback_query.message.message_id,
    reply_markup=InlineKeyboardMarkup(keyboard)
)
bot.answer_callback_query(update.callback_query.id, text='')

Notice the changes:

  • I replaced update.callback_query with bot.
  • IMPORTANT: I replaced edit_message_reply_markup with edit_message_text; Because the first one only changes the markup, but the second one can do both.
  • I added chat_id and message_id arguments; Because that's what it says in the documents.
  • IMPORTANT: I added a new method (bot.answer_callback_query); Because every time you handle a callback query you need to answer it (using this method). However, you can leave the text argument empty, so that it doesn't show anything.

Second. Correct me if I'm wrong, but I believe when the user presses the cancel button, you want the text of the message to be changed to "Bye." and remove the keyboard. If this is the case, what you're doing wrong is that you're sending a new message (reply_text) while trying to remove the keyboard (reply_markup=ReplyKeyboardRemove()). You can simply do it like this:

bot.edit_message_text(
    text='Bye',
    chat_id=update.callback_query.message.chat_id,
    message_id=update.callback_query.message.message_id,
)
bot.answer_callback_query(update.callback_query.id, text='')

Here, the idea is that when you edit the text of the message and don't use a markup keyboard, the previous keyboard gets automatically removed, so you don't need to use ReplyKeyboardRemove().

Here's a GIF (with a hard G) that it works!

enter image description here

like image 131
Amir Shabani Avatar answered Oct 21 '22 07:10

Amir Shabani