Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[QUESTION] Having multiple CallbackQueryHandlers inside a ConversationHandler #4249

Closed
amir-rz opened this issue May 9, 2024 · 5 comments
Closed
Labels

Comments

@amir-rz
Copy link

amir-rz commented May 9, 2024

Issue I am facing

Having multiple CallbackQueryHandlers inside a ConversationHandler

I need to implement a conversation flow where the user interacts with multiple sets of inline buttons (InlineKeyboardMarkup). Each set of inline buttons should have its own CallbackQueryHandler within the ConversationHandler.

My goal is to be able to access the data from the previous CallbackQueryHandler (i.e., the inline button that the user clicked) in the current CallbackQueryHandler. This way, I can keep track of the user's choices throughout the conversation.

For example, let's say the conversation flow looks like this:

  1. The bot presents the user with a set of inline buttons (Option 1, Option 2).
  2. The user selects Option 1.
  3. The bot presents the user with another set of inline buttons (Confirm, Cancel).
  4. If the user selects Confirm, the bot should be able to access the data from the previous step (Option 1) and perform the necessary actions.

Here's some sample code to illustrate what I'm trying to achieve:

from telegram import Update, InlineKeyboardButton, InlineKeyboardMarkup
from telegram.ext import (
    Updater,
    CommandHandler,
    CallbackQueryHandler,
    ConversationHandler,
    MessageHandler,
    Filters,
)

# Define the conversation states
START, OPTIONS, CONFIRM = range(3)

# Define the handler functions
def start(update: Update, context: CallbackContext) -> int:
    keyboard = [[InlineKeyboardButton("Option 1", callback_data='option1')],
                [InlineKeyboardButton("Option 2", callback_data='option2')]]
    reply_markup = InlineKeyboardMarkup(keyboard)

    update.message.reply_text('Please choose an option:', reply_markup=reply_markup)

    return START

def handle_options(update: Update, context: CallbackContext) -> int:
    query = update.callback_query
    query.answer()

    # Store the callback_data in the context
    context.user_data['choice'] = query.data

    keyboard = [[InlineKeyboardButton("Confirm", callback_data='confirm')],
                [InlineKeyboardButton("Cancel", callback_data='cancel')]]
    reply_markup = InlineKeyboardMarkup(keyboard)

    query.edit_message_text(text="You chose {}. Confirm?".format(query.data), reply_markup=reply_markup)

    return OPTIONS

def handle_confirm(update: Update, context: CallbackContext) -> int:
    query = update.callback_query
    query.answer()

    # Retrieve the previous choice from the context
    previous_choice = context.user_data.get('choice')

    if query.data == 'confirm':
        query.edit_message_text(text="You confirmed {}".format(previous_choice))
    else:
        query.edit_message_text(text="You canceled.")

    return ConversationHandler.END

# Set up the conversation handler
# ...

### Traceback to the issue

_No response_

### Related part of your code

_No response_

### Operating System

Ubuntu 24.04

### Version of Python, python-telegram-bot & dependencies

```shell
python-telegram-bot 20.8
Bot API 7.0
Python 3.12.3 (main, Apr 10 2024, 05:33:47) [GCC 13.2.0]
@amir-rz amir-rz changed the title [QUESTION] [QUESTION] Having multiple CallbackQueryHandlers inside a ConversationHandler May 9, 2024
@github-actions github-actions bot added the stale label May 13, 2024
@bqback
Copy link

bqback commented May 14, 2024

What issue are you having, exactly?

@github-actions github-actions bot removed the stale label May 15, 2024
@amir-rz
Copy link
Author

amir-rz commented May 15, 2024

What issue are you having, exactly?

I have around 50 CallbackQueryHandlers, which I believe is slowing down the app. Whenever the user clicks on an InlineKeyboardButton, all those 50 callback handlers need to be checked, let's say.
I was thinking of a way to link these inline buttons directly to their respective handlers in a simpler and more straightforward way. So, when the user clicks on a button, the app knows exactly which handler to execute instead of going through all 50 callback handlers.
BTW, I'm very new to this library and Telegram bots in general, so these are just my thoughts. I would appreciate any recommendations.

@Bibo-Joshi
Copy link
Member

So, when the user clicks on a button, the app knows exactly which handler to execute instead of going through all 50 callback handlers.

that is basically what ConversationHandler already does: it limits the possible choices to the handlers that are set in the currently active state

@amir-rz
Copy link
Author

amir-rz commented May 18, 2024

So, when the user clicks on a button, the app knows exactly which handler to execute instead of going through all 50 callback handlers.

That is basically what ConversationHandler already does: it limits the possible choices to the handlers that are set in the currently active state

I see, so is it possible to pass the callback_data of an inline button to the next state? if so, can you show me an example, please?

@Bibo-Joshi
Copy link
Member

You can save the data in e.g. user_data like you're already doing in your MWE

@amir-rz amir-rz closed this as completed May 19, 2024
@github-actions github-actions bot locked and limited conversation to collaborators May 27, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

3 participants