feat(video-analysis): 多文件媒体改走合并转发

抖音 note/小红书等多图、图+视频混合、多视频(动图)作品,下载产物
超过一个文件时直接拼成一条消息发送会失败(视频段不能与其他段混合),
统一改为合并转发: 一个图/视频一个节点,本地文件优先、S3 预签名链接
兜底; 单文件作品保持原有直发链路,多级发送链(本地→S3→回退)不变。

Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
2026-09-08 14:21:57 +08:00
co-authored by Claude Code
parent 8c1a106230
commit 30899688a7
2 changed files with 140 additions and 10 deletions
@@ -4,7 +4,6 @@ from __future__ import annotations
import html
import re
from typing import Optional
from nonebot import on_message, logger
from nonebot.adapters import Event
@@ -151,7 +150,7 @@ async def match_message(event: Event, plan: str | None = None):
return
if isinstance(message, PendingMedia):
ok, pub = await send_pending_media(message)
ok, pub = await send_pending_media(message, event)
if pub:
await UniMessage.text(f"{pub}").send()
if not ok:
@@ -166,7 +165,7 @@ async def dispatch_url(
url: str,
is_private: bool,
plan: str | None = None,
) -> tuple[Optional[UniMessage], Optional[str]]:
) -> tuple[UniMessage | None, str | None]:
"""按平台分派解析(文本链接与小程序卡片共用)。"""
url = url.rstrip(",。!?、;:)】》\"')")
@@ -246,7 +245,7 @@ async def dispatch_url(
return None, None
async def _extract_xcx_url(msg: str) -> Optional[str]:
async def _extract_xcx_url(msg: str) -> str | None:
"""从 CQ 卡片消息中提取跳转 URL(保留 query 参数)。"""
match = re.search(r'"qqdocurl":"(.*?)"', msg)
if not match: