"""通知图片测试命令 - 供超级用户在群聊/私聊中预览统一通知卡片。 用法(仅超级用户,群内直接发送或私聊发送,均无需 @机器人): 测试通知图片 通知图片测试 测试通知卡片 """ import asyncio from nonebot import on_command, logger from nonebot.adapters.onebot.v11 import Bot, Message, MessageEvent, MessageSegment from nonebot.matcher import Matcher from nonebot.permission import SUPERUSER from .preview_image_render import get_preview_renderer from .text_parser import TextParser # 主命令与别名,唯一的命令入口定义,测试直接据此断言 TEST_COMMAND = "测试通知图片" """主命令""" TEST_COMMAND_ALIASES = ("通知图片测试", "测试通知卡片") """命令别名""" # 固定预览内容:覆盖标题、中文、多行、Emoji 与中文标点,便于肉眼核对版式 PREVIEW_TITLE = "# 会被解析为换行:" """预览卡片标题行文案:同时演示 # 作为换行符的用法""" PREVIEW_TEXT = "\n".join( ( "【通知卡片测试】", "本卡片由「测试通知图片」命令生成,用于核对统一通知卡片版式。", "中文标点:逗号,句号。顿号、分号;冒号:问号?感叹号!", "Emoji:🎉 🏇 😀 👍🏻 🇨🇳", "混合排版:emoji 与正文之间不应错位 🎊,行距与折行都要正常。", ) ) """预览正文(按换行符直接给出,未经 # 替换)""" PREVIEW_PREVIEW_TEXT = PREVIEW_TEXT.replace("\n", "#") """预览文本的 # 写法,经 TextParser 解析后与 PREVIEW_TEXT 一致""" def resolve_scene(event: MessageEvent) -> str: """ 按事件来源选择场景徽章 Args: event: 消息事件 Returns: 群聊为 "group",否则为 "private" """ return "group" if getattr(event, "group_id", None) else "private" def build_message(image_base64: str) -> Message: """ 构建 OneBot V11 图片消息 Args: image_base64: base64:// 前缀的图片数据 Returns: 可直接发送的 Message """ return Message(MessageSegment.image(image_base64)) def preview_text() -> str: """ 构造固定预览文本(以 # 表示换行,交由 TextParser 解析) Returns: 预览文本 """ return PREVIEW_PREVIEW_TEXT test_notification_image = on_command( TEST_COMMAND, aliases=set(TEST_COMMAND_ALIASES), permission=SUPERUSER, priority=1, block=True, ) @test_notification_image.handle() async def handle_test_notification_image(matcher: Matcher, bot: Bot, event: MessageEvent): """把固定预览内容渲染成通知卡片并回发到当前会话。""" from . import plugin_config scene = resolve_scene(event) parsed_text = TextParser(max_length=plugin_config.MaxTextLength).parse(preview_text()) renderer = get_preview_renderer(plugin_config) try: # Pillow 渲染是同步阻塞操作,放到线程池避免阻塞事件循环 image_base64 = await asyncio.to_thread( renderer.render_to_base64, parsed_text, PREVIEW_TITLE, scene ) # 用当前事件的 Bot 直接发送 OneBot V11 图片消息,群聊/私聊都回到触发会话 await bot.send(event, build_message(image_base64)) logger.info(f"[Danding_QqPush] 通知图片测试成功 - scene={scene}") except BaseException as e: # 保留 NoneBot 控制流异常(如 FinishedException),只处理真正的异常 if not isinstance(e, Exception): raise logger.error(f"[Danding_QqPush] 通知图片测试失败 - scene={scene}: {e}") await matcher.finish("通知图片生成失败,请查看机器人日志后重试。")