Bit-by-bit
Bit-by-bit

Reputation: 41

Telegram Bot API: How to get InlineKeyboardButton's text using CallbackQuery.data?

I am coding a Telegram bot in Python and was wondering how I could get or store the value of the "text" key when I press a button in in my bot instance. As I want to use it to adapt the displayed message in the next called function (I hope that it's clear...)

My current code is this:

def live_main(update: Update, context: CallbackContext) -> None:
    query = update.callback_query
    query.answer()
    keyboard = [
        [
            InlineKeyboardButton("1", callback_data=str(LIVE)),
            InlineKeyboardButton("2", callback_data=str(LIVE))      
        ],
        [InlineKeyboardButton("Back", callback_data=str(STARTOVER))]
    ]   
    reply_markup = InlineKeyboardMarkup(keyboard)
    query.edit_message_text(
        text="How many people will attend the live session?", reply_markup=reply_markup
    )
    return FIRST

def live(update: Update, context: CallbackContext) -> None:
    query = update.callback_query
    query.answer()
    keyboard = [
        [InlineKeyboardButton("Btc", callback_data=str(PAYLIVE))],
        [InlineKeyboardButton("Paypal", callback_data=str(PAYLIVE))],
        [InlineKeyboardButton("Back", callback_data=str(LIVEM))]
    ]    
    reply_markup = InlineKeyboardMarkup(keyboard)   
    query.edit_message_text(
        text="Price for {**CallbackQuery.text**} { is {price_live/**CallbackQuery.text**)} USD or the equivalent in crypto-currencies. Please, choose your payment method. (And to be perfectly honest, we prefer crypto...)", reply_markup=reply_markup
    )
    return FIRST

So as you can see, I want to use either the "1" or "2" value from the live_main function inside the live function (where I put the CallbackQuery.text placeholders). I hope someone can help. Regards

Upvotes: 3

Views: 6753

Answers (2)

Vland
Vland

Reputation: 4262

Loop all inline_keyboards in the original message and search for the right query.data key:

def get_clicked_button_text(query):
    key = query.data
    for first_level in query.message["reply_markup"]["inline_keyboard"]:
        for second_level in first_level:
            if second_level["callback_data"] == key:
                return second_level["text"]

eg. If you click button 2:

def live_main(update: Update, context: CallbackContext) -> None:
    query = update.callback_query
    await query.answer()
    button_text = get_clicked_button_text(query)
    print(button_text)
    #2

Upvotes: 1

Oleg
Oleg

Reputation: 619

You can't directly get text of Inline button via Bot...

But you can remember what you send!

To get button text you shoud generate text id and pass it via callback_data

Example:

BUTTONS = {
    '1': 'first button',
    '2': 'second button',
    '3': 'third button',
}

markup = InlineKeyboardMarkup()
for button_id, button_text in BUTTONS.items():
    markup.add(InlineKeyboardButton(text=button_text, callback_data=f'menu:{button_id}'))

Handle CallbackQuery via labda c: c.data.startswith('menu:')

Then parse data and find it in your dict:

button_id = callback_query.data.split(':')[1]
button_text = BUTTONS.get(button_id)

Done :)

P.S.:

  • If your button names are short you can pass text to data without using id.
  • If you have many dynamic text, you can generate id of every button and store it to the database.

Upvotes: 3

Related Questions