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

Telethon中普通Bot与UserBot消息ID不一致及相关问题排查

问题分析与解决方案

1. 消息ID不一致的原因与解决

核心原因

这是Telegram的设计机制,并非Telethon的Bug:

  • 当Bot收到用户消息时,event.message.id是Bot与该用户对话中的本地消息ID,此时对话的chat.id是发送消息的用户ID;
  • 当UserBot调用iter_messages(normal_bot_user.username)时,查询的是UserBot与该Bot的对话,此时对话的chat.id是Bot的ID,消息ID是这个对话中的本地ID;
  • 两个对话属于完全独立的上下文,Telegram会为每个对话维护独立的消息ID序列,因此同一条消息在两个视角下的ID自然不同。

解决存储问题

不要单独使用message.id作为唯一标识,改用对话ID+消息ID的组合作为全局唯一键:

  • Bot侧存储时使用:(event.message.chat.id, event.message.id)
  • UserBot侧存储时使用:(message.chat.id, message.id)

如果需要跨客户端关联同一条消息,可以通过message.text、message.date等内容字段辅助验证,核心依赖对话+消息ID的组合键。

2. get_input_entity返回错误结果的原因与解决

核心原因

从normal_bot_client.get_me()获取的User对象,其access_hash是Bot会话的缓存值,对于UserBot客户端无效。当将这个完整的User对象传递给UserBot的get_input_entity时,Telethon无法正确验证实体身份,导致错误匹配为当前客户端自身(InputPeerSelf())。

解决方案

  • 避免跨客户端传递完整的User实体,改用用户名、用户ID等全局标识让目标客户端重新查询:
    # 推荐方式:使用用户ID
    normal_bot_id = (await normal_bot_client.get_me()).id
    something = await user_bot_client.get_input_entity(normal_bot_id)
    # 或者使用用户名
    something = await user_bot_client.get_input_entity(normal_bot_user.username)
    
  • 如果必须传递实体信息,只提取id、username等无状态字段,不要传递包含会话专属access_hash的完整对象。

代码修改示例

调整原handler中的对话查询逻辑,明确对话标识的差异:

@normal_bot_client.on(events.NewMessage)
async def handler(event):
    print(f'{event.message.id=}')
    print(f'{event.message.chat.id=}')  # 输出为发送消息的用户ID
    print(f'{event.message.text=}')
    print('-----------------')

    async with user_bot_client:
        bot_username = (await normal_bot_client.get_me()).username
        async for message in user_bot_client.iter_messages(bot_username, 3):
            print(f'{message.id=}')
            print(f'{message.chat.id=}')  # 输出为Bot的ID
            print(f'{message.text=}')
            print()

内容的提问来源于stack exchange,提问作者Flana Ban

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 06:40:33