Search code examples
pythontelegramtelegram-botpython-telegram-bot

How to select one message from others telebot?


I'm making a bot for a real estate agency. Bot sends messages containing information about the apartment. Bot can send several messages at once for the user to choose from them. How can I implement the process of selecting one of the messages? When I make an inline button on a message, when the user clicks on it, then for some reason the id of the last message is returned to the bot, that is, if the bot has sent three messages with the "select" buttons, then when the first is clicked, the last one is returned. I thought to make it so that, for example, the user could make a reply to a message and thereby select a specific one, but I do not understand how to correlate the user's message and the message to which he replied. How can I do it better?


Solution

  • when the user clicks on it, then for some reason the id of the last message is returned to the bot

    This is not an expected behavior, if you're sending 3 different messages containing inline button keyboard, upon clicking on any of the buttons a new callbackquery update is created that contains the message id the user clicked on its button as well. You should check this to make sure.

    What you need is callback_data:

    InlineKeyboardButton has callback_data field. That is specifically there for your purpose, you can place apartment_id in callback_data and then when user clicks on any of the buttons, you'll also receive the callback_data and with that you will know which apartment_id the user has clicked on.

    You haven't mentioned which library you use, but check this example on a library in python.

    def start(update: Update, context: CallbackContext) -> None:
        keyboard = [
            [
                InlineKeyboardButton("Option 1", callback_data='1'),
                InlineKeyboardButton("Option 2", callback_data='2'),
            ],
            [InlineKeyboardButton("Option 3", callback_data='3')],
        ]
    
        reply_markup = InlineKeyboardMarkup(keyboard)
    
        update.message.reply_text('Please choose:', reply_markup=reply_markup)
    
    def button(update: Update, context: CallbackContext) -> None:
        query = update.callback_query
    
        # CallbackQueries need to be answered, even if no notification to the user is needed
        # Some clients may have trouble otherwise. See https://core.telegram.org/bots/api#callbackquery
        query.answer()
    
        query.edit_message_text(text="Selected option: {}".format(query.data))
    
    def main():
        # Create the Updater and pass it your bot's token.
        # Make sure to set use_context=True to use the new context based callbacks
        # Post version 12 this will no longer be necessary
        updater = Updater("TOKEN", use_context=True)
    
        updater.dispatcher.add_handler(CommandHandler('start', start))
        updater.dispatcher.add_handler(CallbackQueryHandler(button))
    

    In the example if user clicks on the first button Option 1 the query inside button function will be "1". If they click on the second button Option 2 then you will receive 2 as query. Now instead of 1 and 2 you can store each apartment's id. If you have buttons for multiple purposes you can differentiate them with short phrases like: apartment_id:1 or close_button. While processing the update, you can split the query by :, if split[0] was apartment_id then you'll process split[2] else you'll know the user has clicked on other buttons.

    So callback_data is a limited database as a solution to such problems.