如何使用python-telegram-bot获取并存储用户回复消息
如何用python-telegram-bot获取用户对图片消息的回复并存储?
你现在的问题在于直接用Bot类发送消息是单次同步调用,没法持续监听用户的后续回复。python-telegram-bot提供了更高级的Application和Handler系统来处理这类对话交互场景,下面给你两种可行的解决方案:
方案一:使用ConversationHandler管理对话状态
这种方式适合明确的“一问一答”流程,通过状态标记来控制机器人的行为逻辑:
from telegram import Update from telegram.ext import ( ApplicationBuilder, CommandHandler, MessageHandler, filters, ContextTypes, ConversationHandler ) # 定义对话状态常量 ASKING = 1 async def start(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int: # 获取当前用户ID user_id = update.effective_chat.id image_path = './image.png' # 发送图片并提问 with open(image_path, 'rb') as my_image: await context.bot.send_photo(chat_id=user_id, photo=my_image, caption='What is this?') # 进入等待用户回复的状态 return ASKING async def handle_reply(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int: # 获取用户的文本回复 user_reply = update.message.text # 这里实现存储逻辑:可以存到变量、文件或数据库 print(f"用户[{update.effective_chat.id}]的回复:{user_reply}") # 示例:追加到文本文件 with open('user_replies.txt', 'a', encoding='utf-8') as f: f.write(f"用户ID {update.effective_chat.id}: {user_reply}\n") # 回复用户确认收到 await update.message.reply_text(f"已收到你的回复:{user_reply}") # 结束对话 return ConversationHandler.END async def cancel(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int: await update.message.reply_text("对话已取消") return ConversationHandler.END def main(): token = '1234567890:ABCdEffGH-IJKlm1n23oPqrst_UVzAbcdE4' # 构建Application实例 application = ApplicationBuilder().token(token).build() # 创建对话处理器 conv_handler = ConversationHandler( entry_points=[CommandHandler('start', start)], # 触发对话的入口命令 states={ # 在ASKING状态下,监听用户的文本消息(排除命令类消息) ASKING: [MessageHandler(filters.TEXT & ~filters.COMMAND, handle_reply)] }, fallbacks=[CommandHandler('cancel', cancel)] # 取消对话的命令 ) application.add_handler(conv_handler) # 启动机器人的轮询模式 application.run_polling() if __name__ == '__main__': main()
方案二:用user_data跟踪用户状态
如果你的场景不需要严格的对话流程,也可以用context.user_data来存储每个用户的状态标记,这种方式更灵活:
from telegram import Update from telegram.ext import ApplicationBuilder, CommandHandler, MessageHandler, filters, ContextTypes # 定义状态键 WAITING_FOR_REPLY = 'waiting_for_reply' async def start(update: Update, context: ContextTypes.DEFAULT_TYPE): user_id = update.effective_chat.id image_path = './image.png' with open(image_path, 'rb') as my_image: await context.bot.send_photo(chat_id=user_id, photo=my_image, caption='What is this?') # 在用户专属数据中标记:当前正在等待回复 context.user_data[WAITING_FOR_REPLY] = True async def handle_all_messages(update: Update, context: ContextTypes.DEFAULT_TYPE): # 检查当前用户是否处于等待回复的状态 if context.user_data.get(WAITING_FOR_REPLY, False): user_reply = update.message.text # 执行存储逻辑 with open('user_replies.txt', 'a', encoding='utf-8') as f: f.write(f"用户ID {update.effective_chat.id}: {user_reply}\n") await update.message.reply_text(f"已收到你的回复:{user_reply}") # 清除等待状态 del context.user_data[WAITING_FOR_REPLY] else: # 非等待状态下的消息可以自定义处理 await update.message.reply_text("请先发送/start开始对话哦") async def cancel(update: Update, context: ContextTypes.DEFAULT_TYPE): # 清除等待状态(如果存在) if WAITING_FOR_REPLY in context.user_data: del context.user_data[WAITING_FOR_REPLY] await update.message.reply_text("对话已取消") def main(): token = '1234567890:ABCdEffGH-IJKlm1n23oPqrst_UVzAbcdE4' application = ApplicationBuilder().token(token).build() application.add_handler(CommandHandler('start', start)) application.add_handler(CommandHandler('cancel', cancel)) # 监听所有非命令类文本消息 application.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, handle_all_messages)) application.run_polling() if __name__ == '__main__': main()
注意事项
- 确保你的python-telegram-bot版本是v13或以上,v12及以下版本使用的是
Updater而非Application,API结构不同。 - 如果需要处理非文本回复(比如图片、语音),可以修改
filters参数,比如filters.PHOTO、filters.VOICE等。 - 存储逻辑可以根据需求调整,比如存入SQLite、MySQL等数据库,或者JSON文件。
内容的提问来源于stack exchange,提问作者Ntakwetet
相关产品推荐
相关产品推荐

