diff --git a/src/recv_handler/message_handler.py b/src/recv_handler/message_handler.py index b9fa2d2..b0ebb40 100644 --- a/src/recv_handler/message_handler.py +++ b/src/recv_handler/message_handler.py @@ -14,6 +14,7 @@ from . import RealMessageType, MessageType, ACCEPT_FORMAT import time import json +import base64 import websockets as Server from typing import List, Tuple, Optional, Dict, Any import uuid @@ -318,6 +319,11 @@ class MessageHandler: case RealMessageType.shake: # 预计等价于戳一戳 logger.warning("暂时不支持窗口抖动解析") + case "poke": + data = sub_message.get("data", {}) + poke_type = data.get("type") + poke_id = data.get("id") + seg_message.append(Seg(type="text", data="[戳一戳消息]"))) case RealMessageType.share: logger.warning("暂时不支持链接解析") case RealMessageType.forward: @@ -376,14 +382,64 @@ class MessageHandler: tag = contact_info.get("tag", "推荐群聊") seg_message.append(Seg(type="text", data=f"[{tag}] {name}")) - # 图文分享(如 哔哩哔哩、网页) + # 图文分享(如 哔哩哔哩HD、网页、群精华等) elif app_name == "com.tencent.tuwen.lua": news = meta.get("news", {}) title = news.get("title", "未知标题") - desc = news.get("desc", "") - tag = news.get("tag") or "图文分享" + desc = (news.get("desc", "") or "").replace("[图片]", "").strip() + tag = news.get("tag", "图文分享") + preview_url = news.get("preview", "") + if tag and title and tag in title: + title = title.replace(tag, "", 1).strip(":: -— ") seg_message.append(Seg(type="text", data=f"[{tag}] {title}:{desc}")) - + if preview_url: + try: + image_base64 = await get_image_base64(preview_url) + seg_message.append(Seg(type="image", data=image_base64)) + except Exception as e: + logger.error(f"图文图片下载失败: {e}") + + # 群相册(含预览图) + elif app_name == "com.tencent.feed.lua": + feed = meta.get("feed", {}) + title = feed.get("title", "群相册") + tag = feed.get("tagName", "群相册") + desc = feed.get("forwardMessage", "") + cover_url = feed.get("cover", "") + if tag and title and tag in title: + title = title.replace(tag, "", 1).strip(":: -— ") + seg_message.append(Seg(type="text", data=f"[{tag}] {title}:{desc}")) + if cover_url: + try: + image_base64 = await get_image_base64(cover_url) + seg_message.append(Seg(type="image", data=image_base64)) + except Exception as e: + logger.error(f"群相册图片下载失败: {e}") + + # 群公告(由于图片URL是加密的,因此无法读取) + elif app_name == "com.tencent.mannounce": + mannounce = meta.get("mannounce", {}) + title = mannounce.get("title", "") + text = mannounce.get("text", "") + encode_flag = mannounce.get("encode", 0) + if encode_flag == 1: + try: + if title: + title = base64.b64decode(title).decode("utf-8", errors="ignore") + if text: + text = base64.b64decode(text).decode("utf-8", errors="ignore") + except Exception as e: + logger.warning(f"群公告Base64解码失败: {e}") + if title and text: + content = f"[{title}]:{text}" + elif title: + content = f"[{title}]" + elif text: + content = f"{text}" + else: + content = "[群公告]" + seg_message.append(Seg(type="text", data=content)) + # QQ小程序分享(含预览图) elif app_name == "com.tencent.miniapp_01": detail = meta.get("detail_1", {}) @@ -391,15 +447,13 @@ class MessageHandler: desc = detail.get("desc", "") preview_url = detail.get("preview", "") tag = "QQ小程序" - seg_message.append(Seg(type="text", data=f"[{tag}] {title}:{desc}")) - if preview_url: try: image_base64 = await get_image_base64(preview_url) seg_message.append(Seg(type="image", data=image_base64)) except Exception as e: - logger.error(f"QQ小程序卡片图片下载失败: {e}") + logger.error(f"QQ小程序图片下载失败: {e}") # QQ收藏分享(含预览图) elif app_name == "com.tencent.template.qqfavorite.share": @@ -407,9 +461,7 @@ class MessageHandler: desc = news.get("desc", "").replace("[图片]", "").strip() preview_url = news.get("preview", "") tag = news.get("tag", "QQ收藏") - seg_message.append(Seg(type="text", data=f"[{tag}] {desc}")) - if preview_url: try: image_base64 = await get_image_base64(preview_url) @@ -423,15 +475,13 @@ class MessageHandler: title = miniapp.get("title", "未知标题") tag = miniapp.get("tag", "QQ空间") preview_url = miniapp.get("preview", "") - seg_message.append(Seg(type="text", data=f"[{tag}] {title}")) - if preview_url: try: image_base64 = await get_image_base64(preview_url) seg_message.append(Seg(type="image", data=image_base64)) except Exception as e: - logger.error(f"QQ空间分享卡片图片下载失败: {e}") + logger.error(f"QQ空间图片下载失败: {e}") # QQ地图位置分享 elif app_name == "com.tencent.map": @@ -459,12 +509,27 @@ class MessageHandler: title = news.get("title") or meta.get("title") desc = news.get("desc") or meta.get("desc") tag = news.get("tag") or meta.get("tag") - + encode_flag = news.get("encode") or meta.get("encode") or 0 + if encode_flag == 1: + try: + if title: + title = base64.b64decode(title).decode("utf-8", errors="ignore") + if desc: + desc = base64.b64decode(desc).decode("utf-8", errors="ignore") + except Exception as e: + logger.warning(f"Base64解码失败: {e}") + # 如果三者全都为空,记录错误并跳过输出 if not (title or desc or tag): logger.error(f"[JSON解析失败] app_name={app_name},未识别的字段:meta={meta}") continue + # 三者中至少要有两个有内容,否则判定为未识别类型 + non_empty_count = sum(bool(x) for x in [title, desc, tag]) + if non_empty_count < 2: + logger.warning(f"[JSON卡片字段不足] app_name={app_name},字段过少:title={title}, desc={desc}, tag={tag},字段:meta={meta}") + continue + if not tag: tag = "分享" if not title: @@ -476,7 +541,7 @@ class MessageHandler: # 未识别类型 else: - logger.warning(f"[未识别JSON卡片: {app_name}] {prompt}") + logger.warning(f"[未识别JSON卡片]: {prompt}") except Exception as e: logger.error(f"JSON卡片消息处理失败: {e}")