From 5c6cdddbd3ba039b9edaaa4cf65489f222a6f4b4 Mon Sep 17 00:00:00 2001 From: A0000Xz <629995608@qq.com> Date: Sat, 28 Jun 2025 14:21:42 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=BA=86=E6=92=A4=E5=9B=9E?= =?UTF-8?q?=E6=B6=88=E6=81=AF=E6=8C=87=E4=BB=A4=EF=BC=9B=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E4=BA=86=E5=AF=B9=E8=87=AA=E8=BA=AB=E4=B8=8A=E6=8A=A5=E4=BF=A1?= =?UTF-8?q?=E6=81=AF=E7=9A=84=E5=A4=84=E7=90=86=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- main.py | 5 +- src/__init__.py | 1 + src/recv_handler/__init__.py | 1 + src/recv_handler/message_sent_handler.py | 173 +++++++++++++++++++++++ src/send_handler.py | 25 ++++ 5 files changed, 204 insertions(+), 1 deletion(-) create mode 100644 src/recv_handler/message_sent_handler.py diff --git a/main.py b/main.py index a928191..652d6b8 100644 --- a/main.py +++ b/main.py @@ -6,6 +6,7 @@ from src.logger import logger from src.recv_handler.message_handler import message_handler from src.recv_handler.meta_event_handler import meta_event_handler from src.recv_handler.notice_handler import notice_handler +from src.recv_handler.message_sent_handler import message_sent_handler from src.recv_handler.message_sending import message_send_instance from src.send_handler import send_handler from src.config import global_config @@ -27,7 +28,7 @@ async def message_recv(server_connection: Server.ServerConnection): ) decoded_raw_message: dict = json.loads(raw_message) post_type = decoded_raw_message.get("post_type") - if post_type in ["meta_event", "message", "notice"]: + if post_type in ["meta_event", "message", "notice","message_sent"]: await message_queue.put(decoded_raw_message) elif post_type is None: await put_response(decoded_raw_message) @@ -43,6 +44,8 @@ async def message_process(): await meta_event_handler.handle_meta_event(message) elif post_type == "notice": await notice_handler.handle_notice(message) + elif post_type == "message_sent": + await message_sent_handler.handle_sent_message(message) else: logger.warning(f"未知的post_type: {post_type}") message_queue.task_done() 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/message_sent_handler.py b/src/recv_handler/message_sent_handler.py new file mode 100644 index 0000000..be600d9 --- /dev/null +++ b/src/recv_handler/message_sent_handler.py @@ -0,0 +1,173 @@ +from src.logger import logger +from src.config import global_config +from src.utils import ( + get_group_info, + get_member_info, +) +from .message_sending import message_send_instance +from . import MessageSentType +from .message_handler import message_handler + +import time +import websockets as Server +from typing import List, Dict + +from maim_message import ( + UserInfo, + GroupInfo, + Seg, + BaseMessageInfo, + MessageBase, + TemplateInfo, + FormatInfo, +) + +class MessageSentHandler: + def __init__(self): + self.server_connection: Server.ServerConnection = None + self.bot_id_list: Dict[int, bool] = {} + + async def set_server_connection(self, server_connection: Server.ServerConnection) -> None: + """设置Napcat连接""" + self.server_connection = server_connection + + async def handle_sent_message(self, raw_message: dict) -> None: + """ + 从Napcat接受的原始发送消息处理 + + Parameters: + raw_message: dict: 原始消息 + """ + message_type: str = raw_message.get("message_type") + message_id: int = raw_message.get("message_id") + message_time: float = time.time() + + template_info: TemplateInfo = None # 模板信息,暂时为空,等待启用 + format_info: FormatInfo = FormatInfo( + content_format=["text", "image", "emoji"], + accept_format=["text", "image", "emoji", "reply"], + ) # 上报信息暂时只支持这四种解析 + if message_type == MessageSentType.private: + sub_type = raw_message.get("sub_type") + if sub_type == MessageSentType.Private.friend: + sender_info: dict = raw_message.get("sender") + + # 发送者用户信息 + user_info: UserInfo = UserInfo( + platform=global_config.maibot_server.platform_name, + user_id=sender_info.get("user_id"), + user_nickname=sender_info.get("nickname"), + user_cardname=sender_info.get("card"), + ) + + # 不存在群信息 + group_info: GroupInfo = None + elif sub_type == MessageSentType.Private.group: + """ + 本部分暂时不做支持,先放着 + """ + logger.warning("群临时消息类型不支持") + return None + + sender_info: dict = raw_message.get("sender") + + # 由于临时会话中,Napcat默认不发送成员昵称,所以需要单独获取 + fetched_member_info: dict = await get_member_info( + self.server_connection, + raw_message.get("group_id"), + sender_info.get("user_id"), + ) + nickname = fetched_member_info.get("nickname") if fetched_member_info else None + # 发送者用户信息 + user_info: UserInfo = UserInfo( + platform=global_config.maibot_server.platform_name, + user_id=sender_info.get("user_id"), + user_nickname=nickname, + user_cardname=None, + ) + + # -------------------这里需要群信息吗?------------------- + + # 获取群聊相关信息,在此单独处理group_name,因为默认发送的消息中没有 + fetched_group_info: dict = await get_group_info(self.server_connection, raw_message.get("group_id")) + group_name = "" + if fetched_group_info.get("group_name"): + group_name = fetched_group_info.get("group_name") + + group_info: GroupInfo = GroupInfo( + platform=global_config.maibot_server.platform_name, + group_id=raw_message.get("group_id"), + group_name=group_name, + ) + + else: + logger.warning(f"私聊消息类型 {sub_type} 不支持") + return None + elif message_type == MessageSentType.group: + sub_type = raw_message.get("sub_type") + if sub_type == MessageSentType.Group.normal: + sender_info: dict = raw_message.get("sender") + + # 发送者用户信息 + user_info: UserInfo = UserInfo( + platform=global_config.maibot_server.platform_name, + user_id=sender_info.get("user_id"), + user_nickname=sender_info.get("nickname"), + user_cardname=sender_info.get("card"), + ) + + # 获取群聊相关信息,在此单独处理group_name,因为默认发送的消息中没有 + fetched_group_info = await get_group_info(self.server_connection, raw_message.get("group_id")) + group_name: str = None + if fetched_group_info: + group_name = fetched_group_info.get("group_name") + + group_info: GroupInfo = GroupInfo( + platform=global_config.maibot_server.platform_name, + group_id=raw_message.get("group_id"), + group_name=group_name, + ) + + else: + logger.warning(f"群聊消息类型 {sub_type} 不支持") + return None + + additional_config: dict = {"sent_message":True} + + # 消息信息 + message_info: BaseMessageInfo = BaseMessageInfo( + platform=global_config.maibot_server.platform_name, + message_id=message_id, + time=message_time, + user_info=user_info, + group_info=group_info, + template_info=template_info, + format_info=format_info, + additional_config=additional_config, + ) + + # 处理实际信息 + if not raw_message.get("message"): + logger.warning("原始消息内容为空") + return None + + # 获取Seg列表 + seg_message: List[Seg] = await message_handler.handle_real_message(raw_message) + if not seg_message: + logger.warning("处理后消息内容为空") + return None + submit_seg: Seg = Seg( + type="seglist", + data=seg_message, + ) + # MessageBase创建 + message_base: MessageBase = MessageBase( + message_info=message_info, + message_segment=submit_seg, + raw_message=raw_message.get("raw_message"), + ) + + logger.info("发送到Maibot处理以更新数据库") + await message_send_instance.message_send(message_base) + +message_sent_handler = MessageSentHandler() \ No newline at end of file diff --git a/src/send_handler.py b/src/send_handler.py index 6cb3094..0be634d 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,29 @@ 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 (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())