Skip to content

Conversation

@Moemu
Copy link
Contributor

@Moemu Moemu commented Apr 20, 2025

问题描述

在 Telegram 实现中, event.reply_to_message 有可能为 ForumTopicCreated ,从而在 extract_reply 抛出 has no attribute 异常。

这是因为在 Telegram topic thread 中发送消息需要引用 💬 "Topic" was created参考资料),也就是 Telegram 适配中的 ForumTopicCreated类,而这个类不继承于 MessageEvent ,所以这个类就没有 original_message 从而抛出异常。

最小复现示例及异常
at_event = on_alconna(
    Alconna(re.compile(".+"), Args["text?", AllParam], separators=""),
    priority=100,
    rule=to_me(),
    block=True,
    extensions=[ReplyRecordExtension()],
)

@at_event.handle()
async def handle_supported_adapters():
	pass
    |   File "c:\Users\Muika\.conda\envs\nonebot\Lib\site-packages\nonebot\internal\rule.py", line 88, in _run_checker
    |     is_passed = await checker(
    |                       └ Dependent(call=Alconna(command=Alconna::re.compile('.+')(args=[Arg(name='text', value=*, field=Field(default=<class 'inspect....
    |   File "c:\Users\Muika\.conda\envs\nonebot\Lib\site-packages\nonebot\dependencies\__init__.py", line 113, in __call__
    |     return await cast(Callable[..., Awaitable[R]], self.call)(**values)
    |                  │    │             │         │    │    │       └ {'event': ForumTopicMessageEvent(telegram_model=Update(update_id=777511108, message=Message(message_id=2919, message_thread_i...
    |                  │    │             │         │    │    └ Alconna(command=Alconna::re.compile('.+')(args=[Arg(name='text', value=*, field=Field(default=<class 'inspect._empty'>, alias...
    |                  │    │             │         │    └ Dependent(call=Alconna(command=Alconna::re.compile('.+')(args=[Arg(name='text', value=*, field=Field(default=<class 'inspect....
    |                  │    │             │         └ ~R
    |                  │    │             └ <class 'collections.abc.Awaitable'>
    |                  │    └ typing.Callable
    |                  └ <function cast at 0x000002DF9654D4E0>
    |   File "c:\Users\Muika\.conda\envs\nonebot\Lib\site-packages\nonebot_plugin_alconna\rule.py", line 290, in __call__
    |     msg = await self.executor.receive_wrapper(bot, event, cmd, msg)
    |                 │    │                        │    │      │    └ [Text(text='有一种保守的方法是在 to_me 外部加一层判断 orignal_message 是否存在的逻辑;再保守一点就是放弃 at_event 在 on_alconna 的实现', styles={(59, 67): ['code']...
    |                 │    │                        │    │      └ Alconna::re.compile('.+')(args=[Arg(name='text', value=*, field=Field(default=<class 'inspect._empty'>, alias=None), notice=N...
    |                 │    │                        │    └ ForumTopicMessageEvent(telegram_model=Update(update_id=777511108, message=Message(message_id=2919, message_thread_id=1579, fr...
    |                 │    │                        └ Bot(type='Telegram', self_id='7312500650')
    |                 │    └ <member 'executor' of 'AlconnaRule' objects>
    |                 └ Alconna(command=Alconna::re.compile('.+')(args=[Arg(name='text', value=*, field=Field(default=<class 'inspect._empty'>, alias...
    |   File "c:\Users\Muika\.conda\envs\nonebot\Lib\site-packages\nonebot_plugin_alconna\extension.py", line 244, in receive_wrapper
    |     res = await ext.receive_wrapper(bot, event, command, res)
    |                 │   │               │    │      │        └ [Text(text='有一种保守的方法是在 to_me 外部加一层判断 orignal_message 是否存在的逻辑;再保守一点就是放弃 at_event 在 on_alconna 的实现', styles={(59, 67): ['code']...
    |                 │   │               │    │      └ Alconna::re.compile('.+')(args=[Arg(name='text', value=*, field=Field(default=<class 'inspect._empty'>, alias=None), notice=N...
    |                 │   │               │    └ ForumTopicMessageEvent(telegram_model=Update(update_id=777511108, message=Message(message_id=2919, message_thread_id=1579, fr...
    |                 │   │               └ Bot(type='Telegram', self_id='7312500650')
    |                 │   └ <function ReplyRecordExtension.receive_wrapper at 0x000002DFA5947060>
    |                 └ <nonebot_plugin_alconna.builtins.extensions.reply.ReplyRecordExtension object at 0x000002DFA5D84390>
    |   File "c:\Users\Muika\.conda\envs\nonebot\Lib\site-packages\nonebot_plugin_alconna\builtins\extensions\reply.py", line 46, in receive_wrapper
    |     if not (reply := await reply_fetch(event, bot)):
    |                            │           │      └ Bot(type='Telegram', self_id='7312500650')
    |                            │           └ ForumTopicMessageEvent(telegram_model=Update(update_id=777511108, message=Message(message_id=2919, message_thread_id=1579, fr...
    |                            └ <function reply_fetch at 0x000002DFA2F68E00>
    |   File "c:\Users\Muika\.conda\envs\nonebot\Lib\site-packages\nonebot_plugin_alconna\uniseg\tools.py", line 26, in reply_fetch
    |     return await fn.extract_reply(event, bot)
    |                  │  │             │      └ Bot(type='Telegram', self_id='7312500650')
    |                  │  │             └ ForumTopicMessageEvent(telegram_model=Update(update_id=777511108, message=Message(message_id=2919, message_thread_id=1579, fr...
    |                  │  └ <function TelegramMessageBuilder.extract_reply at 0x000002DFA2FE3CE0>
    |                  └ <nonebot_plugin_alconna.uniseg.adapters.telegram.builder.TelegramMessageBuilder object at 0x000002DFA2FEF190>
    |   File "c:\Users\Muika\.conda\envs\nonebot\Lib\site-packages\nonebot_plugin_alconna\uniseg\adapters\telegram\builder.py", line 123, in extract_reply
    |     event.reply_to_message.original_message,
    |     │     └ ForumTopicCreatedEvent(telegram_model=None, message_thread_id=1579, from_=User(id=6287985548, is_bot=False, first_name='Muika...
    |     └ ForumTopicMessageEvent(telegram_model=Update(update_id=777511108, message=Message(message_id=2919, message_thread_id=1579, fr...
    |   File "c:\Users\Muika\.conda\envs\nonebot\Lib\site-packages\pydantic\main.py", line 885, in __getattr__
    |     raise AttributeError(f'{type(self).__name__!r} object has no attribute {item!r}') from exc
    |
    | AttributeError: 'ForumTopicCreatedEvent' object has no attribute 'original_message'

解决方案

由于 ForumTopicCreated 不是一类真正的消息事件,也没有 message_id 没办法初始化 Reply 类,因此选择在 if event.reply_to_message 后加入类型判断,这样即可解决问题

async def extract_reply(self, event: Event, bot: Bot):
    if TYPE_CHECKING:
        assert isinstance(event, MessageEvent)
    if event.reply_to_message and isinstance(event.reply_to_message, MessageEvent): # 加入 isinstance 判断
        return Reply(
            f"{event.reply_to_message.message_id}",
            event.reply_to_message.original_message,
            event.reply_to_message,
        )
    return None

@RF-Tar-Railt RF-Tar-Railt merged commit 4980b54 into nonebot:master Apr 20, 2025
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants