Search code examples
pythontelegrampython-telegram-bot

Is there a way to have either ReplyKeyboardButtons with callbacks, or InlineKeyboardButtons that write a message from the user and not the bot?


I'm working on a Telegram bot and I'm trying to implement a feature where the bot presents buttons to the user, and when the user clicks on a button, the bot should launch a defined function and echo the content of the button as a message from the user. I currently use InlineKeyboardButtons, implement the callbacks I want, and then in the callbacks have the bot reply "You answered: {clicked button text}" but this isn't really great UX.

Is there a way do do both? I've tried both ReplyKeyboardButtons and InlineKeyboardButtons, but I haven't found a way to make InlineKeyboardButtons write messages from the user's perspective rather than the bot's, or to have ReplyKeyboardButtons call callbacks.

My use case is that I have a screen that allows admins to send users of the bot messages with pre-defined response buttons. I want these response buttons to 1) send a message bubble from the user to the bot with their content and 2) trigger a callback. It seems I can only do 1 with ReplyKeyboardButtons and 2 with InlineKeyboardButtons.

Users may receive more than one message with buttons and reply in a different order compared to when they receive them so it's important that buttons and answers are linked to the messages sent.

If it's useful, I am using python-telegram-bot.


Solution

  • ReplyKeyboardButtons just send the message, you can further process that message with a MessageHandler, try this

    from telegram import Update, ReplyKeyboardMarkup
    from telegram.ext import Application, CommandHandler, MessageHandler, filters
    
    async def start(update, context):
        reply_markup = ReplyKeyboardMarkup([['Message_1'], ['Message_2']])
        await update.message.reply_text("Choose", reply_markup=reply_markup)
    
    
    async def message_handler(update, context):
        message = update.message.text
        await update.message.reply_text('You selected ' + message)
        
    def main() -> None:
        application = Application.builder().token("TOKEN").build()
    
        application.add_handler(CommandHandler("start", start))
        
        # This handler processes any message sent by the user that starts with 'Message_'
        application.add_handler(MessageHandler(filters.Regex("^Message_"), message_handler))
    
        application.run_polling(allowed_updates=Update.ALL_TYPES)
    
    main()