diff --git a/src/recv_handler/__init__.py b/src/recv_handler/__init__.py index f8904ee..e4c9744 100644 --- a/src/recv_handler/__init__.py +++ b/src/recv_handler/__init__.py @@ -41,6 +41,7 @@ class NoticeType: # 通知事件 class Notify: poke = "poke" # 戳一戳 + group_name = "group_name" # 群名称变更 class GroupBan: ban = "ban" # 禁言 diff --git a/src/recv_handler/message_handler.py b/src/recv_handler/message_handler.py index 10d01d8..d52d21a 100644 --- a/src/recv_handler/message_handler.py +++ b/src/recv_handler/message_handler.py @@ -8,6 +8,7 @@ from src.utils import ( get_self_info, get_message_detail, ) +import base64 from .qq_emoji_list import qq_face from .message_sending import message_send_instance from . import RealMessageType, MessageType, ACCEPT_FORMAT @@ -509,8 +510,22 @@ class MessageHandler: if app == "com.tencent.mannounce": meta = parsed_json.get("meta", {}) mannounce = meta.get("mannounce", {}) - title = mannounce.get("title", "") - text = mannounce.get("text", "") + title_encoded = mannounce.get("title", "") + text_encoded = mannounce.get("text", "") + + # 解码Base64编码的标题和内容 + title = "" + text = "" + try: + if title_encoded: + title = base64.b64decode(title_encoded).decode("utf-8") + if text_encoded: + text = base64.b64decode(text_encoded).decode("utf-8") + except Exception as e: + logger.warning(f"群公告Base64解码失败: {e}") + # 降级使用原始值 + title = title_encoded + text = text_encoded # 构建群公告文本 announce_text = "[群公告]" diff --git a/src/recv_handler/notice_handler.py b/src/recv_handler/notice_handler.py index 2915241..1c9ea5d 100644 --- a/src/recv_handler/notice_handler.py +++ b/src/recv_handler/notice_handler.py @@ -105,6 +105,12 @@ class NoticeHandler: handled_message, user_info = await self.handle_poke_notify(raw_message, group_id, user_id) else: logger.warning("戳一戳消息被禁用,取消戳一戳处理") + case NoticeType.Notify.group_name: + if not await message_handler.check_allow_to_chat(user_id, group_id, True, False): + return None + logger.info("处理群名称变更") + handled_message, user_info = await self.handle_group_name_notify(raw_message, group_id, user_id) + system_notice = True case _: logger.warning(f"不支持的notify类型: {notice_type}.{sub_type}") case NoticeType.group_ban: @@ -1111,5 +1117,47 @@ class NoticeHandler: return notify_seg, user_info + async def handle_group_name_notify( + self, raw_message: dict, group_id: int, user_id: int + ) -> Tuple[Seg | None, UserInfo | None]: + """ + 处理群名称变更通知 + """ + new_name = raw_message.get("name_new") + + if not new_name: + logger.warning("群名称变更通知缺少新名称") + return None, None + + # 获取操作者信息 + user_info_dict: dict = await get_member_info(self.server_connection, group_id, user_id) + if user_info_dict: + user_name = user_info_dict.get("nickname") + user_cardname = user_info_dict.get("card") + else: + logger.warning("无法获取修改群名称的用户信息") + user_name = "QQ用户" + user_cardname = None + + user_info = UserInfo( + platform=global_config.maibot_server.platform_name, + user_id=user_id, + user_nickname=user_name, + user_cardname=user_cardname, + ) + + action_text = f"修改群名称为: {new_name}" + + notify_seg = Seg( + type="notify", + data={ + "sub_type": "group_name", + "action": action_text, + "new_name": new_name, + }, + ) + + return notify_seg, user_info + notice_handler = NoticeHandler() diff --git a/src/send_handler/send_message_handler.py b/src/send_handler/send_message_handler.py index 089353b..b5c70f5 100644 --- a/src/send_handler/send_message_handler.py +++ b/src/send_handler/send_message_handler.py @@ -54,8 +54,8 @@ class SendMessageHandleClass: voice_url = seg.data new_payload = cls.build_payload(payload, cls.handle_voiceurl_message(voice_url), False) elif seg.type == "music": - song_id = seg.data - new_payload = cls.build_payload(payload, cls.handle_music_message(song_id), False) + music_data = seg.data + new_payload = cls.build_payload(payload, cls.handle_music_message(music_data), False) elif seg.type == "videourl": video_url = seg.data new_payload = cls.build_payload(payload, cls.handle_videourl_message(video_url), False) @@ -170,12 +170,42 @@ class SendMessageHandleClass: } @staticmethod - def handle_music_message(song_id: str) -> dict: - """处理音乐消息""" - return { - "type": "music", - "data": {"type": "163", "id": song_id}, - } + def handle_music_message(music_data) -> dict: + """ + 处理音乐消息 + music_data 可以是: + 1. 字符串:默认为网易云音乐ID + 2. 字典:{"type": "163"/"qq", "id": "歌曲ID"} + """ + # 兼容旧格式:直接传入歌曲ID字符串 + if isinstance(music_data, str): + return { + "type": "music", + "data": {"type": "163", "id": music_data}, + } + + # 新格式:字典包含平台和ID + if isinstance(music_data, dict): + platform = music_data.get("type", "163") # 默认网易云 + song_id = music_data.get("id", "") + + # 验证平台类型 + if platform not in ["163", "qq"]: + logger.warning(f"不支持的音乐平台: {platform},使用默认平台163") + platform = "163" + + # 确保ID是字符串 + if not isinstance(song_id, str): + song_id = str(song_id) + + return { + "type": "music", + "data": {"type": platform, "id": song_id}, + } + + # 其他情况返回空 + logger.error(f"不支持的音乐数据格式: {type(music_data)}") + return {} @staticmethod def handle_videourl_message(video_url: str) -> dict: