You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.23 15:28:14