Python开发Telegram机器人:命令触发后等待用户普通消息回复并存储
实现命令触发后等待用户回复的交互逻辑
Telegram机器人本身是无状态事件驱动的架构,要实现这个功能不需要复杂的异步等待逻辑,核心是 按用户ID维护单独的交互状态标记,流程清晰、对新手非常友好。
核心实现思路
- 用内存字典记录每个用户当前是否处于「等待回复」的状态
- 收到/ask命令时,给对应用户打上等待标记,发送提示消息引导用户输入
- 拦截所有用户发送的非命令类普通消息,先检查当前用户是否有等待标记:
- 有标记:把用户发送的内容存入指定变量,清除等待标记,给用户反馈存储结果
- 无标记:走默认的普通消息回复逻辑
环境准备
首先安装官方维护的python-telegram-bot v20+ 版本(目前最稳定、文档结构最清晰的版本),执行安装命令:pip install python-telegram-bot[asyncio]
完整可运行代码实现
import asyncio from telegram import Update from telegram.ext import ( ApplicationBuilder, CommandHandler, MessageHandler, ContextTypes, filters ) # 全局状态存储:键为用户chat_id,值为当前等待的交互类型 user_wait_states = {} # 存储用户提交的ask内容的变量,按chat_id区分避免多用户混淆 stored_ask_content = {} # /ask 命令处理函数 async def ask_command(update: Update, context: ContextTypes.DEFAULT_TYPE): chat_id = update.effective_chat.id # 给当前用户打上等待回复的标记 user_wait_states[chat_id] = "waiting_for_ask_reply" # 发送引导提示 await context.bot.send_message( chat_id=chat_id, text="已进入内容收集状态,请直接发送普通文本消息,发送任意命令可自动退出等待状态。" ) # 普通文本消息处理函数(仅拦截非命令的文本) async def handle_regular_text(update: Update, context: ContextTypes.DEFAULT_TYPE): chat_id = update.effective_chat.id user_input_text = update.effective_message.text # 检查用户是否处于等待状态 if chat_id in user_wait_states: # 匹配等待类型 if user_wait_states[chat_id] == "waiting_for_ask_reply": # 把用户输入存入指定变量 stored_ask_content[chat_id] = user_input_text # 清除等待标记,回到正常交互逻辑 del user_wait_states[chat_id] # 给用户反馈存储结果 await context.bot.send_message( chat_id=chat_id, text=f"✅ 内容已成功存储,你提交的内容为:\n{user_input_text}" ) return # 非等待状态下的默认回复 await context.bot.send_message( chat_id=chat_id, text="发送 /ask 命令即可触发内容收集流程" ) # 机器人启动主函数 async def main(): # 替换为你从@BotFather获取的机器人Token app = ApplicationBuilder().token("你的机器人Token").build() # 注册事件处理器:注意顺序,命令处理器必须在普通消息处理器之前注册 app.add_handler(CommandHandler("ask", ask_command)) app.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, handle_regular_text)) # 启动轮询监听消息 app.run_polling() if __name__ == "__main__": asyncio.run(main())
新手适配注意事项
- 示例里的状态和存储内容都存在内存中,机器人重启后数据会丢失,新手阶段先跑通交互逻辑即可,后续如果需要持久化存储,可以把字典替换成本地JSON文件、SQLite数据库存储
- 这套逻辑天然支持多用户并发交互,每个用户的状态按chat_id做了隔离,不会出现用户之间状态串扰的问题
- 如果需要加中途取消等待的功能,只需要新增一个
/cancel命令的处理函数,逻辑是直接把对应用户的chat_id从user_wait_states字典中删除即可 - 一定要注意处理器的注册顺序,命令处理器优先级要高于普通文本处理器,否则命令消息会被普通消息逻辑拦截,导致命令失效
内容的提问来源于stack exchange,提问作者valentino1337
相关产品推荐
相关产品推荐

