nonebot / aiocqhttp

A Python SDK with async I/O for CQHTTP (OneBot).
https://aiocqhttp.nonebot.dev
MIT License
280 stars 39 forks source link

怎么获取bot自己在群里发的消息? #70

Open ilihu opened 1 year ago

ilihu commented 1 year ago

功能描述 我go-cq的bot上报自身消息已开,可以正常上报自身消息。请教下,aiocqhttp可以获取bot自己发的消息吗?

cleoold commented 1 year ago

應該是 ok 的,只要上報的訊息格式一致.

ilihu commented 1 year ago

應該是 ok 的,只要上報的訊息格式一致.

刚刚调试了一下。在gocq里如果是自己发的消息,消息体是这样的

{'post_type': 'message_sent', 'message_type': 'group', 'time': 1679895405, 'self_id': 123123, 'sub_type': 'normal', 'raw_message': 'Test body', 'sender': {'age': 0, 'area': '', 'card': '', 'level': '', 'nickname': 'nickname', 'role': 'member', 'sex': 'unknown', 'title': '', 'user_id': 123123}, 'user_id': 123123, 'message_seq': 3741, 'font': 0, 'group_id': 321321, 'message': 'Test body', 'message_id': 97658941, 'anonymous': None}

post_type 是 message_sent

但是这个在下面这个函数里被过滤掉了

# aiocqhttp.__init__.py

async def _handle_event(self, payload: Dict[str, Any]) -> Any:
        ev = Event.from_payload(payload)
        if not ev:
            return

        event_name = ev.name
        self.logger.info(f'received event: {event_name}')

        if self._message_class and 'message' in ev:
            ev['message'] = self._message_class(ev['message'])
        results = list(
            filter(lambda r: r is not None, await
                   self._bus.emit(event_name, ev)))
        # return the first non-none result
        return results[0] if results else None

async def _handle_event_with_response(self, payload: Dict[str,
                                                              Any]) -> None:
        response = await self._handle_event(payload)
        if isinstance(response, dict):
            payload.pop('message', None)  # avoid wasting bandwidth
            payload.pop('raw_message', None)
            payload.pop('comment', None)
            payload.pop('sender', None)
            payload.pop('message_seq', None)
            payload.pop('time', None)
            payload.pop('title', None)
            try:
                await self._api.call_action(
                    self_id=payload['self_id'],
                    action='.handle_quick_operation_async',
                    context=payload,
                    operation=response)
            except Error:
                pass

所以,如果不修改源代码是收不到bot自身上报的消息的

cleoold commented 1 year ago

I see. Gocqhttp is sending a post type of 'message_sent' and with a 'message_type' being 'group'.

aiocqhttp when sees the word 'message_sent', assumes the event should have a 'message_sent_type' being a 'group'. so its gocqhttp not obeying a convention.

There is a bot.before_sending() function, maybe you can try it without modifying library code.

On Mon., Mar. 27, 2023, 01:42 ilihu, @.***> wrote:

應該是 ok 的,只要上報的訊息格式一致.

刚刚调试了一下。在gocq里如果是自己发的消息,消息体是这样的

{'post_type': 'message_sent', 'message_type': 'group', 'time': 1679895405, 'self_id': 123123, 'sub_type': 'normal', 'raw_message': 'Test body', 'sender': {'age': 0, 'area': '', 'card': '', 'level': '', 'nickname': 'nickname', 'role': 'member', 'sex': 'unknown', 'title': '', 'user_id': 123123}, 'user_id': 123123, 'message_seq': 3741, 'font': 0, 'group_id': 321321, 'message': 'Test body', 'message_id': 97658941, 'anonymous': None}

post_type 是 message_sent

但是这个在下面这个函数里被过滤掉了

aiocqhttp.init.py

async def _handle_event(self, payload: Dict[str, Any]) -> Any: ev = Event.from_payload(payload) if not ev: return

    event_name = ev.name
    self.logger.info(f'received event: {event_name}')

    if self._message_class and 'message' in ev:
        ev['message'] = self._message_class(ev['message'])
    results = list(
        filter(lambda r: r is not None, await
               self._bus.emit(event_name, ev)))
    # return the first non-none result
    return results[0] if results else None

async def _handle_event_with_response(self, payload: Dict[str, Any]) -> None: response = await self._handle_event(payload) if isinstance(response, dict): payload.pop('message', None) # avoid wasting bandwidth payload.pop('raw_message', None) payload.pop('comment', None) payload.pop('sender', None) payload.pop('message_seq', None) payload.pop('time', None) payload.pop('title', None) try: await self._api.call_action( self_id=payload['self_id'], action='.handle_quick_operation_async', context=payload, operation=response) except Error: pass

所以,如果不修改源代码是收不到bot自身上报的消息的

— Reply to this email directly, view it on GitHub https://github.com/nonebot/aiocqhttp/issues/70#issuecomment-1484528778, or unsubscribe https://github.com/notifications/unsubscribe-auth/ADKGVBZLBHZR7WMJAST5U5TW6ESFRANCNFSM6AAAAAAWIVULWQ . You are receiving this because you commented.Message ID: @.***>

ilihu commented 1 year ago

I see. Gocqhttp is sending a post type of 'message_sent' and with a 'message_type' being 'group'. aiocqhttp when sees the word 'message_sent', assumes the event should have a 'message_sent_type' being a 'group'. so its gocqhttp not obeying a convention. There is a bot.before_sending() function, maybe you can try it without modifying library code.

在下一个版本里,希望能直接调用到bot自身上报的消息