GraiaProject / Ariadne

一个优雅且完备的 Python QQ 自动化框架,基于 Mirai API HTTP v2。 Powered by Graia Project.
https://graia.cn/ariadne
GNU Affero General Public License v3.0
741 stars 45 forks source link

[Bug] `app.send_message()`在`quote = True`时无法正确传入`MessageEvent`对象 #229

Closed EZForever closed 1 year ago

EZForever commented 1 year ago

问题

根据API文档app.send_message()方法允许target参数传入MessageEvent对象(如FriendMessage),且在quote = True时可以自动从该参数解析回复对象。但目前实现在quote = True时总会抛出TypeError异常。

根本原因在app.send_message()的控制流逻辑有误:

https://github.com/GraiaProject/Ariadne/blob/8e47d9951ec7a7081440196a9115daf000bdc500/src/graia/ariadne/app.py#L1963-L1967

这里的raise TypeError应该在一个if isinstanceelse分支中。

如何复现

from graia.ariadne.entry import Ariadne, WebsocketClientConfig
from graia.ariadne.event.message import FriendMessage, MessageEvent

app = Ariadne(ariadne_config(
    ********,
    '********',
    WebsocketClientConfig('http://********')
))

@app.broadcast.receiver('FriendMessage')
async def on_metacmd(app: Ariadne, event: FriendMessage) -> None:
    #print(event)
    #print('isinstance() =', isinstance(event, MessageEvent))
    await app.send_message(event, 'Hello World', quote = True)

app.launch_blocking()

之后向机器人私聊任意消息,可以观察到无法正常回复消息,控制台输出如下。

预期行为

quote = True时Ariadne可以正确解析传入的MessageEvent对象,并以此设置回复参数。

使用环境:

日志/截图

控制台输出:

2023-05-01 15:48:06 [D/asyncio] __init__: Using selector: EpollSelector
2023-05-01 15:48:06.184 | INFO     | launart.manager:launch_blocking:479 - Starting launart main task...
2023-05-01 15:48:06.184 | INFO     | launart.manager:launch:331 - Launching 4 components as async task...
2023-05-01 15:48:06.206 | INFO     | graia.ariadne.service:base_telemetry:108 - 
    _         _           _
   / \   _ __(_) __ _  __| |_ __   ___
  / _ \ | '__| |/ _` |/ _` | '_ \ / _ \
 / ___ \| |  | | (_| | (_| | | | |  __/
/_/   \_\_|  |_|\__,_|\__,_|_| |_|\___|

graia-amnesia: 0.7.1
graia-ariadne: 0.11.3
graia-broadcast: 0.19.2
launart: 0.6.3
statv: 0.3.2
2023-05-01 15:48:06.206 | SUCCESS  | launart.manager:launch:384 - Layer #1:[cache.client/memcache, http.client/aiohttp] preparation completed.
2023-05-01 15:48:06.206 | SUCCESS  | launart.manager:launch:384 - Layer #3:[elizabeth.service] preparation completed.
2023-05-01 15:48:06.206 | INFO     | launart.manager:launch:389 - All components prepared, start blocking phase.
2023-05-01 15:48:06.210 | SUCCESS  | graia.ariadne.connection.ws:_:64 - Successfully got session key
2023-05-01 15:48:17.580 | INFO     | graia.ariadne.model:log:82 - ********: [RECV][****(********)] -> hello
2023-05-01 15:48:17.581 | ERROR    | graia.ariadne.util:loguru_exc_callback:76 - Exception:
Traceback (most recent call last):

  File "/usr/lib/python3.10/runpy.py", line 196, in _run_module_as_main
    return _run_code(code, main_globals, None,
           │         │     └ {'__name__': '__main__', '__doc__': None, '__package__': 'bot', '__loader__': <_frozen_importlib_external.Source...
           │         └ <code object <module> at 0x7efc2aae9d10, file "/app/bot/__main__.py", line 1>
           └ <function _run_code at 0x7efc2b00b1c0>
  File "/usr/lib/python3.10/runpy.py", line 86, in _run_code
    exec(code, run_globals)
         │     └ {'__name__': '__main__', '__doc__': None, '__package__': 'bot', '__loader__': <_frozen_importlib_external.Source...
         └ <code object <module> at 0x7efc2aae9d10, file "/app/bot/__main__.py", line 1>

  File "/app/bot/__main__.py", line 76, in <module>
    sys.exit(main(sys.argv))
    │   │    │     │   └ ['/app/bot/__main__.py']
    │   │    │     └ <module 'sys' (built-in)>
    │   │    └ <function main at 0x7efc28aa15a0>
    │   └ <built-in function exit>
    └ <module 'sys' (built-in)>

  File "/app/bot/__main__.py", line 71, in main
    app.launch_blocking([signal.SIGINT, signal.SIGTERM])
    │   │                │      │       │      └ <Signals.SIGTERM: 15>
    │   │                │      │       └ <module 'signal' from '/usr/lib/python3.10/signal.py'>
    │   │                │      └ <Signals.SIGINT: 2>
    │   │                └ <module 'signal' from '/usr/lib/python3.10/signal.py'>
    │   └ <classmethod(<function Ariadne.launch_blocking at 0x7efc28c3d240>)>
    └ <graia.ariadne.app.Ariadne object at 0x7efc2b0cbc10>

  File "/root/.cache/pypoetry/virtualenvs/bot-hGsJ4VSK-py3.10/lib/python3.10/site-packages/graia/ariadne/app.py", line 312, in launch_blocking
    cls.launch_manager.launch_blocking(loop=cls.service.loop, stop_signal=stop_signals)
    │   │              │                    │   │       │                 └ [<Signals.SIGINT: 2>, <Signals.SIGTERM: 15>]
    │   │              │                    │   │       └ <property object at 0x7efc28c26a20>
    │   │              │                    │   └ <graia.ariadne.service.ElizabethService object at 0x7efc28c36680>
    │   │              │                    └ <class 'graia.ariadne.app.Ariadne'>
    │   │              └ <function Launart.launch_blocking at 0x7efc29fb5bd0>
    │   └ <launart.manager.Launart object at 0x7efc287a4070>
    └ <class 'graia.ariadne.app.Ariadne'>
  File "/root/.cache/pypoetry/virtualenvs/bot-hGsJ4VSK-py3.10/lib/python3.10/site-packages/launart/manager.py", line 494, in launch_blocking
    loop.run_until_complete(launch_task)
    │    │                  └ <Task pending name='amnesia-launch' coro=<Launart.launch() running at /root/.cache/pypoetry/virtualenvs/bot-hGsJ4VSK-py3.1...
    │    └ <function BaseEventLoop.run_until_complete at 0x7efc2a12fb50>
    └ <_UnixSelectorEventLoop running=True closed=False debug=False>
  File "/usr/lib/python3.10/asyncio/base_events.py", line 636, in run_until_complete
    self.run_forever()
    │    └ <function BaseEventLoop.run_forever at 0x7efc2a12fac0>
    └ <_UnixSelectorEventLoop running=True closed=False debug=False>
  File "/usr/lib/python3.10/asyncio/base_events.py", line 603, in run_forever
    self._run_once()
    │    └ <function BaseEventLoop._run_once at 0x7efc2a135630>
    └ <_UnixSelectorEventLoop running=True closed=False debug=False>
  File "/usr/lib/python3.10/asyncio/base_events.py", line 1909, in _run_once
    handle._run()
    │      └ <function Handle._run at 0x7efc2a0d9000>
    └ <Handle <TaskStepMethWrapper object at 0x7efc287a63b0>()>
  File "/usr/lib/python3.10/asyncio/events.py", line 80, in _run
    self._context.run(self._callback, *self._args)
    │    │            │    │           │    └ <member '_args' of 'Handle' objects>
    │    │            │    │           └ <Handle <TaskStepMethWrapper object at 0x7efc287a63b0>()>
    │    │            │    └ <member '_callback' of 'Handle' objects>
    │    │            └ <Handle <TaskStepMethWrapper object at 0x7efc287a63b0>()>
    │    └ <member '_context' of 'Handle' objects>
    └ <Handle <TaskStepMethWrapper object at 0x7efc287a63b0>()>
> File "/root/.cache/pypoetry/virtualenvs/bot-hGsJ4VSK-py3.10/lib/python3.10/site-packages/graia/broadcast/__init__.py", line 191, in Executor
    result = await run_always_await(target_callable, **parameter_compile_result)
                   │                │                  └ {'app': <graia.ariadne.app.Ariadne object at 0x7efc2b0cbc10>, 'event': FriendMessage(type='FriendMessage', message_chain=Mess...
                   │                └ <function main.<locals>.on_metacmd at 0x7efc28ae7010>
                   └ <function run_always_await at 0x7efc29fff250>
  File "/root/.cache/pypoetry/virtualenvs/bot-hGsJ4VSK-py3.10/lib/python3.10/site-packages/graia/broadcast/utilles.py", line 34, in run_always_await
    obj = await obj
                └ <coroutine object main.<locals>.on_metacmd at 0x7efc28895770>

  File "/app/bot/__main__.py", line 69, in on_metacmd
    await app.send_message(event, 'Hello World', quote = True)
          │   │            └ FriendMessage(type='FriendMessage', message_chain=MessageChain([Plain(text='hello')]), sender=Friend(id=********, nickname=...
          │   └ <function Ariadne.send_message at 0x7efc28c48700>
          └ <graia.ariadne.app.Ariadne object at 0x7efc2b0cbc10>

  File "/root/.cache/pypoetry/virtualenvs/bot-hGsJ4VSK-py3.10/lib/python3.10/site-packages/graia/ariadne/app.py", line 1954, in send_message
    raise TypeError("Passing `quote=True` is only valid when passing a MessageEvent.")

TypeError: Passing `quote=True` is only valid when passing a MessageEvent.