diff --git a/README.md b/README.md index 3e76e39..266ebac 100644 --- a/README.md +++ b/README.md @@ -63,7 +63,7 @@ sequenceDiagram - [x] 读取戳一戳的自定义内容 - [ ] 语音解析(?) - [ ] 所有的notice类 - - [ ] 撤回 + - [x] 撤回(已添加相关指令) - [x] 发送消息 - [x] 发送文本 - [x] 发送图片 diff --git a/command_args.md b/command_args.md index 01390a7..afd5f37 100644 --- a/command_args.md +++ b/command_args.md @@ -46,4 +46,15 @@ Seg.data: Dict[str, Any] = { "qq_id": "目标QQ号" } } -``` \ No newline at end of file +``` + +## 撤回消息 +```python +Seg.data: Dict[str, Any] = { + "name": "DELETE_MSG", + "args": { + "message_id": "消息所对应的message_id" + } +} +``` +message_id怎么搞到手全凭你本事,也请在自己的插件里写好确定是否能撤回对应的消息的功能,毕竟这玩意真的单纯根据message_id撤消息 \ No newline at end of file diff --git a/src/__init__.py b/src/__init__.py index b1ac77e..0ac0aa5 100644 --- a/src/__init__.py +++ b/src/__init__.py @@ -11,6 +11,7 @@ class CommandType(Enum): GROUP_WHOLE_BAN = "set_group_whole_ban" # 群全体禁言 GROUP_KICK = "set_group_kick" # 踢出群聊 SEND_POKE = "send_poke" # 戳一戳 + DELETE_MSG = "delete_msg" # 撤回消息 def __str__(self) -> str: return self.value diff --git a/src/recv_handler/__init__.py b/src/recv_handler/__init__.py index 40f0070..5bd1b74 100644 --- a/src/recv_handler/__init__.py +++ b/src/recv_handler/__init__.py @@ -78,6 +78,7 @@ class CommandType(Enum): GROUP_WHOLE_BAN = "set_group_whole_ban" # 群全体禁言 GROUP_KICK = "set_group_kick" # 踢出群聊 SEND_POKE = "send_poke" # 戳一戳 + DELETE_MSG = "delete_msg" # 撤回消息 def __str__(self) -> str: return self.value diff --git a/src/recv_handler/notice_handler.py b/src/recv_handler/notice_handler.py index 0f46b04..cf84848 100644 --- a/src/recv_handler/notice_handler.py +++ b/src/recv_handler/notice_handler.py @@ -78,6 +78,7 @@ class NoticeHandler: group_id = raw_message.get("group_id") user_id = raw_message.get("user_id") + target_id = raw_message.get("target_id") handled_message: Seg = None user_info: UserInfo = None @@ -151,6 +152,7 @@ class NoticeHandler: group_info=group_info, template_info=None, format_info=None, + additional_config = {"target_id": target_id}# 在这里塞了一个target_id,方便mmc那边知道被戳的人是谁 ) message_base: MessageBase = MessageBase( @@ -165,68 +167,79 @@ class NoticeHandler: logger.info("发送到Maibot处理通知信息") await message_send_instance.message_send(message_base) - async def handle_poke_notify(self, raw_message: dict, group_id: int, user_id: int) -> Tuple[Seg | None, UserInfo]: + async def handle_poke_notify(self, raw_message: dict, group_id: int, user_id: int) -> Tuple[Seg | None, UserInfo | None]: self_info: dict = await get_self_info(self.server_connection) + if not self_info: logger.error("自身信息获取失败") - return None + return None, None + self_id = raw_message.get("self_id") target_id = raw_message.get("target_id") target_name: str = None raw_info: list = raw_message.get("raw_info") - # 计算user_info - source_name: str = None - source_cardname: str = None if group_id: - member_info: dict = await get_member_info(self.server_connection, group_id, user_id) - if member_info: - source_name = member_info.get("nickname") - source_cardname = member_info.get("card") + user_qq_info: dict = await get_member_info( + self.server_connection, group_id, user_id + ) + if user_qq_info: + user_name = user_qq_info.get("nickname") + user_cardname = user_qq_info.get("card") else: - logger.warning("无法获取戳一戳消息发送者的昵称,消息可能会无效") - source_name = "QQ用户" + user_name = "QQ用户" + user_cardname = "QQ用户" + logger.info("无法获取戳一戳对方的用户昵称") else: - stranger_info = await get_stranger_info(self.server_connection, user_id) - if stranger_info: - source_name = stranger_info.get("nickname") + user_qq_info: dict = await get_stranger_info( + self.server_connection, user_id + ) + if user_qq_info: + user_name = user_qq_info.get("nickname") + user_cardname = user_qq_info.get("card") else: - logger.warning("无法获取戳一戳消息发送者的昵称,消息可能会无效") - source_name = "QQ用户" - - user_info: UserInfo = UserInfo( - platform=global_config.maibot_server.platform_name, - user_id=user_id, - user_nickname=source_name, - user_cardname=source_cardname, - ) + user_name = "QQ用户" + user_cardname = "QQ用户" + logger.info("无法获取戳一戳对方的用户昵称") # 计算Seg - if self_id == target_id: + if self_id == target_id: # 现在这里应当是专注于处理私聊戳一戳的,也就是说当私聊里,被戳的是另一方时,不会给这个消息。 + display_name = "" target_name = self_info.get("nickname") + + elif self_id == user_id: + return None, None # 这应当让ada不发送麦麦戳别人的消息,因为这个消息已经被mmc的命令记录了,没必要记第二次。 + else: - return None, None + if group_id: # 如果是群聊环境,老实说做这一步判定没啥意义,毕竟私聊是没有其他人之间的戳一戳的,但是感觉可以有这个判定来强限制群聊环境 + fetched_member_info: dict = await get_member_info( + self.server_connection, group_id, target_id + ) + if fetched_member_info: + target_name = fetched_member_info.get("nickname") + else: + target_name = "QQ用户" + logger.info("无法获取被戳一戳方的用户昵称") + display_name = user_name + else: + return None, None try: first_txt = raw_info[2].get("txt", "戳了戳") second_txt = raw_info[4].get("txt", "") except Exception as e: logger.warning(f"解析戳一戳消息失败: {str(e)},将使用默认文本") first_txt = "戳了戳" - second_txt = "" - """ - # 不启用戳其他人的处理 - else: - # 由于Napcat不支持获取昵称,所以需要单独获取 - group_id = raw_message.get("group_id") - fetched_member_info: dict = await get_member_info( - self.server_connection, group_id, target_id - ) - if fetched_member_info: - target_name = fetched_member_info.get("nickname") - """ + + user_info: UserInfo = UserInfo( + platform=global_config.maibot_server.platform_name, + user_id=user_id, + user_nickname=user_name, + user_cardname=user_cardname, + ) + seg_data: Seg = Seg( type="text", - data=f"{first_txt}{target_name}{second_txt}(这是QQ的一个功能,用于提及某人,但没那么明显)", + data=f"{display_name}{first_txt}{target_name}{second_txt}(这是QQ的一个功能,用于提及某人,但没那么明显)", ) return seg_data, user_info @@ -503,4 +516,4 @@ class NoticeHandler: await asyncio.sleep(1) -notice_handler = NoticeHandler() +notice_handler = NoticeHandler() \ No newline at end of file diff --git a/src/send_handler.py b/src/send_handler.py index 6cb3094..8e14852 100644 --- a/src/send_handler.py +++ b/src/send_handler.py @@ -103,6 +103,8 @@ class SendHandler: command, args_dict = self.handle_kick_command(seg_data.get("args"), group_info) case CommandType.SEND_POKE.name: command, args_dict = self.handle_poke_command(seg_data.get("args"), group_info) + case CommandType.DELETE_MSG.name: + command, args_dict = self.delete_msg_command(seg_data.get("args")) case _: logger.error(f"未知命令: {command_name}") return @@ -347,6 +349,31 @@ class SendHandler: "user_id": user_id, }, ) + + def delete_msg_command(self, args: Dict[str, Any]) -> Tuple[str, Dict[str, Any]]: + """处理撤回消息命令 + + Args: + args (Dict[str, Any]): 参数字典 + + Returns: + Tuple[CommandType, Dict[str, Any]] + """ + try: + message_id = int(args["message_id"]) + if message_id <= 0: + raise ValueError("消息ID无效") + except KeyError: + raise ValueError("缺少必需参数: message_id") + except (ValueError, TypeError) as e: + raise ValueError(f"消息ID无效: {args['message_id']} - {str(e)}") + + return ( + CommandType.DELETE_MSG.value, + { + "message_id": message_id + }, + ) async def send_message_to_napcat(self, action: str, params: dict) -> dict: request_uuid = str(uuid.uuid4())