Search code examples
pythontelegram-botpython-telegram-bot

How to trigger a command when an inline button is pressed?


I want to initiate a command when an inline button is pressed. This is the code:

from telegram import (
    ReplyKeyboardMarkup, ReplyKeyboardRemove, Update,
    InlineKeyboardButton, InlineKeyboardMarkup, KeyboardButton
)

from telegram.ext import (
    Application,
    CommandHandler,
    ContextTypes,
    ConversationHandler,
    CallbackQueryHandler,
    MessageHandler,
    filters,
)

# ---------------------------------------------------------------------------------------------

token = 'abc'

# ---------------------------------------------------------------------------------------------

async def start_func(update, context):
    home_btn = [
        [
            InlineKeyboardButton('home', callback_data='/home'),
            InlineKeyboardButton('profile', callback_data='executive_menu'),
        ]
    ]

    reply_markup = InlineKeyboardMarkup(home_btn)

    await update.message.reply_text('start_message', reply_markup=reply_markup)


async def thanks_func(update, context):
    await update.message.reply_text('thanks_message')


async def home_func(update, context):
    await update.message.reply_text('testing home 0')
    await update.message.reply_text('testing home 1')


async def query_func(update, context):
    query = update.callback_query
    home_func(update, context)
    await query.answer()


def main() -> None:
    application = Application.builder().token(token).build()
    # handlers /////////////////////////////////////////////////////////////
    start_handler = CommandHandler('start', start_func)
    thanks_handler = MessageHandler(filters.TEXT & (~filters.COMMAND), thanks_func)
    home_handler = CommandHandler('home', home_func)
    query_handler = CallbackQueryHandler(query_func)
    # ///////////////////////////////////////////////////////////////////////
    application.add_handler(start_handler)
    application.add_handler(thanks_handler)
    application.add_handler(home_handler)
    application.add_handler(query_handler)
    # ///////////////////////////////////////////////////////////////////////
    application.run_polling()


if __name__ == "__main__":
    main()

I am using python-telegram-bot == 20.4. When I run /start it gave me home inline button. I want to run the command /home by pressing that button. When I type /home manually it worked ok. However I want to achieve exact same behavior when i press home inline button.

I tried to await it as can be seen in query_func but it didn't work. I also tried this answer.


Solution

  • Your functions start_func and query_func rely on update.message being non-None. This is not the case for updates handled by CallbackQueryHandler - see also this wiki page. That's why the answer provided in Send a command using InlineKeyboardButton python telegram bot can not directly work.

    I recommend to write a helper function that includes the common logic that you want to execute both on commands and button presses. This helper function should be able to handle the cases where update.message is present and where instead update.callback_query is present. You can then call this helper function from both query_func and home_func.


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