结构调整
视频解析多图/多媒体结构 消息体适配
This commit is contained in:
@@ -0,0 +1,110 @@
|
||||
from nonebot import get_bot
|
||||
from nonebot import require
|
||||
from nonebot.adapters.onebot.v11 import Bot, Message, MessageEvent, MessageSegment
|
||||
from nonebot.log import logger
|
||||
|
||||
require("nonebot_plugin_htmlrender")
|
||||
from nonebot_plugin_htmlrender import md_to_pic
|
||||
|
||||
|
||||
async def send_markdown(
|
||||
bot: Bot,
|
||||
event: MessageEvent,
|
||||
markdown: str,
|
||||
fallback_text: str | None = None,
|
||||
) -> None:
|
||||
"""发送 Markdown
|
||||
|
||||
优先尝试 OneBot 后端的原生 markdown 消息段;后端不支持/失败时
|
||||
自动降级为 htmlrender 把 Markdown 渲染成图片发送,保证任何后端都能看到。
|
||||
"""
|
||||
# 1. 尝试原生 markdown 消息段(不同后端字段可能不同,失败自动降级)
|
||||
try:
|
||||
seg = MessageSegment("markdown", {"content": markdown})
|
||||
await bot.send(event=event, message=Message(seg))
|
||||
return
|
||||
except Exception as e:
|
||||
logger.warning(f"原生 markdown 发送失败,尝试降级为图片: {e}")
|
||||
|
||||
# 2. 降级:htmlrender 渲染成图片
|
||||
try:
|
||||
img = await md_to_pic(md=markdown, width=540, device_scale_factor=4)
|
||||
await bot.send(event=event, message=MessageSegment.image(img))
|
||||
except Exception as e:
|
||||
logger.error(f"Markdown 渲染图片失败,发送纯文本: {e}")
|
||||
await bot.send(event=event, message=fallback_text or markdown)
|
||||
|
||||
|
||||
async def send_poke(group_id: int | None = None, user_id: int = 0):
|
||||
"""发送戳一戳(OneBot V11 send_poke API)
|
||||
|
||||
group_id 为空时向私聊发送戳一戳;失败返回 None
|
||||
"""
|
||||
bot = get_bot()
|
||||
params = {"user_id": int(user_id)}
|
||||
if group_id:
|
||||
params["group_id"] = int(group_id)
|
||||
logger.debug(f"send_poke: {params}")
|
||||
try:
|
||||
return await bot.call_api("send_poke", **params)
|
||||
except Exception as e:
|
||||
logger.error(f"send_poke 失败: {e}")
|
||||
return None
|
||||
|
||||
|
||||
def get_reply_message(event: MessageEvent) -> Message:
|
||||
"""获取消息内容:若为回复消息则返回被回复的消息,否则返回当前消息"""
|
||||
if event.reply is not None:
|
||||
logger.info(f"此条消息为回复消息: {event.reply.message}")
|
||||
return event.reply.message
|
||||
logger.info(f"此条消息为普通消息: {event.message}")
|
||||
return event.message
|
||||
|
||||
|
||||
def build_forward_nodes(
|
||||
self_id: int,
|
||||
entries: list[tuple[str, str]],
|
||||
sender_name: str | None = None,
|
||||
) -> list[dict]:
|
||||
"""构造合并转发节点列表
|
||||
|
||||
entries: [(发送者名, 消息内容), ...]
|
||||
sender_name: 非空时所有节点统一使用该昵称(用于把插件名等放进 content,
|
||||
而不是作为转发节点的发送者昵称)
|
||||
"""
|
||||
return [
|
||||
{
|
||||
"type": "node",
|
||||
"data": {
|
||||
"name": sender_name if sender_name is not None else name,
|
||||
"uin": str(self_id),
|
||||
"content": content,
|
||||
},
|
||||
}
|
||||
for name, content in entries
|
||||
]
|
||||
|
||||
|
||||
async def send_forward_msg(
|
||||
bot: Bot,
|
||||
event: MessageEvent,
|
||||
entries: list[tuple[str, str]],
|
||||
fallback: str,
|
||||
sender_name: str | None = None,
|
||||
):
|
||||
"""群聊发送合并转发消息,私聊或发送失败时回退纯文本
|
||||
|
||||
entries: [(发送者名, 消息内容), ...]
|
||||
sender_name: 非空时统一用于节点发送者昵称(插件名等应写入 content)
|
||||
"""
|
||||
group_id = getattr(event, "group_id", None)
|
||||
if group_id:
|
||||
try:
|
||||
await bot.send_group_forward_msg(
|
||||
group_id=group_id,
|
||||
messages=build_forward_nodes(event.self_id, entries, sender_name),
|
||||
)
|
||||
return
|
||||
except Exception as e:
|
||||
logger.warning(f"合并转发发送失败,回退文本: {e}")
|
||||
await bot.send(event, fallback)
|
||||
Reference in New Issue
Block a user