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

Python运行时动态修改Telethon装饰器参数的实现方法

解决Telethon动态添加Chat ID无法同步监听的问题

问题根源在于:装饰器@telethon_client.on(events.NewMessage(...))在脚本启动时就会把chats=FROM的当前列表内容绑定到事件处理器上,后续修改FROM列表不会更新这个绑定的监听范围,所以新添加的Chat ID不会触发消息捕获。

下面给两种实用的解决方法:

方法一:函数内部动态检查(推荐)

去掉装饰器里的chats参数,改为在消息处理函数内部判断当前消息的Chat ID是否在FROM列表中。这样每次触发事件时都会读取最新的FROM列表,动态添加的ID立即生效。

修改后的代码:

from telethon import TelegramClient, events
from telethon.sessions import StringSession

telethon_client = TelegramClient(StringSession(SESSION), APP_ID, API_HASH)
telethon_client.start()
# some code here

FROM=[CHAT_ID_1, CHAT_ID_2, CHAT_ID_3]
TO = ...  # 替换为你的目标聊天ID
BOT_CHAT_ID = ...  # 替换为你的机器人聊天ID

@telethon_client.on(events.NewMessage(outgoing=outgoing, incoming=True))
async def catch_messages(event):
    global FROM
    # 动态检查当前消息的聊天ID是否在监听列表里
    if event.chat_id not in FROM:
        return
    # 原有的转发逻辑
    await telethon_client.send_message(entity=TO, message=event.message)

@telethon_client.on(events.NewMessage(pattern=r"\/", chats=BOT_CHAT_ID, incoming=False))
async def handler(event):
    global FROM
    new_chat_id = CHAT_ID_4  # 这里可以根据实际命令提取Chat ID
    if new_chat_id not in FROM:
        FROM.append(new_chat_id)
        await event.respond(f"已成功添加聊天ID {new_chat_id}")
    else:
        await event.respond("该聊天ID已在监听列表中")

telethon_client.run_until_disconnected()

方法二:动态注册事件处理器

如果需要更精细的控制(比如单独管理每个Chat ID的监听),可以通过add_event_handler方法在添加新Chat ID时,为其单独注册消息处理函数。

修改后的代码:

from telethon import TelegramClient, events
from telethon.sessions import StringSession

telethon_client = TelegramClient(StringSession(SESSION), APP_ID, API_HASH)
telethon_client.start()

FROM=[CHAT_ID_1, CHAT_ID_2, CHAT_ID_3]
TO = ...  # 替换为你的目标聊天ID
BOT_CHAT_ID = ...  # 替换为你的机器人聊天ID

# 定义通用的转发处理函数
async def forward_message(event):
    await telethon_client.send_message(entity=TO, message=event.message)

# 初始注册所有初始Chat ID的监听
for chat_id in FROM:
    telethon_client.add_event_handler(
        forward_message,
        events.NewMessage(outgoing=outgoing, incoming=True, chats=chat_id)
    )

@telethon_client.on(events.NewMessage(pattern=r"\/", chats=BOT_CHAT_ID, incoming=False))
async def handler(event):
    global FROM
    new_chat_id = CHAT_ID_4  # 根据实际命令提取Chat ID
    if new_chat_id not in FROM:
        FROM.append(new_chat_id)
        # 为新Chat ID注册监听
        telethon_client.add_event_handler(
            forward_message,
            events.NewMessage(outgoing=outgoing, incoming=True, chats=new_chat_id)
        )
        await event.respond(f"已添加聊天ID {new_chat_id} 到转发列表")
    else:
        await event.respond("该聊天ID已在监听列表中")

telethon_client.run_until_disconnected()

两种方法对比:

  • 方法一实现简单,无需额外操作,适合大多数场景;
  • 方法二更灵活,支持后续单独注销某个Chat ID的监听(通过remove_event_handler),适合复杂需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 22:33:29