skip to Main Content

The user interacts with my Telegram bot using an Inline Keyboard. Some buttons execute functions that are sensitive and I would like to ask the user’s confirmation before proceeding.

For example : in the main menu, the user chooses between two buttons Option 1 and Option 2. If clicked, the sensitive functions do_action_1 and do_action_2 are executed respectively.

A minimal working example is below :

from telegram import InlineKeyboardButton, InlineKeyboardMarkup, Update
from telegram.ext import Updater, CommandHandler, CallbackQueryHandler, CallbackContext


def start(update: Update, context: CallbackContext) -> None:
     update.message.reply_text('Please choose:',
                              reply_markup = keyboard_main_menu())


def main_menu(update: Update, context: CallbackContext) -> None:
    """ Displays the main menu keyboard when called. """

    query = update.callback_query
    query.answer()
    query.edit_message_text(text         = 'Please choose an option:',
                            reply_markup = keyboard_main_menu())


def keyboard_main_menu():
    """ Creates the main menu keyboard """

    keyboard = [
        [InlineKeyboardButton("Option 1", callback_data='1'),
         InlineKeyboardButton("Option 2", callback_data='2'),],
    ]

    return InlineKeyboardMarkup(keyboard)


def do_action_1(update: Update, context: CallbackContext) -> None:

    keyboard = [[InlineKeyboardButton("Main menu", callback_data='main')]]
    reply_markup = InlineKeyboardMarkup(keyboard)

    query = update.callback_query
    query.answer()
    query.edit_message_text(text=f"Selected option {query.data}n"
                                 f"Executed action 1.",
                            reply_markup=reply_markup)


def do_action_2(update: Update, context: CallbackContext) -> None:

    keyboard = [[InlineKeyboardButton("Main menu", callback_data='main')]]
    reply_markup = InlineKeyboardMarkup(keyboard)

    query = update.callback_query
    query.answer()
    query.edit_message_text(text=f"Selected option {query.data}n"
                                 f"Executed action 2.",
                            reply_markup=reply_markup)


def main() -> None:
    """Run the bot."""

    updater = Updater("TOKEN")

    updater.dispatcher.add_handler(CommandHandler('start', start))
    updater.dispatcher.add_handler(CallbackQueryHandler(main_menu, pattern='main'))
    updater.dispatcher.add_handler(CallbackQueryHandler(do_action_1, pattern='1'))
    updater.dispatcher.add_handler(CallbackQueryHandler(do_action_2, pattern='2'))

    # Start the Bot
    updater.start_polling()
    print('started')


if __name__ == '__main__':
    main()

Now, I would like to insert an intermediate step after clicking Option 1 or Option 2, displaying a keyboard "Are you sure ?" with two buttons Yes and No. Clicking Yes executes do_action_1 or do_action_2 based on the user’s choice at the previous keyboard. Clicking No would bring the user back to the main menu.

How can I do that ?

2

Answers


  1. Chosen as BEST ANSWER

    Thanks to @CallMeStag's answer, I managed to get a mwe :

    from telegram import InlineKeyboardButton, InlineKeyboardMarkup, Update
    from telegram.ext import Updater, CommandHandler, CallbackQueryHandler, CallbackContext
    
    
    def start(update: Update, context: CallbackContext) -> None:
        """Sends a message with three inline buttons attached."""
    
        update.message.reply_text('Please choose:',
                                  reply_markup = keyboard_main_menu())
    
    
    def main_menu(update: Update, context: CallbackContext) -> None:
        """ Displays the main menu keyboard when called. """
    
        query = update.callback_query
        query.answer()
        query.edit_message_text(text         = 'Please choose:',
                                reply_markup = keyboard_main_menu())
    
    
    def keyboard_main_menu():
        """ Creates the main menu keyboard """
    
        keyboard = [
            [InlineKeyboardButton("Option 1", callback_data='1'),
             InlineKeyboardButton("Option 2", callback_data='2'),],
        ]
    
        return InlineKeyboardMarkup(keyboard)
    
    
    def confirm(update: Update, context: CallbackContext) -> None:
        """Parses the CallbackQuery and updates the message text."""
    
        query = update.callback_query
        query.answer()
    
        keyboard = [
            [InlineKeyboardButton("Yes", callback_data=f'YES{query.data}'),
             InlineKeyboardButton("No",  callback_data='main'),],
        ]
    
        reply_markup = InlineKeyboardMarkup(keyboard)
    
        query.edit_message_text(text=f"Selected option {query.data}."
                                     f"Are you sure ? ",
                                reply_markup=reply_markup)
    
    
    def do_action_1(update: Update, context: CallbackContext) -> None:
    
        keyboard = [[InlineKeyboardButton("Main menu", callback_data='main')]]
        reply_markup = InlineKeyboardMarkup(keyboard)
    
        query = update.callback_query
        query.answer()
        query.edit_message_text(text=f"Selected option {query.data}n"
                                     f"Executed action 1.",
                                reply_markup=reply_markup)
    
    
    def do_action_2(update: Update, context: CallbackContext) -> None:
    
        keyboard = [[InlineKeyboardButton("Main menu", callback_data='main')]]
        reply_markup = InlineKeyboardMarkup(keyboard)
    
        query = update.callback_query
        query.answer()
        query.edit_message_text(text=f"Selected option {query.data}n"
                                     f"Executed action 2.",
                                reply_markup=reply_markup)
    
    
    def main() -> None:
        """Run the bot."""
        # Create the Updater and pass it your bot's token.
        updater = Updater("TOKEN")
    
        updater.dispatcher.add_handler(CommandHandler('start', start))
        updater.dispatcher.add_handler(CallbackQueryHandler(main_menu, pattern='main'))
        updater.dispatcher.add_handler(CallbackQueryHandler(confirm, pattern='^(|1|2)$'))
        updater.dispatcher.add_handler(CallbackQueryHandler(do_action_1, pattern='YES1'))
        updater.dispatcher.add_handler(CallbackQueryHandler(do_action_2, pattern='YES2'))
    
    
        # Start the Bot
        updater.start_polling()
        print('started')
    
    if __name__ == '__main__':
        main()
    
    

    The bot now correctly asks for the user's confirmation before executing do_action_1 and do_action_2. Thanks a lot !


  2. You can display a keyboard with the options YES and NO and handle the input like you handled the input for the other buttons. To keep track of which action to take when the user presses YES, you can either encode that action in the callback_data or store it temporarily. See also this wiki page an Storing Data.


    Disclaimer: I’m currently the maintainer of python-telegram-bot

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search