python-telegram-bot点击内联按钮触发ConversationHandler会话的实现方法
解决方案
要实现点击内联按钮启动会话,只需要调整ConversationHandler的入口逻辑、适配触发场景即可,具体修改如下:
1. 适配会话启动函数ask的触发场景
原来的ask仅适配命令触发场景,点击按钮触发时数据会从callback_query传入,需要做兼容处理:
def ask(update: Update, context: CallbackContext) -> int: reply_keyboard = [['Boy', 'Girl', 'Other']] # 区分触发来源 if update.message: # 命令触发场景 sender = update.message else: # 按钮回调触发场景,先应答回调避免客户端报错 query = update.callback_query query.answer() sender = query.message # 可选:编辑原来的按钮消息提示会话已启动 query.edit_message_text(text="已启动信息收集流程") sender.reply_text( 'Hi! My name is Professor Bot. I will hold a conversation with you. ' 'Send /cancel to stop talking to me.\n\n' 'Are you a boy or a girl?', reply_markup=ReplyKeyboardMarkup( reply_keyboard, one_time_keyboard=True, input_field_placeholder='Boy or Girl?' ), ) return GENDER
2. 给ConversationHandler新增按钮回调入口
ConversationHandler的入口不局限于命令,任意类型的Handler都可以作为入口,我们新增匹配callback_data='3'的回调处理器即可:
conv_handler = ConversationHandler( entry_points=[ CommandHandler('ask', ask), # 新增:点击对应按钮时也启动会话 CallbackQueryHandler(ask, pattern='^3$') ], states={ GENDER: [MessageHandler(Filters.regex('^(Boy|Girl|Other)$'), gender)], PHOTO: [MessageHandler(Filters.photo, photo), CommandHandler('skip', skip_photo)], LOCATION: [ MessageHandler(Filters.location, location), CommandHandler('skip', skip_location), ], BIO: [MessageHandler(Filters.text & ~Filters.command, bio)], }, fallbacks=[CommandHandler('cancel', cancel)], )
3. 调整处理器注册顺序
python-telegram-bot的处理器是按注册顺序匹配的,匹配到第一个符合条件的处理器就会停止向下匹配,因此要把会话处理器注册在通用按钮回调处理器前面:
def main() -> None: updater = Updater("你的机器人token") # 先注册会话处理器 updater.dispatcher.add_handler(conv_handler) updater.dispatcher.add_handler(CommandHandler('start', start)) # 通用按钮回调放在最后,处理未被会话捕获的按钮事件 updater.dispatcher.add_handler(CallbackQueryHandler(button)) updater.start_polling() updater.idle()
4. 清理冗余逻辑
删掉原来button函数里elif query.data == "3":的分支即可,该场景已经被会话入口处理器捕获,不会再走到通用回调逻辑里。
修改完成后点击「Where are you」按钮就会直接启动会话流程,不需要再发送/ask命令。
内容的提问来源于stack exchange,提问作者niaei
相关产品推荐
相关产品推荐

