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

如何在python-telegram-bot的for循环中获取用户下一条消息?

解决Telegram Bot循环中获取用户下一条消息的问题

核心错误分析

  • 阻塞异步循环:time.sleep(10)会直接阻塞bot的异步事件循环,这段时间内bot无法接收或处理任何用户消息,自然拿不到输入的tag。
  • 错误的handler注册方式:在循环内动态注册MessageHandler无效——Telegram Bot的handler是全局注册的,重复添加会引发逻辑冲突,且无法和当前循环的应用上下文绑定。

正确实现方案:对话状态管理

利用Telegram Bot的ConversationHandler和context.user_data跟踪对话状态,分步骤收集每个应用的tag,避免阻塞且逻辑清晰。

步骤1:定义对话状态与处理器

from telegram import Update
from telegram.ext import (
    ContextTypes,
    MessageHandler,
    filters,
    CallbackQueryHandler,
    ConversationHandler
)
import pandas as pd

# 定义对话状态常量
WAITING_FOR_TAG = 1

async def end(update: Update, context: ContextTypes.DEFAULT_TYPE):
    await update.callback_query.edit_message_reply_markup(reply_markup=None)
    
    # 解析回调数据
    callback_data = update.callback_query.data.split(',')
    subsystem = callback_data[0]
    env = callback_data[1]
    
    # 从谷歌表格获取应用列表
    gc = GoogleSheetsUpdater().connect()
    sheet_url = f"https://docs.google.com/spreadsheets/d/{config['DEFAULT']['spreadsheetId']}"
    sheet = gc.open_by_url(sheet_url)
    ws = sheet.get_worksheet(0)
    df = pd.DataFrame(ws.get_all_records())
    apps_list = df['app'][df['subsystem'] == subsystem].tolist()
    
    # 初始化对话状态,保存到用户数据中
    context.user_data.update({
        'apps_list': apps_list,
        'current_index': 0,
        'subsystem': subsystem
    })
    
    # 发送第一个tag请求
    first_app = apps_list[0]
    await update.callback_query.edit_message_text(
        text=f"Please, send me a tag for {first_app} in {subsystem}:"
    )
    
    # 进入等待用户输入的状态
    return WAITING_FOR_TAG

async def tag_handler(update: Update, context: ContextTypes.DEFAULT_TYPE):
    tag = update.message.text
    user_data = context.user_data
    
    # 获取当前处理的应用信息
    current_idx = user_data['current_index']
    current_app = user_data['apps_list'][current_idx]
    subsystem = user_data['subsystem']
    
    # 这里添加tag的处理逻辑(比如写入表格)
    print(f"Tag received for {current_app}: {tag}")
    
    # 处理下一个应用
    current_idx += 1
    if current_idx < len(user_data['apps_list']):
        next_app = user_data['apps_list'][current_idx]
        await update.message.reply_text(
            text=f"Please, send me a tag for {next_app} in {subsystem}:"
        )
        user_data['current_index'] = current_idx
        return WAITING_FOR_TAG
    else:
        # 所有应用处理完成
        await update.message.reply_text("All tags have been collected successfully!")
        user_data.clear()
        return ConversationHandler.END

步骤2:注册对话处理器

在bot初始化时,注册ConversationHandler管理整个对话流程:

# 替换成你的callback触发模式(比如匹配以'end'开头的回调数据)
conv_handler = ConversationHandler(
    entry_points=[CallbackQueryHandler(end, pattern=r'^end.*$')],
    states={
        WAITING_FOR_TAG: [MessageHandler(filters.TEXT & ~filters.COMMAND, tag_handler)]
    },
    fallbacks=[]  # 可添加/取消等命令的处理器,用于中断对话
)

# 添加到应用中
application.add_handler(conv_handler)

方案优势

  • 非阻塞:完全基于异步逻辑,bot在等待用户输入时仍能处理其他请求。
  • 状态隔离:每个用户的对话状态保存在user_data中,不会和其他用户的流程冲突。
  • 逻辑清晰:通过ConversationHandler明确划分对话阶段,避免循环内的混乱逻辑。

内容的提问来源于stack exchange,提问作者Bergan Jar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 13:05:02