Telegram调查机器人:输入类问题完成后内联键盘无法显示的问题求助
Telegram调查机器人:输入类问题完成后内联键盘无法显示的问题求助
我仔细看了你的代码,发现几个关键问题导致内联键盘无法正常显示,咱们一步步来解决:
1. 对话状态的处理器类型不匹配
你的Q3状态配置的是CallbackQueryHandler,但在Q2_handler处理完用户的文本输入后,应该主动发送Q3的问题和内联键盘,而不是等待用户的回调操作。同时,Q3这个状态其实是多余的——你应该在Q2_handler处理完输入后,直接触发发送Q3的键盘逻辑,然后进入Q4状态等待用户的回调选择。
2. Q2_handler的逻辑错误
你在Q2_handler里重复发送了"Write time when you been on water station",这会让用户困惑,而且没有触发后续的内联键盘发送。正确的逻辑应该是:接收用户输入的时间后,直接发送Q3的问题(停留时长)和对应的内联键盘,然后返回Q4状态等待用户的回调。
3. Q6_handler的处理器类型错误
Q6是内联键盘选择(是否满意服务),但你给Q6状态配置的是MessageHandler,这会导致用户点击内联键盘后,系统无法正确处理回调,反而等待用户输入文本,自然也不会触发后续流程。
4. 部分回调数据与状态映射混乱
比如Q1的两个内联按钮回调数据都是str(Q1),这会导致无法区分用户选择的是Yes还是No,需要把回调数据改成具体选项(比如"yes"、"no"),或者和状态区分开。
以下是修正后的完整代码:
import logging from telegram import InlineKeyboardButton, InlineKeyboardMarkup, Update from telegram.ext import ( CallbackQueryHandler, CommandHandler, ConversationHandler, MessageHandler, Updater, Filters, ) logging.basicConfig( format="%(asctime)s - %(name)s - %(levelname)s - %(message)s", level=logging.INFO ) logger = logging.getLogger(__name__) # 移除多余的Q3状态,简化状态映射 Q1, Q2, Q4, Q5, Q6, AGE = 0, 1, 3, 4, 5, 6 user_data = {} def start_handler(update: Update, context): keyboard = [ [ InlineKeyboardButton("Yes", callback_data="yes"), # 改成具体选项值,方便区分用户选择 InlineKeyboardButton("No", callback_data="no"), ] ] reply_markup = InlineKeyboardMarkup(keyboard) update.message.reply_text("Are you currently at water station?", reply_markup=reply_markup) return Q1 def Q1_handler(update: Update, context): query = update.callback_query query.answer() user_data[Q1] = query.data # 存储用户选择的具体值,而非整个query对象 query.edit_message_text("Please write the time you were at the water station:") return Q2 def Q2_handler(update: Update, context): user_data[Q2] = update.message.text # 处理完用户输入后,直接发送Q3的问题和内联键盘 keyboard = [ [ InlineKeyboardButton("5", callback_data="5"), InlineKeyboardButton("5-15", callback_data="5-15"), InlineKeyboardButton("15-30", callback_data="15-30"), InlineKeyboardButton(">30", callback_data=">30"), ] ] reply_markup = InlineKeyboardMarkup(keyboard) update.message.reply_text("How much time did you spend at the water station?", reply_markup=reply_markup) return Q4 # 直接进入Q4状态等待用户回调 def Q4_handler(update: Update, context): query = update.callback_query query.answer() user_data[Q4] = query.data # 发送Q5的问题和键盘(修改问题描述避免重复) keyboard = [ [ InlineKeyboardButton("5", callback_data="5"), InlineKeyboardButton("5-15", callback_data="5-15"), ] ] reply_markup = InlineKeyboardMarkup(keyboard) query.edit_message_text("How much time did you spend waiting?", reply_markup=reply_markup) return Q5 def Q5_handler(update: Update, context): query = update.callback_query query.answer() user_data[Q5] = query.data # 发送Q6的问题和键盘 keyboard = [ [ InlineKeyboardButton("Yes", callback_data="yes"), InlineKeyboardButton("No", callback_data="no"), ] ] reply_markup = InlineKeyboardMarkup(keyboard) query.edit_message_text("Are you satisfied with the service?", reply_markup=reply_markup) return Q6 def Q6_handler(update: Update, context): query = update.callback_query query.answer() user_data[Q6] = query.data # 存储用户的满意度选择 query.edit_message_text("Please enter your age:") return AGE def finish_handler(update: Update, context): user_data[AGE] = update.message.text # 格式化输出用户数据,更易读 result_text = ( f"Survey Results:\n" f"Q1: At water station now? {user_data[Q1]}\n" f"Q2: Time at station: {user_data[Q2]}\n" f"Q3: Time spent at station: {user_data[Q4]}\n" f"Q4: Waiting time: {user_data[Q5]}\n" f"Q5: Satisfied with service? {user_data[Q6]}\n" f"Age: {user_data[AGE]}" ) update.message.reply_text(result_text) return ConversationHandler.END def cancel_handler(update: Update, context): update.message.reply_text("Survey cancelled. Bye!") return ConversationHandler.END def main(): updater = Updater( token="TOKEN", use_context=True, ) dp = updater.dispatcher conv_handler = ConversationHandler( entry_points=[CommandHandler("start", start_handler)], states={ Q1: [CallbackQueryHandler(Q1_handler)], # 只处理文本消息,排除命令类消息 Q2: [MessageHandler(Filters.text & ~Filters.command, Q2_handler)], Q4: [CallbackQueryHandler(Q4_handler)], Q5: [CallbackQueryHandler(Q5_handler)], # Q6改为CallbackQueryHandler,匹配内联键盘回调 Q6: [CallbackQueryHandler(Q6_handler)], AGE: [MessageHandler(Filters.text & ~Filters.command, finish_handler)] }, fallbacks=[CommandHandler("cancel", cancel_handler)], ) dp.add_handler(conv_handler) updater.start_polling() updater.idle() if __name__ == "__main__": main()
关键修改说明:
- 移除了多余的
Q3状态:Q2处理完后直接发送内联键盘,无需额外状态等待 - 修正了各状态的处理器类型:
Q6状态改为CallbackQueryHandler,匹配内联键盘的回调处理 - 修复了
Q2_handler的逻辑:不再重复发送提示,直接触发后续的内联键盘发送 - 优化了回调数据存储:存储用户选择的具体选项值(而非callback query对象),方便后续使用
- 调整了问题描述:避免重复文本,让用户更清晰
- 完善了
cancel_handler:给用户反馈并结束对话
这样修改后,输入类问题完成后内联键盘就能正常显示,整个调查流程也能顺畅运行啦!
备注:内容来源于stack exchange,提问作者Oleksii Vasylenko
相关产品推荐
相关产品推荐

