You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何通过Python Telegram Bot库获取聊天历史?连接池超时问题及实现可行性咨询

如何通过Python Telegram Bot库获取聊天历史?连接池超时问题及实现可行性咨询

嘿,我来帮你捋清楚这个问题。首先直接给你结论:机器人是可以获取聊天历史的,但你当前的做法有两个核心问题:用错了API,连接池的使用方式也不对,才导致了超时错误。

先说说你遇到的TimedOut错误为什么会发生:
你在handler里直接调用了update._bot.get_updates(),这里有两个明显的坑:

  • 首先update._bot是库的内部对象,不应该直接调用,正确的做法是用context.bot来获取Bot实例;
  • 其次,你的Application已经在运行run_polling()了,这个操作本身会占用连接池里的连接,你又在handler里额外发起API请求,直接把20个连接池资源耗尽了,自然就触发了超时。调大连接池尺寸(比如改成30)能临时缓解,但这不是根本解决办法——因为你用错了获取历史的API。

正确获取聊天历史的方式

get_updates()这个方法是用来拉取未被机器人处理过的新更新的,不是用来查询旧历史的。Telegram服务器只会保留最近24小时左右的未处理更新,如果你已经用polling处理过这些消息,get_updates()根本拿不到。要获取真正的历史消息,你应该用get_chat_history()方法(针对python-telegram-bot v20+版本)。

给你改一下你代码里的关键部分:

async def menu_callback(update: Update, context: ContextTypes.DEFAULT_TYPE):
    client = await get_client(update)
    logger.error(client.stage)
    match client.stage:
        case Stage.some_stage:
            logger.error(update.message.text)
            logger.error(update.message)
            
            # 替换掉原来的get_updates,用正确的方式拿历史
            chat_id = update.effective_chat.id
            try:
                # 获取最近10条聊天历史,你可以调整limit的数值(最大支持100)
                chat_history = await context.bot.get_chat_history(chat_id=chat_id, limit=10)
                for msg in chat_history:
                    logger.error(f"历史消息ID: {msg.message_id}, 内容: {msg.text}")
            except Exception as e:
                logger.error(f"获取历史失败: {str(e)}")
            
            last_update_id = update.update_id
            # 你的其他逻辑...

一些重要的注意点

  • 权限要求:机器人必须在目标聊天里(私人聊天要和用户聊过,群组里机器人必须是成员),而且要有读取消息的权限;
  • 批量获取更多历史:如果需要超过100条的历史,你可以循环调用get_chat_history,每次把offset_id设为上一次获取的最后一条消息的ID减1,直到返回的消息为空;
  • 避免速率限制:不要在短时间内发起大量历史查询请求,Telegram对机器人的API调用频率有限制;
  • 连接池优化:如果你确实需要在handler里发起多个API请求,可以在创建Application时适当调大连接池尺寸,同时设置pool_timeout,比如:
    self.application = ApplicationBuilder().token(self.token)\
        .connection_pool_size(30)\
        .pool_timeout(15)\
        .build()
    

最后再明确可行性

完全可以通过Python Telegram Bot库获取聊天历史,但有两个小限制:

  1. 只能获取机器人参与过的聊天的历史;
  2. 太古老的消息可能拿不到,因为Telegram服务器不会永久保存所有历史,不过近期的消息(比如几个月内的)一般都能拿到。

内容来源于stack exchange

火山引擎 最新活动