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 <noreply@anthropic.com>
This commit is contained in:
sheetung
2026-05-18 04:55:18 +00:00
parent 17bbc8bf10
commit c758908745

View File

@@ -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)