Skip to content

Commit 6f6a5b5

Browse files
committed
fix: active message cannot handle forward type message properly in aiocqhttp adapter
1 parent 71290f0 commit 6f6a5b5

File tree

2 files changed

+83
-53
lines changed

2 files changed

+83
-53
lines changed

astrbot/core/platform/sources/aiocqhttp/aiocqhttp_message_event.py

Lines changed: 68 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import asyncio
22
import re
33
from typing import AsyncGenerator, Dict, List
4-
from aiocqhttp import CQHttp
4+
from aiocqhttp import CQHttp, Event
55
from astrbot.api.event import AstrMessageEvent, MessageChain
66
from astrbot.api.message_components import (
77
Image,
@@ -58,50 +58,79 @@ async def _parse_onebot_json(message_chain: MessageChain):
5858
ret.append(d)
5959
return ret
6060

61-
async def send(self, message: MessageChain):
61+
@classmethod
62+
async def send_message(
63+
cls,
64+
bot: CQHttp,
65+
message_chain: MessageChain,
66+
event: Event | None = None,
67+
is_group: bool = False,
68+
session_id: str = None,
69+
):
70+
"""发送消息"""
71+
72+
async def _send(
73+
event: Event, is_group: bool, session_id: str, messages: list[dict]
74+
):
75+
if event:
76+
await bot.send(event=event, message=messages)
77+
elif is_group:
78+
await bot.send_group_msg(group_id=session_id, message=messages)
79+
else:
80+
await bot.send_private_msg(user_id=session_id, message=messages)
81+
6282
# 转发消息、文件消息不能和普通消息混在一起发送
6383
send_one_by_one = any(
64-
isinstance(seg, (Node, Nodes, File)) for seg in message.chain
84+
isinstance(seg, (Node, Nodes, File)) for seg in message_chain.chain
6585
)
66-
if send_one_by_one:
67-
for seg in message.chain:
68-
if isinstance(seg, (Node, Nodes)):
69-
# 合并转发消息
70-
71-
if isinstance(seg, Node):
72-
nodes = Nodes([seg])
73-
seg = nodes
74-
75-
payload = await seg.to_dict()
76-
77-
if self.get_group_id():
78-
payload["group_id"] = self.get_group_id()
79-
await self.bot.call_action("send_group_forward_msg", **payload)
80-
else:
81-
payload["user_id"] = self.get_sender_id()
82-
await self.bot.call_action(
83-
"send_private_forward_msg", **payload
84-
)
85-
elif isinstance(seg, File):
86-
d = await AiocqhttpMessageEvent._from_segment_to_dict(seg)
87-
await self.bot.send(
88-
self.message_obj.raw_message,
89-
[d],
90-
)
91-
else:
92-
await self.bot.send(
93-
self.message_obj.raw_message,
94-
await AiocqhttpMessageEvent._parse_onebot_json(
95-
MessageChain([seg])
96-
),
97-
)
98-
await asyncio.sleep(0.5)
99-
else:
100-
ret = await AiocqhttpMessageEvent._parse_onebot_json(message)
86+
if not send_one_by_one:
87+
ret = await cls._parse_onebot_json(message_chain)
10188
if not ret:
10289
return
103-
await self.bot.send(self.message_obj.raw_message, ret)
90+
await _send(event, is_group, session_id, ret)
91+
return
92+
for seg in message_chain.chain:
93+
if isinstance(seg, (Node, Nodes)):
94+
# 合并转发消息
95+
if isinstance(seg, Node):
96+
nodes = Nodes([seg])
97+
seg = nodes
98+
99+
payload = await seg.to_dict()
100+
101+
if is_group:
102+
payload["group_id"] = session_id
103+
await bot.call_action("send_group_forward_msg", **payload)
104+
else:
105+
payload["user_id"] = session_id
106+
await bot.call_action("send_private_forward_msg", **payload)
107+
elif isinstance(seg, File):
108+
d = await cls._from_segment_to_dict(seg)
109+
await _send(event, is_group, session_id, [d])
110+
else:
111+
messages = await cls._parse_onebot_json(MessageChain([seg]))
112+
if not messages:
113+
continue
114+
await _send(event, is_group, session_id, messages)
115+
await asyncio.sleep(0.5)
104116

117+
async def send(self, message: MessageChain):
118+
"""发送消息"""
119+
event = self.message_obj.raw_message
120+
assert isinstance(event, Event), "Event must be an instance of aiocqhttp.Event"
121+
is_group = False
122+
if self.get_group_id():
123+
is_group = True
124+
session_id = self.get_group_id()
125+
else:
126+
session_id = self.get_sender_id()
127+
await self.send_message(
128+
bot=self.bot,
129+
message_chain=message,
130+
event=event,
131+
is_group=is_group,
132+
session_id=session_id,
133+
)
105134
await super().send(message)
106135

107136
async def send_streaming(

astrbot/core/platform/sources/aiocqhttp/aiocqhttp_platform_adapter.py

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -83,19 +83,18 @@ def on_websocket_connection(_):
8383
async def send_by_session(
8484
self, session: MessageSesion, message_chain: MessageChain
8585
):
86-
ret = await AiocqhttpMessageEvent._parse_onebot_json(message_chain)
87-
match session.message_type.value:
88-
case MessageType.GROUP_MESSAGE.value:
89-
if "_" in session.session_id:
90-
# 独立会话
91-
_, group_id = session.session_id.split("_")
92-
await self.bot.send_group_msg(group_id=group_id, message=ret)
93-
else:
94-
await self.bot.send_group_msg(
95-
group_id=session.session_id, message=ret
96-
)
97-
case MessageType.FRIEND_MESSAGE.value:
98-
await self.bot.send_private_msg(user_id=session.session_id, message=ret)
86+
is_group = session.message_type == MessageType.GROUP_MESSAGE
87+
if is_group:
88+
session_id = session.session_id.split("_")[-1]
89+
else:
90+
session_id = session.session_id
91+
await AiocqhttpMessageEvent.send_message(
92+
bot=self.bot,
93+
message_chain=message_chain,
94+
event=None, # 这里不需要 event,因为是通过 session 发送的
95+
is_group=is_group,
96+
session_id=session_id,
97+
)
9998
await super().send_by_session(session, message_chain)
10099

101100
async def convert_message(self, event: Event) -> AstrBotMessage:
@@ -307,7 +306,9 @@ async def _convert_handle_message_event(
307306
user_id=int(m["data"]["qq"]),
308307
)
309308
if at_info:
310-
nickname = at_info.get("nick", "") or at_info.get("nickname", "")
309+
nickname = at_info.get("nick", "") or at_info.get(
310+
"nickname", ""
311+
)
311312
is_at_self = str(m["data"]["qq"]) in {abm.self_id, "all"}
312313

313314
abm.message.append(

0 commit comments

Comments
 (0)