Telethon中NewMessage事件的实体参数配置矛盾问题
解决Telethon动态获取Entity并注册NewMessage事件的问题
问题核心在于:装饰器@events.register会在脚本加载阶段立即执行,此时客户端未启动、目标频道Entity也未获取,直接用from_users=desired_channel必然报错。解决思路是将事件注册逻辑延后到获取到Entity之后,动态添加事件处理器。
修改后的完整代码
from telethon import TelegramClient, events from telegram.api_library import ( write_in_saved_messages, get_entity_data, ) from user_files.user_settings import ( USER_SESSION_NAME, USER_TELEGRAM_API_HASH, USER_TELEGRAM_API_ID, ) # 修正客户端初始化的闭合括号 telegram_client: TelegramClient = TelegramClient( USER_SESSION_NAME, USER_TELEGRAM_API_ID, USER_TELEGRAM_API_HASH ) async def message_received(event): """处理目标频道的新消息""" # 修正:获取消息文本而非Message对象本身 incoming_message_text = event.message.text sender_id = (await event.get_input_sender()).channel_id print(f"Message from {sender_id}:\n{incoming_message_text}") async def main(): """初始化流程:启动提示 → 获取频道Entity → 注册事件""" await write_in_saved_messages(telegram_client, "Message Receiver started!") # 获取目标频道的Entity desired_channel = await get_entity_data( telegram_client, "desired_channel_name" ) # 动态注册事件处理器(此时已拿到合法的Entity) telegram_client.add_event_handler( message_received, events.NewMessage( incoming=True, from_users=desired_channel ) ) def start_receiver(): """启动接收器""" with telegram_client: # 确保初始化流程(获取Entity、注册事件)执行完毕后,再进入事件循环 telegram_client.loop.run_until_complete(main()) telegram_client.run_until_disconnected()
关键改动说明
- 移除装饰器注册:放弃
@events.register,改用add_event_handler动态注册事件,确保只有拿到Entity后才配置from_users参数。 - 调整执行顺序:将Entity获取、事件注册逻辑放在
main函数中,通过run_until_complete确保这些初始化步骤完成后,再启动客户端的事件循环。 - 修复代码语法错误:补全了
TelegramClient初始化时缺失的闭合括号,修正了消息文本的获取方式(event.message.text而非直接取event.message)。
备选方案(低效率但改动小)
如果不想调整事件注册逻辑,也可以在事件处理函数内部判断发送者是否为目标频道,但这种方式每次收到消息都会重新获取Entity,效率较低:
@events.register(events.NewMessage(incoming=True)) async def message_received(event): desired_channel = await get_entity_data(telegram_client, "desired_channel_name") sender = await event.get_input_sender() # 不是目标频道则直接返回 if sender.channel_id != desired_channel.id: return # 后续消息处理逻辑 incoming_message_text = event.message.text print(f"Message from {sender.channel_id}:\n{incoming_message_text}")
内容的提问来源于stack exchange,提问作者Mohsen HNSJ
相关产品推荐
相关产品推荐

