diff --git a/astrbot/api/platform/__init__.py b/astrbot/api/platform/__init__.py index dcc02bb49..5a98c5903 100644 --- a/astrbot/api/platform/__init__.py +++ b/astrbot/api/platform/__init__.py @@ -5,6 +5,7 @@ from astrbot.core.platform import ( MessageMember, MessageType, PlatformMetadata, + Group, ) from astrbot.core.platform.register import register_platform_adapter @@ -18,4 +19,5 @@ __all__ = [ "MessageType", "PlatformMetadata", "register_platform_adapter", + "Group", ] diff --git a/astrbot/core/platform/__init__.py b/astrbot/core/platform/__init__.py index 48ea57b8a..69a173396 100644 --- a/astrbot/core/platform/__init__.py +++ b/astrbot/core/platform/__init__.py @@ -1,7 +1,7 @@ from .platform import Platform from .astr_message_event import AstrMessageEvent from .platform_metadata import PlatformMetadata -from .astrbot_message import AstrBotMessage, MessageMember, MessageType +from .astrbot_message import AstrBotMessage, MessageMember, MessageType, Group __all__ = [ "Platform", diff --git a/astrbot/core/platform/astr_message_event.py b/astrbot/core/platform/astr_message_event.py index 35a2c4179..3e1b14ee6 100644 --- a/astrbot/core/platform/astr_message_event.py +++ b/astrbot/core/platform/astr_message_event.py @@ -202,15 +202,6 @@ class AstrMessageEvent(abc.ABC): """ return self.role == "admin" - async def send(self, message: MessageChain): - """ - 发送消息到消息平台。 - """ - asyncio.create_task( - Metric.upload(msg_event_tick=1, adapter_name=self.platform_meta.name) - ) - self._has_send_oper = True - async def _pre_send(self): """调度器会在执行 send() 前调用该方法""" @@ -373,36 +364,25 @@ class AstrMessageEvent(abc.ABC): conversation=conversation, ) - async def get_group(self, group_id: str = None) -> Optional[Group]: + """平台适配器""" + + async def send(self, message: MessageChain): + """发送消息到消息平台。 + + Args: + message (MessageChain): 消息链,具体使用方式请参考文档。 """ - 获取群聊,如果不填写group_id,且消息是私聊消息,则返回 None - 目前只实现了 GeweChat 协议 - """ - # 确定有效的 group_id - if group_id is None: - group_id = self.message_obj.group_id - - if group_id is None: - return None - - # 检查平台是否为 gewechat - if self.platform_meta.name != "gewechat": - return None - - from astrbot.core.platform.sources.gewechat.gewechat_event import ( - GewechatPlatformEvent, + asyncio.create_task( + Metric.upload(msg_event_tick=1, adapter_name=self.platform_meta.name) ) + self._has_send_oper = True - assert isinstance(self, GewechatPlatformEvent) - client = self.client + async def get_group(self, group_id: str = None, **kwargs) -> Optional[Group]: + """获取一个群聊的数据, 如果不填写 group_id: 如果是私聊消息,返回 None。如果是群聊消息,返回当前群聊的数据。 - # 从客户端获取群信息 - res = await client.get_group(group_id) + 适配情况: - data = res["data"] - - # 检查 chatroomId 是否为空 - if data["chatroomId"] == "": - return None - - return Group.from_dict(data) + - gewechat + - aiocqhttp(OneBotv11) + """ + ... diff --git a/astrbot/core/platform/astrbot_message.py b/astrbot/core/platform/astrbot_message.py index be49ba18e..def638e96 100644 --- a/astrbot/core/platform/astrbot_message.py +++ b/astrbot/core/platform/astrbot_message.py @@ -13,7 +13,7 @@ class MessageMember: def __str__(self): # 使用 f-string 来构建返回的字符串表示形式 return ( - f"User ID: {self.user_id}\n" + f"User ID: {self.user_id}," f"Nickname: {self.nickname if self.nickname else 'N/A'}" ) @@ -21,19 +21,17 @@ class MessageMember: @dataclass class Group: group_id: str + """群号""" group_name: str = None - - # 群头像 + """群名称""" group_avatar: str = None - - # 群主id + """群头像""" group_owner: str = None - - # 群管理员id - group_admin: str = None - - # 群成员 + """群主 id""" + group_admins: List[str] = None + """群管理员 id""" members: List[MessageMember] = None + """所有群成员""" def __str__(self): # 使用 f-string 来构建返回的字符串表示形式 @@ -42,23 +40,9 @@ class Group: f"Name: {self.group_name if self.group_name else 'N/A'}\n" f"Avatar: {self.group_avatar if self.group_avatar else 'N/A'}\n" f"Owner ID: {self.group_owner if self.group_owner else 'N/A'}\n" - f"Admin ID: {self.group_admin if self.group_admin else 'N/A'}" - ) - - @classmethod - def from_dict(cls, data: Dict[str, Any]) -> "Group": - # 提取members信息并转换为MessageMember对象 - members = [ - MessageMember(user_id=member["wxid"], nickname=member["nickName"]) - for member in data.get("memberList", []) - ] - - return cls( - group_id=data["chatroomId"], - group_name=data.get("nickName"), - group_avatar=data.get("smallHeadImgUrl"), - group_owner=data.get("chatRoomOwner"), - members=members, + f"Admin IDs: {self.group_admins if self.group_admins else 'N/A'}\n" + f"Members Len: {len(self.members) if self.members else 0}\n" + f"First Member: {self.members[0] if self.members else 'N/A'}\n" ) diff --git a/astrbot/core/platform/sources/aiocqhttp/aiocqhttp_message_event.py b/astrbot/core/platform/sources/aiocqhttp/aiocqhttp_message_event.py index 0dfe41a4e..c7aede7d1 100644 --- a/astrbot/core/platform/sources/aiocqhttp/aiocqhttp_message_event.py +++ b/astrbot/core/platform/sources/aiocqhttp/aiocqhttp_message_event.py @@ -1,6 +1,7 @@ import asyncio - +import typing from astrbot.api.event import AstrMessageEvent, MessageChain +from astrbot.api.platform import Group, MessageMember from astrbot.api.message_components import Plain, Image, Record, At, Node, Nodes from aiocqhttp import CQHttp @@ -74,3 +75,46 @@ class AiocqhttpMessageEvent(AstrMessageEvent): await self.bot.send(self.message_obj.raw_message, ret) await super().send(message) + + async def get_group(self, group_id=None, **kwargs): + if isinstance(group_id, str) and group_id.isdigit(): + group_id = int(group_id) + elif self.get_group_id(): + group_id = int(self.get_group_id()) + else: + return None + + info: dict = await self.bot.call_action( + "get_group_info", + group_id=group_id, + ) + + members: typing.List[typing.Dict] = await self.bot.call_action( + "get_group_member_list", + group_id=group_id, + ) + + owner_id = None + admin_ids = [] + for member in members: + if member["role"] == "owner": + owner_id = member["user_id"] + if member["role"] == "admin": + admin_ids.append(member["user_id"]) + + group = Group( + group_id=str(group_id), + group_name=info.get("group_name"), + group_avatar="", + group_admins=admin_ids, + group_owner=str(owner_id), + members=[ + MessageMember( + user_id=member["user_id"], + nickname=member.get("nickname") or member.get("card"), + ) + for member in members + ], + ) + + return group diff --git a/astrbot/core/platform/sources/gewechat/gewechat_event.py b/astrbot/core/platform/sources/gewechat/gewechat_event.py index 15f0badd7..26633f622 100644 --- a/astrbot/core/platform/sources/gewechat/gewechat_event.py +++ b/astrbot/core/platform/sources/gewechat/gewechat_event.py @@ -6,7 +6,7 @@ from astrbot.core.utils.io import save_temp_img, download_file from astrbot.core.utils.tencent_record_helper import wav_to_tencent_silk from astrbot.api import logger from astrbot.api.event import AstrMessageEvent, MessageChain -from astrbot.api.platform import AstrBotMessage, PlatformMetadata +from astrbot.api.platform import AstrBotMessage, PlatformMetadata, Group, MessageMember from astrbot.api.message_components import Plain, Image, Record, At, File from .client import SimpleGewechatClient @@ -123,3 +123,30 @@ class GewechatPlatformEvent(AstrMessageEvent): to_wxid = self.message_obj.raw_message.get("to_wxid", None) await GewechatPlatformEvent.send_with_client(message, to_wxid, self.client) await super().send(message) + + async def get_group(self, group_id = None, **kwargs): + # 确定有效的 group_id + if group_id is None: + group_id = self.message_obj.group_id + + if group_id is None: + return None + + res = await self.client.get_group(group_id) + data: dict = res["data"] + + if not data["chatroomId"]: + return None + + members = [ + MessageMember(user_id=member["wxid"], nickname=member["nickName"]) + for member in data.get("memberList", []) + ] + + return Group( + group_id=data["chatroomId"], + group_name=data.get("nickName"), + group_avatar=data.get("smallHeadImgUrl"), + group_owner=data.get("chatRoomOwner"), + members=members, + )