From 63eb67843344c6b476f5bf25b4443704e14e78c0 Mon Sep 17 00:00:00 2001 From: A0000Xz <629995608@qq.com> Date: Thu, 26 Jun 2025 23:16:13 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=BA=86mmc=E5=AF=B9?= =?UTF-8?q?=E4=BA=8E=E4=B8=8A=E6=8A=A5=E6=B6=88=E6=81=AF=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E5=BA=93=E5=86=85message=5Fid=E7=9A=84?= =?UTF-8?q?=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 目前只能支持text,image,emoji和reply的message_id更新 --- src/chat/message_receive/bot.py | 7 ++ src/chat/message_receive/storage.py | 111 +++++++++++++++++++++++++++- 2 files changed, 117 insertions(+), 1 deletion(-) diff --git a/src/chat/message_receive/bot.py b/src/chat/message_receive/bot.py index 62f074636..9e46fc7ac 100644 --- a/src/chat/message_receive/bot.py +++ b/src/chat/message_receive/bot.py @@ -131,6 +131,13 @@ class ChatBot: message = MessageRecv(message_data) group_info = message.message_info.group_info user_info = message.message_info.user_info + sent_message = message.message_info.additional_config.get("sent_message", False) + + if user_info.user_id == global_config.bot.qq_account and sent_message: # 这一段只是为了在一切处理前劫持上报的自身消息,用于更新message_id,需要ada支持上报事件,实际测试中不会对正常使用造成任何问题 + await message.process() + await MessageStorage.update_message(message) + return + get_chat_manager().register_message(message) # 创建聊天流 diff --git a/src/chat/message_receive/storage.py b/src/chat/message_receive/storage.py index ac7818842..78a72d016 100644 --- a/src/chat/message_receive/storage.py +++ b/src/chat/message_receive/storage.py @@ -1,10 +1,13 @@ import re -from typing import Union +import base64 +import hashlib +from typing import Union, List # from ...common.database.database import db # db is now Peewee's SqliteDatabase instance from .message import MessageSending, MessageRecv from .chat_stream import ChatStream from ...common.database.database_model import Messages, RecalledMessages # Import Peewee models +from ...common.database.database_model import Images from src.common.logger import get_logger logger = get_logger("message_storage") @@ -103,3 +106,109 @@ class MessageStorage: # 如果需要其他存储相关的函数,可以在这里添加 + @staticmethod + async def update_message(message: MessageRecv) -> None: # 用于实时更新数据库的自身发送消息ID,目前能处理text,reply,image和emoji + """更新最新一条匹配消息的message_id,区分文字和图片情况""" + try: + new_message_id = message.message_info.message_id + user_id = message.message_info.user_info.user_id + + # 检查消息是否包含图片 + image_hashes = MessageStorage._extract_image_hashes(message.message_segment) + + if image_hashes: + # 图片消息处理 + await MessageStorage._update_image_message(message, new_message_id, user_id, image_hashes) + else: + # 文本消息处理 + await MessageStorage._update_text_message(message, new_message_id, user_id) + + except Exception: + logger.exception("更新消息ID失败") + + @staticmethod + def _extract_image_hashes(segment) -> List[str]: + """递归提取消息段中的所有图片哈希值""" + hashes = [] + + if segment.type == "image" or segment.type == "emoji": + try: + # 计算图片哈希值 + binary_data = base64.b64decode(segment.data) + file_hash = hashlib.md5(binary_data).hexdigest() + hashes.append(file_hash) + except Exception as e: + logger.error(f"计算图片哈希失败: {e}") + + elif segment.type == "seglist": + # 递归处理子消息段 + for sub_seg in segment.data: + hashes.extend(MessageStorage._extract_image_hashes(sub_seg)) + + return hashes + + @staticmethod + async def _update_image_message(message: MessageRecv, new_message_id: str, user_id: str, image_hashes: List[str]) -> None: + """处理图片消息的更新逻辑""" + + # 使用第一张图片的哈希值查询描述 + first_image_hash = image_hashes[0] + logger.info(f"{first_image_hash}") + + try: + # 查询图片描述 + image_desc = Images.get_or_none( + Images.emoji_hash == first_image_hash + ) + + if not image_desc or not image_desc.description: + logger.debug(f"未找到图片描述: {first_image_hash}") + return + + # 在Messages表中查找包含该描述的最新消息 + matched_message = Messages.select().where( + (Messages.user_id == user_id) & + (Messages.processed_plain_text.contains(image_desc.description)) + ).order_by(Messages.time.desc()).first() + + if matched_message: + # 更新找到的消息记录 + Messages.update(message_id=new_message_id).where( + Messages.id == matched_message.id + ).execute() + logger.info(f"更新图片消息ID成功: {matched_message.message_id} -> {new_message_id}") + else: + logger.debug(f"未找到包含描述'{image_desc.description}'的消息") + + except Exception as e: + logger.error(f"更新图片消息失败: {e}") + + @staticmethod + async def _update_text_message(message: MessageRecv, new_message_id: str, user_id: str) -> None: + """处理文本消息的更新逻辑""" + try: + # 过滤处理文本(与store_message相同的处理方式) + pattern = r".*?|.*?|.*?" + processed_plain_text = re.sub( + pattern, "", + message.processed_plain_text, + flags=re.DOTALL + ) if message.processed_plain_text else "" + + # 查询最新一条匹配消息 + matched_message = Messages.select().where( + (Messages.user_id == user_id) & + (Messages.processed_plain_text == processed_plain_text) + ).order_by(Messages.time.desc()).first() + + if matched_message: + # 更新找到的消息记录 + Messages.update(message_id=new_message_id).where( + Messages.id == matched_message.id + ).execute() + logger.info(f"更新文本消息ID成功: {matched_message.message_id} -> {new_message_id}") + else: + logger.debug("未找到匹配的文本消息") + + except Exception as e: + logger.error(f"更新文本消息失败: {e}") \ No newline at end of file