1
votes

I'm trying to create a menu where users pick an option and some text with information is shown. I'm not being able to show any information with the code I have. Any ideas? I've tried capturing users callback_data with "opciones" but nothing ever happens.

# ! python3

from telegram.ext import Updater, CommandHandler, MessageHandler, Filters, CallbackQueryHandler
from telegram import InlineKeyboardButton, InlineKeyboardMarkup

import logging
logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', level=logging.INFO)

############################### Bot ############################################
def start(update, context):
    context.bot.send_message(chat_id=update.effective_chat.id, text="¡Hola!")

def info(update, context):
    update.message.reply_text(main_menu_message(),
                              reply_markup=main_menu_keyboard())

def main_menu(update, context):
    query = update.callback_query
    query.answer()
    query.edit_message_text(
        text=main_menu_message(),
        reply_markup=main_menu_keyboard())

def cs_menu(update, context):
    query = update.callback_query
    query.answer()
    query.edit_message_text(
        text=cms_menu_message(),
        reply_markup=cs_menu_keyboard())

def omenu(update, context):
    query = update.callback_query
    query.answer()
    query.edit_message_text(
        text=omenu_message(),
        reply_markup=omenu_keyboard())

def d_menu(update, context):
    query = update.callback_query
    query.answer()
    query.edit_message_text(
        text=dsl_menu_message(),
        reply_markup=ds_menu_keyboard())

def opciones(update, context):
    query = update.callback_query
    query.answer()
    if query.data == "cm11":
        query.edit_message_text(text="Test 1")
    elif query.data == "cm12":
        query.edit_message_text(text="Test 2")
    elif query.data == "cm13":
        query.edit_message_text(text="Test 3")

def probando(update, context):
    context.bot.send_message(chat_id=update.effective_chat.id, text="Probando las funciones.")

def unknown(update, context):
    context.bot.send_message(chat_id=update.effective_chat.id, text="No entiendo ese comando.")

############################ Keyboards #########################################
def main_menu_keyboard():
    keyboard = [[InlineKeyboardButton('CMs', callback_data='cm1')],
                [InlineKeyboardButton('Os', callback_data='om2')],
                [InlineKeyboardButton('Xs', callback_data='dm3')]]
    return InlineKeyboardMarkup(keyboard)

def cs_menu_keyboard():
    keyboard = [[InlineKeyboardButton('Option 1-1', callback_data='cm11')],
                [InlineKeyboardButton('Option 1-2', callback_data='cm12')],
                [InlineKeyboardButton('Option 1-3', callback_data='cm13')],
                [InlineKeyboardButton('Option 1-4', callback_data='cm14')],
                [InlineKeyboardButton('Option 1-5', callback_data='cm15')],
                [InlineKeyboardButton('Menú principal', callback_data='main')]]
    return InlineKeyboardMarkup(keyboard)

def omenu_keyboard():
    keyboard = [[InlineKeyboardButton('Option 2-1', callback_data='om21')],
                [InlineKeyboardButton('Option 2-2', callback_data='om22')],
                [InlineKeyboardButton('Option 2-3', callback_data='om23')],
                [InlineKeyboardButton('Option 2-4', callback_data='om24')],
                [InlineKeyboardButton('Menú principal', callback_data='main')]]
    return InlineKeyboardMarkup(keyboard)

def ds_menu_keyboard():
    keyboard = [[InlineKeyboardButton('Option 3-1', callback_data='dm31')],
                [InlineKeyboardButton('Option 3-2', callback_data='dm32')],
                [InlineKeyboardButton('Option 3-3', callback_data='dm33')],
                [InlineKeyboardButton('Option 3-4', callback_data='dm34')],
                [InlineKeyboardButton('Menú principal', callback_data='main')]]
    return InlineKeyboardMarkup(keyboard)

############################# Messages #########################################
def main_menu_message():
    return 'First menu'

def cs_menu_message():
    return 'Second menu'

def omenu_message():
    return 'Third menu'

def ds_menu_message():
    return 'Fourth menu'

############################# Handlers #########################################
if __name__ == "__main__":
    TOKEN = 'TOKEN'
    updater = Updater(token=TOKEN, use_context=True)

    dispatcher = updater.dispatcher
    dispatcher.add_handler(CommandHandler('start', start))
    dispatcher.add_handler(CommandHandler('info', info))
    dispatcher.add_handler(CommandHandler('probando', probando))
    dispatcher.add_handler(MessageHandler(Filters.command, unknown))
    updater.dispatcher.add_handler(CallbackQueryHandler(main_menu, pattern='main'))
    updater.dispatcher.add_handler(CallbackQueryHandler(cs_menu, pattern='cm1'))
    updater.dispatcher.add_handler(CallbackQueryHandler(omenu, pattern='om2'))
    updater.dispatcher.add_handler(CallbackQueryHandler(d_menu, pattern='dm3'))
    updater.dispatcher.add_handler(CallbackQueryHandler(opciones))

    updater.start_polling()

    # updater.start_polling(allowed_updates=[])

I've also tried to add the if part to the cs_menu but nothing happened.

1
Try placing the last opciones handler on top of other handlers. - Alen Paul Varghese
Tried that, the menus now don't work. - elRestaurador
if I were you, i tried adding a single callback_query handler: and filters out the data using if else statement like if context.data == "cm1": do something ; elif "dm1" inn context.data: do another thing at the end there will only be one handler for callbackquery - Alen Paul Varghese
mmm i'm not sure to fully understand - elRestaurador
check this in this project i am using only a single callback query handler github.com/alenpaul2001/Web-Screenshot-Bot/blob/… - Alen Paul Varghese

1 Answers

0
votes

For complicated dialogs like this, I would recommend to use ConversationHandler (see official example from python-telegram-bot library). Using it you will always know where user is, what are message/keyboard to show and how it can react on future input.