forked from bot/app
✨擴展event字段
This commit is contained in:
parent
287ab63091
commit
eb7c8300fa
@ -8,32 +8,57 @@ Copyright (C) 2020-2024 LiteyukiStudio. All Rights Reserved
|
|||||||
@File : event.py
|
@File : event.py
|
||||||
@Software: PyCharm
|
@Software: PyCharm
|
||||||
"""
|
"""
|
||||||
from typing import Any
|
from typing import Any, Optional
|
||||||
|
|
||||||
from liteyuki.comm.storage import shared_memory
|
from liteyuki.comm.storage import shared_memory
|
||||||
|
|
||||||
|
|
||||||
class Event:
|
class MessageEvent:
|
||||||
def __init__(self, type: str, data: dict[str, Any], bot_id: str, session_id: str, session_type: str, receive_channel: str = "event_to_nonebot"):
|
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:
|
Args:
|
||||||
type: 类型
|
|
||||||
data: 数据
|
|
||||||
bot_id: 机器人ID
|
bot_id: 机器人ID
|
||||||
session_id: 会话ID
|
message: 消息,消息段数组[{type: str, data: dict[str, Any]}]
|
||||||
session_type: 会话类型
|
raw_message: 原始消息(通常为纯文本的格式)
|
||||||
receive_channel: 接收频道
|
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.data = data
|
||||||
self.bot_id = bot_id
|
self.bot_id = bot_id
|
||||||
|
|
||||||
|
self.message = message
|
||||||
|
self.raw_message = raw_message
|
||||||
|
|
||||||
self.session_id = session_id
|
self.session_id = session_id
|
||||||
self.session_type = session_type
|
self.session_type = session_type
|
||||||
|
|
||||||
self.receive_channel = receive_channel
|
self.receive_channel = receive_channel
|
||||||
|
|
||||||
def __str__(self):
|
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]):
|
def reply(self, message: str | dict[str, Any]):
|
||||||
"""
|
"""
|
||||||
@ -42,8 +67,10 @@ class Event:
|
|||||||
message:
|
message:
|
||||||
Returns:
|
Returns:
|
||||||
"""
|
"""
|
||||||
to_nonebot_event = Event(
|
reply_event = MessageEvent(
|
||||||
type=self.session_type,
|
message_type=self.session_type,
|
||||||
|
message=message,
|
||||||
|
raw_message="",
|
||||||
data={
|
data={
|
||||||
"message": message
|
"message": message
|
||||||
},
|
},
|
||||||
@ -52,5 +79,4 @@ class Event:
|
|||||||
session_type=self.session_type,
|
session_type=self.session_type,
|
||||||
receive_channel="_"
|
receive_channel="_"
|
||||||
)
|
)
|
||||||
print(to_nonebot_event)
|
shared_memory.publish(self.receive_channel, reply_event)
|
||||||
shared_memory.publish(self.receive_channel, to_nonebot_event)
|
|
||||||
|
@ -11,10 +11,10 @@ Copyright (C) 2020-2024 LiteyukiStudio. All Rights Reserved
|
|||||||
import traceback
|
import traceback
|
||||||
from typing import Any, TypeAlias, Callable, Coroutine
|
from typing import Any, TypeAlias, Callable, Coroutine
|
||||||
|
|
||||||
from liteyuki import Event
|
from liteyuki.message.event import MessageEvent
|
||||||
from liteyuki.message.rule import Rule
|
from liteyuki.message.rule import Rule
|
||||||
|
|
||||||
EventHandler: TypeAlias = Callable[[Event], Coroutine[None, None, Any]]
|
EventHandler: TypeAlias = Callable[[MessageEvent], Coroutine[None, None, Any]]
|
||||||
|
|
||||||
|
|
||||||
class Matcher:
|
class Matcher:
|
||||||
|
@ -8,13 +8,12 @@ Copyright (C) 2020-2024 LiteyukiStudio. All Rights Reserved
|
|||||||
@File : on.py
|
@File : on.py
|
||||||
@Software: PyCharm
|
@Software: PyCharm
|
||||||
"""
|
"""
|
||||||
import threading
|
|
||||||
|
|
||||||
from queue import Queue
|
from queue import Queue
|
||||||
|
|
||||||
from liteyuki.comm.storage import shared_memory
|
from liteyuki.comm.storage import shared_memory
|
||||||
from liteyuki.log import logger
|
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.matcher import Matcher
|
||||||
from liteyuki.message.rule import Rule
|
from liteyuki.message.rule import Rule
|
||||||
|
|
||||||
@ -23,7 +22,7 @@ _queue: Queue = Queue()
|
|||||||
|
|
||||||
|
|
||||||
@shared_memory.on_subscriber_receive("event_to_liteyuki")
|
@shared_memory.on_subscriber_receive("event_to_liteyuki")
|
||||||
async def _(event: Event):
|
async def _(event: MessageEvent):
|
||||||
current_priority = -1
|
current_priority = -1
|
||||||
for i, matcher in enumerate(_matcher_list):
|
for i, matcher in enumerate(_matcher_list):
|
||||||
logger.info(f"Running matcher {matcher} for event: {event}")
|
logger.info(f"Running matcher {matcher} for event: {event}")
|
||||||
|
@ -11,9 +11,9 @@ Copyright (C) 2020-2024 LiteyukiStudio. All Rights Reserved
|
|||||||
|
|
||||||
from typing import Optional, TypeAlias, Callable, Coroutine
|
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":
|
def __and__(self, other: "Rule") -> "Rule":
|
||||||
return Rule(lambda event: self.handler(event) and other.handler(event))
|
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:
|
if self.handler is None:
|
||||||
return True
|
return True
|
||||||
return await self.handler(event)
|
return await self.handler(event)
|
||||||
|
@ -10,7 +10,7 @@ Copyright (C) 2020-2024 LiteyukiStudio. All Rights Reserved
|
|||||||
"""
|
"""
|
||||||
from liteyuki.plugin import PluginMetadata, PluginType
|
from liteyuki.plugin import PluginMetadata, PluginType
|
||||||
from liteyuki.message.on import on_message
|
from liteyuki.message.on import on_message
|
||||||
from liteyuki.message.event import Event
|
from liteyuki.message.event import MessageEvent
|
||||||
|
|
||||||
__plugin_meta__ = PluginMetadata(
|
__plugin_meta__ = PluginMetadata(
|
||||||
name="你好轻雪",
|
name="你好轻雪",
|
||||||
@ -19,6 +19,6 @@ __plugin_meta__ = PluginMetadata(
|
|||||||
|
|
||||||
|
|
||||||
@on_message().handle
|
@on_message().handle
|
||||||
async def _(event: Event):
|
async def _(event: MessageEvent):
|
||||||
if str(event.data["raw_message"]) == "你好轻雪":
|
if str(event.raw_message) == "你好轻雪":
|
||||||
event.reply("你好呀")
|
event.reply("你好呀")
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import nonebot
|
import nonebot
|
||||||
|
|
||||||
from nonebot.message import event_preprocessor
|
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.base.ly_typing import T_MessageEvent
|
||||||
from src.utils import satori_utils
|
from src.utils import satori_utils
|
||||||
from nonebot.adapters import satori
|
from nonebot.adapters import satori
|
||||||
|
@ -12,7 +12,7 @@ from nonebot import Bot, get_bot, on_message
|
|||||||
from nonebot.plugin import PluginMetadata
|
from nonebot.plugin import PluginMetadata
|
||||||
from nonebot.adapters.onebot.v11 import MessageEvent, Bot
|
from nonebot.adapters.onebot.v11 import MessageEvent, Bot
|
||||||
from liteyuki.comm.storage import shared_memory
|
from liteyuki.comm.storage import shared_memory
|
||||||
from liteyuki.message.event import Event
|
from liteyuki.message.event import MessageEvent as LiteyukiMessageEvent
|
||||||
|
|
||||||
__plugin_meta__ = PluginMetadata(
|
__plugin_meta__ = PluginMetadata(
|
||||||
name="轻雪物流",
|
name="轻雪物流",
|
||||||
@ -23,8 +23,10 @@ __plugin_meta__ = PluginMetadata(
|
|||||||
|
|
||||||
@on_message().handle()
|
@on_message().handle()
|
||||||
async def _(bot: Bot, event: MessageEvent):
|
async def _(bot: Bot, event: MessageEvent):
|
||||||
liteyuki_event = Event(
|
liteyuki_event = LiteyukiMessageEvent(
|
||||||
type=event.message_type,
|
message_type=event.message_type,
|
||||||
|
message=event.dict()["message"],
|
||||||
|
raw_message=event.raw_message,
|
||||||
data=event.dict(),
|
data=event.dict(),
|
||||||
bot_id=bot.self_id,
|
bot_id=bot.self_id,
|
||||||
session_id=str(event.user_id if event.message_type == "private" else event.group_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")
|
@shared_memory.on_subscriber_receive("event_to_nonebot")
|
||||||
async def _(event: Event):
|
async def _(event: MessageEvent):
|
||||||
bot: Bot = get_bot(event.bot_id)
|
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"])
|
||||||
|
@ -1,18 +1,15 @@
|
|||||||
import base64
|
import base64
|
||||||
import io
|
import io
|
||||||
|
from typing import Any
|
||||||
from urllib.parse import quote
|
from urllib.parse import quote
|
||||||
|
|
||||||
import aiofiles
|
import aiofiles
|
||||||
from PIL import Image
|
|
||||||
import aiohttp
|
import aiohttp
|
||||||
import nonebot
|
import nonebot
|
||||||
|
from PIL import Image
|
||||||
from nonebot import require
|
from nonebot import require
|
||||||
from nonebot.adapters import satori
|
from nonebot.adapters import satori
|
||||||
from nonebot.adapters.onebot import v11
|
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 .. import load_from_yaml
|
||||||
from ..base.ly_typing import T_Bot, T_Message, T_MessageEvent
|
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'\\\"')
|
formatted_md = v11.unescape(markdown).replace("\n", r"\n").replace('"', r'\\\"')
|
||||||
if event is not None and message_type is None:
|
plain_markdown = formatted_md.replace("[🔗", "[")
|
||||||
if isinstance(event, satori.event.Event):
|
md_image_bytes = await md_to_pic(
|
||||||
message_type = "private" if event.guild is None else "group"
|
md=plain_markdown,
|
||||||
group_id = event.guild.id if event.guild is not None else None
|
width=540,
|
||||||
else:
|
device_scale_factor=4
|
||||||
assert event is not None
|
)
|
||||||
message_type = event.message_type
|
data = await bot.send_msg(
|
||||||
group_id = event.group_id if message_type == "group" else None
|
message_type=message_type,
|
||||||
user_id = event.user.id if isinstance(event, satori.event.Event) else event.user_id
|
group_id=session_id,
|
||||||
session_id = user_id if message_type == "private" else group_id
|
user_id=session_id,
|
||||||
else:
|
message=v11.MessageSegment.image(md_image_bytes),
|
||||||
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),
|
|
||||||
)
|
|
||||||
return data
|
return data
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@ -156,28 +90,17 @@ class MarkdownMessage:
|
|||||||
Args:
|
Args:
|
||||||
image: 图片字节流或图片本地路径,链接请使用Markdown.image_async方法获取后通过send_md发送
|
image: 图片字节流或图片本地路径,链接请使用Markdown.image_async方法获取后通过send_md发送
|
||||||
bot: bot instance
|
bot: bot instance
|
||||||
message_type: message type
|
message_type: message message_type
|
||||||
session_id: session id
|
session_id: session id
|
||||||
event: event
|
event: event
|
||||||
kwargs: other arguments
|
kwargs: other arguments
|
||||||
Returns:
|
Returns:
|
||||||
dict: response data
|
dict: response data
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if isinstance(image, str):
|
if isinstance(image, str):
|
||||||
async with aiofiles.open(image, "rb") as f:
|
async with aiofiles.open(image, "rb") as f:
|
||||||
image = await f.read()
|
image = await f.read()
|
||||||
method = 2
|
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:
|
if method == 2:
|
||||||
base64_string = base64.b64encode(image).decode("utf-8")
|
base64_string = base64.b64encode(image).decode("utf-8")
|
||||||
data = await bot.call_api("upload_image", file=f"base64://{base64_string}")
|
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(
|
image_message_id = (await bot.send_private_msg(
|
||||||
user_id=bot.self_id,
|
user_id=bot.self_id,
|
||||||
message=[
|
message=[
|
||||||
v11.MessageSegment.image(file=image)
|
v11.MessageSegment.image(file=image)
|
||||||
]
|
]
|
||||||
))["message_id"]
|
))["message_id"]
|
||||||
image_url = (await bot.get_msg(message_id=image_message_id))["message"][0]["data"]["url"]
|
image_url = (await bot.get_msg(message_id=image_message_id))["message"][0]["data"]["url"]
|
||||||
|
Loading…
Reference in New Issue
Block a user