From c758908745f740d5e6e2a63d8fed9b03639c666a Mon Sep 17 00:00:00 2001 From: sheetung <755855262@qq.com> Date: Mon, 18 May 2026 04:55:18 +0000 Subject: [PATCH] feat(aiocqhttp): handle json type messages in message converter Add support for parsing OneBot JSON message segments (QQ mini-program, Bilibili share cards, etc.) in the target2yiri converter. Parses the card metadata and converts it to plain text to avoid silently dropping these message types. Co-Authored-By: Claude Opus 4.7 --- src/langbot/pkg/platform/sources/aiocqhttp.py | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/src/langbot/pkg/platform/sources/aiocqhttp.py b/src/langbot/pkg/platform/sources/aiocqhttp.py index 50e7922c..287b4b04 100644 --- a/src/langbot/pkg/platform/sources/aiocqhttp.py +++ b/src/langbot/pkg/platform/sources/aiocqhttp.py @@ -3,6 +3,7 @@ import typing import asyncio import traceback import datetime +import json import aiocqhttp import pydantic @@ -293,6 +294,41 @@ class AiocqhttpMessageConverter(abstract_platform_adapter.AbstractMessageConvert elif msg.type == 'dice': face_id = msg.data['result'] yiri_msg_list.append(platform_message.Face(face_type='dice', face_id=int(face_id), face_name='骰子')) + elif msg.type == 'json': + try: + # `msg.data['data']` may already be a dict in some implementations, or a JSON string in others + raw = msg.data.get('data', {}) + if isinstance(raw, (dict, list)): + inner_data = raw + else: + try: + inner_data = json.loads(raw or '{}') + except Exception: + inner_data = {} + + # Try to parse QQ mini-program / Bilibili share cards + app_name = inner_data.get('app', '') if isinstance(inner_data, dict) else '' + if app_name == 'com.tencent.miniapp_01': + detail = inner_data.get('meta', {}) + # Some implementations nest details under detail_1 + detail_1 = detail.get('detail_1') if isinstance(detail, dict) else None + detail_block = detail_1 if isinstance(detail_1, dict) else detail + title = ( + detail_block.get('desc', '分享小程序') if isinstance(detail_block, dict) else '分享小程序' + ) + qqdocurl = detail_block.get('qqdocurl', '') if isinstance(detail_block, dict) else '' + + if qqdocurl: + clean_url = qqdocurl.split('?')[0] + text_content = f'[小程序:{title}] {clean_url}' + yiri_msg_list.append(platform_message.Plain(text=text_content)) + else: + yiri_msg_list.append(platform_message.Plain(text=f'[小程序:{title}]')) + else: + # Fallback for unknown JSON card types + yiri_msg_list.append(platform_message.Plain(text='[收到一张JSON卡片]')) + except Exception as e: + print(f'解析 JSON 消息失败: {e}') chain = platform_message.MessageChain(yiri_msg_list)