Pyrogram多会话接收Telegram频道消息异常:仅单会话能接收
问题分析:Pyrogram多会话仅单账号接收指定频道消息异常
问题背景
使用两个Telegram账号加入同一目标频道,通过Pyrogram编写多会话代码接收并打印消息,但仅其中一个会话能输出消息,另一个无任何响应。手机端两个账号均能正常查看该频道消息,且在自建测试频道中多会话可正常工作,但目标频道始终出现异常。后续测试发现:
- 调换两个会话的启动顺序,能接收消息的账号会随之切换
- 将两个会话拆分为独立脚本在不同终端运行,仍只有一个实例能接收目标频道消息,测试频道则无此问题
复现代码
#!/usr/bin/python3 from pyrogram import Client, filters, idle from pyrogram.handlers import MessageHandler import config from datetime import datetime import asyncio CHANNEL_ID = -1000123456789 def india_number_handler(client, message): message_handler('india_number', message) def uk_number_handler(client, message): message_handler('uk_number', message) def message_handler(session_name, message): if message.sender_chat is not None and message.sender_chat.id == CHANNEL_ID and message.text is not None: print(datetime.now().strftime('%d-%m-%Y-%H:%M:%S-%f') + ': ' + session_name + ' received channel message: ' + message.text, flush = True) async def main(): app_india = Client("india_number", api_id=config.getEnv("api_id"), api_hash=config.getEnv("api_hash")) app_uk = Client("uk_number", api_id=config.getEnv("api_id"), api_hash=config.getEnv("api_hash")) app_india.add_handler(MessageHandler(india_number_handler)) app_uk.add_handler(MessageHandler(uk_number_handler)) await app_india.start() await app_uk.start() await idle() await app.stop() # 此处存在错误,应为app_india.stop() await app_uk.stop() asyncio.run(main())
可能原因
- 同一API ID的多会话限制:Telegram服务器可能对同一API ID下同时运行的多个会话进行消息推送限制,测试频道活跃度低未触发,但目标频道的高活跃度或反滥用机制触发了该限制,导致仅一个会话能接收消息。
- 消息过滤逻辑缺陷:当前过滤条件依赖
message.sender_chat.id == CHANNEL_ID,若目标频道存在转发消息(消息发送者并非频道自身),message.sender_chat会指向原发送者而非频道ID,导致消息被过滤。测试频道消息均为频道自身发送,所以能正常触发判断。 - 会话状态不同步:两个账号的频道消息已读状态不一致,服务器会跳过推送已标记为已读的消息;调换启动顺序时,会话初始化的状态同步逻辑可能影响消息接收优先级。
- 代码语法错误:
await app.stop()应为await app_india.stop(),该错误可能导致会话资源未正确释放,间接影响消息接收流程。
解决方案
- 使用独立API ID/Hash:为两个账号分别申请独立的API ID和API Hash,避免同一API ID下的多会话被服务器限制。
- 优化过滤条件:将过滤逻辑改为判断
message.chat.id == CHANNEL_ID,因为频道消息的chat.id始终对应频道ID,不受消息是否转发影响:def message_handler(session_name, message): if message.chat.id == CHANNEL_ID and message.text is not None: print(datetime.now().strftime('%d-%m-%Y-%H:%M:%S-%f') + ': ' + session_name + ' received channel message: ' + message.text, flush = True) - 同步会话已读状态:在启动会话后,手动标记频道消息为已读,确保服务器推送新消息:
await app_india.start() await app_india.mark_chat_as_read(CHANNEL_ID) await app_uk.start() await app_uk.mark_chat_as_read(CHANNEL_ID) - 修复代码错误:将
await app.stop()修正为await app_india.stop(),保证两个会话都能正确关闭。 - 添加调试日志:在
message_handler中打印完整消息对象,对比两个账号的消息结构差异,确认过滤条件是否命中:def message_handler(session_name, message): print(f"[{session_name}] Raw message: {message}") if message.chat.id == CHANNEL_ID and message.text is not None: print(datetime.now().strftime('%d-%m-%Y-%H:%M:%S-%f') + ': ' + session_name + ' received channel message: ' + message.text, flush = True)
内容的提问来源于stack exchange,提问作者Kannan J
相关产品推荐
相关产品推荐

