From eb7c8300faa9cbd62664ee93981a915a9530f681 Mon Sep 17 00:00:00 2001 From: snowy Date: Tue, 20 Aug 2024 20:30:50 +0800 Subject: [PATCH] =?UTF-8?q?:sparkles:=E6=93=B4=E5=B1=95event=E5=AD=97?= =?UTF-8?q?=E6=AE=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- liteyuki/message/event.py | 56 ++++++--- liteyuki/message/matcher.py | 4 +- liteyuki/message/on.py | 5 +- liteyuki/message/rule.py | 6 +- src/liteyuki_plugins/hello_liteyuki.py | 6 +- .../liteyuki_satori_user_info/auto_update.py | 1 - src/nonebot_plugins/to_liteyuki.py | 12 +- src/utils/message/message.py | 109 +++--------------- 8 files changed, 74 insertions(+), 125 deletions(-) diff --git a/liteyuki/message/event.py b/liteyuki/message/event.py index 834e6e9b..d6221a5f 100644 --- a/liteyuki/message/event.py +++ b/liteyuki/message/event.py @@ -8,32 +8,57 @@ Copyright (C) 2020-2024 LiteyukiStudio. All Rights Reserved @File : event.py @Software: PyCharm """ -from typing import Any +from typing import Any, Optional from liteyuki.comm.storage import shared_memory -class Event: - def __init__(self, type: str, data: dict[str, Any], bot_id: str, session_id: str, session_type: str, receive_channel: str = "event_to_nonebot"): +class MessageEvent: + def __init__( + self, + + bot_id: str, + message: list[dict[str, Any]] | str, + message_type: str, + raw_message: str, + session_id: str, + session_type: str, + receive_channel: str, + data: Optional[dict[str, Any]] = None, + ): """ - 事件 + 轻雪抽象消息事件 Args: - type: 类型 - data: 数据 + bot_id: 机器人ID - session_id: 会话ID - session_type: 会话类型 - receive_channel: 接收频道 + message: 消息,消息段数组[{type: str, data: dict[str, Any]}] + raw_message: 原始消息(通常为纯文本的格式) + message_type: 消息类型(private, group, other) + + session_id: 会话ID(私聊通常为用户ID,群聊通常为群ID) + session_type: 会话类型(private, group) + receive_channel: 接收频道(用于回复消息) + + data: 附加数据 """ - self.type = type + + if data is None: + data = {} + self.message_type = message_type self.data = data self.bot_id = bot_id + + self.message = message + self.raw_message = raw_message + self.session_id = session_id self.session_type = session_type + self.receive_channel = receive_channel def __str__(self): - return f"Event(type={self.type}, data={self.data}, bot_id={self.bot_id}, session_id={self.session_id}, session_type={self.session_type})" + return (f"Event(message_type={self.message_type}, data={self.data}, bot_id={self.bot_id}, " + f"session_id={self.session_id}, session_type={self.session_type})") def reply(self, message: str | dict[str, Any]): """ @@ -42,8 +67,10 @@ class Event: message: Returns: """ - to_nonebot_event = Event( - type=self.session_type, + reply_event = MessageEvent( + message_type=self.session_type, + message=message, + raw_message="", data={ "message": message }, @@ -52,5 +79,4 @@ class Event: session_type=self.session_type, receive_channel="_" ) - print(to_nonebot_event) - shared_memory.publish(self.receive_channel, to_nonebot_event) + shared_memory.publish(self.receive_channel, reply_event) diff --git a/liteyuki/message/matcher.py b/liteyuki/message/matcher.py index a29c94ab..4e54d0f9 100644 --- a/liteyuki/message/matcher.py +++ b/liteyuki/message/matcher.py @@ -11,10 +11,10 @@ Copyright (C) 2020-2024 LiteyukiStudio. All Rights Reserved import traceback from typing import Any, TypeAlias, Callable, Coroutine -from liteyuki import Event +from liteyuki.message.event import MessageEvent from liteyuki.message.rule import Rule -EventHandler: TypeAlias = Callable[[Event], Coroutine[None, None, Any]] +EventHandler: TypeAlias = Callable[[MessageEvent], Coroutine[None, None, Any]] class Matcher: diff --git a/liteyuki/message/on.py b/liteyuki/message/on.py index 8b1259c4..bbc161e4 100644 --- a/liteyuki/message/on.py +++ b/liteyuki/message/on.py @@ -8,13 +8,12 @@ Copyright (C) 2020-2024 LiteyukiStudio. All Rights Reserved @File : on.py @Software: PyCharm """ -import threading from queue import Queue from liteyuki.comm.storage import shared_memory from liteyuki.log import logger -from liteyuki.message.event import Event +from liteyuki.message.event import MessageEvent from liteyuki.message.matcher import Matcher from liteyuki.message.rule import Rule @@ -23,7 +22,7 @@ _queue: Queue = Queue() @shared_memory.on_subscriber_receive("event_to_liteyuki") -async def _(event: Event): +async def _(event: MessageEvent): current_priority = -1 for i, matcher in enumerate(_matcher_list): logger.info(f"Running matcher {matcher} for event: {event}") diff --git a/liteyuki/message/rule.py b/liteyuki/message/rule.py index 3c1443ea..31af299e 100644 --- a/liteyuki/message/rule.py +++ b/liteyuki/message/rule.py @@ -11,9 +11,9 @@ Copyright (C) 2020-2024 LiteyukiStudio. All Rights Reserved from typing import Optional, TypeAlias, Callable, Coroutine -from liteyuki.message.event import Event +from liteyuki.message.event import MessageEvent -RuleHandler: TypeAlias = Callable[[Event], Coroutine[None, None, bool]] +RuleHandler: TypeAlias = Callable[[MessageEvent], Coroutine[None, None, bool]] """规则函数签名""" @@ -27,7 +27,7 @@ class Rule: def __and__(self, other: "Rule") -> "Rule": return Rule(lambda event: self.handler(event) and other.handler(event)) - async def __call__(self, event: Event) -> bool: + async def __call__(self, event: MessageEvent) -> bool: if self.handler is None: return True return await self.handler(event) diff --git a/src/liteyuki_plugins/hello_liteyuki.py b/src/liteyuki_plugins/hello_liteyuki.py index 4ca03260..72d1ac42 100644 --- a/src/liteyuki_plugins/hello_liteyuki.py +++ b/src/liteyuki_plugins/hello_liteyuki.py @@ -10,7 +10,7 @@ Copyright (C) 2020-2024 LiteyukiStudio. All Rights Reserved """ from liteyuki.plugin import PluginMetadata, PluginType from liteyuki.message.on import on_message -from liteyuki.message.event import Event +from liteyuki.message.event import MessageEvent __plugin_meta__ = PluginMetadata( name="你好轻雪", @@ -19,6 +19,6 @@ __plugin_meta__ = PluginMetadata( @on_message().handle -async def _(event: Event): - if str(event.data["raw_message"]) == "你好轻雪": +async def _(event: MessageEvent): + if str(event.raw_message) == "你好轻雪": event.reply("你好呀") diff --git a/src/nonebot_plugins/liteyuki_satori_user_info/auto_update.py b/src/nonebot_plugins/liteyuki_satori_user_info/auto_update.py index bb4b40bd..d7631647 100644 --- a/src/nonebot_plugins/liteyuki_satori_user_info/auto_update.py +++ b/src/nonebot_plugins/liteyuki_satori_user_info/auto_update.py @@ -1,7 +1,6 @@ import nonebot from nonebot.message import event_preprocessor -# from nonebot_plugin_alconna.typings import Event from src.utils.base.ly_typing import T_MessageEvent from src.utils import satori_utils from nonebot.adapters import satori diff --git a/src/nonebot_plugins/to_liteyuki.py b/src/nonebot_plugins/to_liteyuki.py index 1d01bcfd..8358db5c 100644 --- a/src/nonebot_plugins/to_liteyuki.py +++ b/src/nonebot_plugins/to_liteyuki.py @@ -12,7 +12,7 @@ from nonebot import Bot, get_bot, on_message from nonebot.plugin import PluginMetadata from nonebot.adapters.onebot.v11 import MessageEvent, Bot from liteyuki.comm.storage import shared_memory -from liteyuki.message.event import Event +from liteyuki.message.event import MessageEvent as LiteyukiMessageEvent __plugin_meta__ = PluginMetadata( name="轻雪物流", @@ -23,8 +23,10 @@ __plugin_meta__ = PluginMetadata( @on_message().handle() async def _(bot: Bot, event: MessageEvent): - liteyuki_event = Event( - type=event.message_type, + liteyuki_event = LiteyukiMessageEvent( + message_type=event.message_type, + message=event.dict()["message"], + raw_message=event.raw_message, data=event.dict(), bot_id=bot.self_id, session_id=str(event.user_id if event.message_type == "private" else event.group_id), @@ -35,6 +37,6 @@ async def _(bot: Bot, event: MessageEvent): @shared_memory.on_subscriber_receive("event_to_nonebot") -async def _(event: Event): +async def _(event: MessageEvent): bot: Bot = get_bot(event.bot_id) - await bot.send_msg(message_type=event.type, user_id=int(event.session_id), group_id=int(event.session_id), message=event.data["message"]) + await bot.send_msg(message_type=event.message_type, user_id=int(event.session_id), group_id=int(event.session_id), message=event.data["message"]) diff --git a/src/utils/message/message.py b/src/utils/message/message.py index 6fbefa66..67ca76a1 100644 --- a/src/utils/message/message.py +++ b/src/utils/message/message.py @@ -1,18 +1,15 @@ import base64 import io +from typing import Any from urllib.parse import quote import aiofiles -from PIL import Image import aiohttp import nonebot +from PIL import Image from nonebot import require from nonebot.adapters import satori from nonebot.adapters.onebot import v11 -from typing import Any, Type - -from nonebot.internal.adapter import MessageSegment -from nonebot.internal.adapter.message import TM from .. import load_from_yaml from ..base.ly_typing import T_Bot, T_Message, T_MessageEvent @@ -65,81 +62,18 @@ class MarkdownMessage: """ formatted_md = v11.unescape(markdown).replace("\n", r"\n").replace('"', r'\\\"') - if event is not None and message_type is None: - if isinstance(event, satori.event.Event): - message_type = "private" if event.guild is None else "group" - group_id = event.guild.id if event.guild is not None else None - else: - assert event is not None - message_type = event.message_type - group_id = event.group_id if message_type == "group" else None - user_id = event.user.id if isinstance(event, satori.event.Event) else event.user_id - session_id = user_id if message_type == "private" else group_id - else: - pass - try: - raise TencentBannedMarkdownError("Tencent banned markdown") - forward_id = await bot.call_api( - "send_private_forward_msg", - messages=[ - { - "type": "node", - "data": { - "content": [ - { - "data": { - "content": "{\"content\":\"%s\"}" % formatted_md, - }, - "type": "markdown" - } - ], - "name": "[]", - "uin": bot.self_id - } - } - ], - user_id=bot.self_id - - ) - data = await bot.send_msg( - user_id=session_id, - group_id=session_id, - message_type=message_type, - message=[ - { - "type": "longmsg", - "data": { - "id": forward_id - } - }, - ], - **kwargs - ) - except BaseException as e: - nonebot.logger.error(f"send markdown error, retry as image: {e}") - # 发送失败,渲染为图片发送 - # if not retry_as_image: - # return None - - plain_markdown = markdown.replace("[🔗", "[") - md_image_bytes = await md_to_pic( - md=plain_markdown, - width=540, - device_scale_factor=4 - ) - if isinstance(bot, satori.Bot): - msg_seg = satori.MessageSegment.image(raw=md_image_bytes,mime="image/png") - data = await bot.send( - event=event, - message=msg_seg - ) - else: - data = await bot.send_msg( - message_type=message_type, - group_id=session_id, - user_id=session_id, - message=v11.MessageSegment.image(md_image_bytes), - ) + plain_markdown = formatted_md.replace("[🔗", "[") + md_image_bytes = await md_to_pic( + md=plain_markdown, + width=540, + device_scale_factor=4 + ) + data = await bot.send_msg( + message_type=message_type, + group_id=session_id, + user_id=session_id, + message=v11.MessageSegment.image(md_image_bytes), + ) return data @staticmethod @@ -156,28 +90,17 @@ class MarkdownMessage: Args: image: 图片字节流或图片本地路径,链接请使用Markdown.image_async方法获取后通过send_md发送 bot: bot instance - message_type: message type + message_type: message message_type session_id: session id event: event kwargs: other arguments Returns: dict: response data - """ if isinstance(image, str): async with aiofiles.open(image, "rb") as f: image = await f.read() method = 2 - # 1.轻雪图床方案 - # if method == 1: - # image_url = await liteyuki_api.upload_image(image) - # image_size = Image.open(io.BytesIO(image)).size - # image_md = Markdown.image(image_url, image_size) - # data = await Markdown.send_md(image_md, bot, message_type=message_type, session_id=session_id, event=event, - # retry_as_image=False, - # **kwargs) - - # Lagrange.OneBot方案 if method == 2: base64_string = base64.b64encode(image).decode("utf-8") data = await bot.call_api("upload_image", file=f"base64://{base64_string}") @@ -190,7 +113,7 @@ class MarkdownMessage: image_message_id = (await bot.send_private_msg( user_id=bot.self_id, message=[ - v11.MessageSegment.image(file=image) + v11.MessageSegment.image(file=image) ] ))["message_id"] image_url = (await bot.get_msg(message_id=image_message_id))["message"][0]["data"]["url"]