Merge branch 'dev' into plugins

This commit is contained in:
镀铬酸钾
2026-01-02 17:45:39 +08:00
committed by GitHub
27 changed files with 1048 additions and 338 deletions

View File

@@ -1,49 +1,57 @@
"""
消息段模型模块
定义了 MessageSegment 类,用于封装 OneBot 11 的消息段。
该模块定义了 `MessageSegment` 类,用于构建和表示 OneBot v11 协议中的消息段。
通过此类可以方便地创建文本、图片、At 等不同类型的消息内容,并支持链式操作。
"""
from dataclasses import dataclass
from typing import Any, Dict
@dataclass
@dataclass(slots=True)
class MessageSegment:
"""
消息段,对应 OneBot 11 标准中的消息段对象
表示一个 OneBot v11 消息段
Attributes:
type (str): 消息段的类型,例如 'text', 'image', 'at'
data (Dict[str, Any]): 消息段的具体数据,是一个键值对字典。
"""
type: str
"""消息段类型,如 text, image, at 等"""
data: Dict[str, Any]
"""消息段数据"""
@property
def text(self) -> str:
"""
获取文本内容(仅当 type 为 text 时有效)
当消息段类型为 'text' 时,快速获取其文本内容。
:return: 文本内容
Returns:
str: 消息段的文本内容。如果类型不是 'text',则返回空字符串。
"""
return self.data.get("text", "") if self.type == "text" else ""
@property
def image_url(self) -> str:
"""
获取图片 URL仅当 type 为 image 时有效)
当消息段类型为 'image' 时,快速获取其图片 URL。
:return: 图片 URL
Returns:
str: 图片的 URL。如果类型不是 'image' 或数据中不含 'url',则返回空字符串。
"""
return self.data.get("url", "") if self.type == "image" else ""
def is_at(self, user_id: int = None) -> bool:
"""
判断是否为 @某人
检查当前消息段是否是一个 'at' (提及) 消息段。
:param user_id: 指定的 QQ 号,如果为 None 则只判断是否为 at 类型
:return: 是否匹配
Args:
user_id (int, optional): 如果提供,则进一步检查被提及的 QQ 号是否匹配
Defaults to None.
Returns:
bool: 如果消息段是 'at' 类型且 user_id 匹配 (如果提供),则返回 True。
"""
if self.type != "at":
return False
@@ -52,6 +60,9 @@ class MessageSegment:
return str(self.data.get("qq")) == str(user_id)
def __repr__(self):
"""
返回消息段对象的字符串表示形式,便于调试。
"""
return f"[MS:{self.type}:{self.data}]"
# --- 快捷构造方法 ---
@@ -59,39 +70,52 @@ class MessageSegment:
@staticmethod
def text(text: str) -> "MessageSegment": # noqa: F811
"""
构造文本消息段
创建一个文本消息段
:param text: 文本内容
:return: MessageSegment 对象
Args:
text (str): 文本内容。
Returns:
MessageSegment: 一个类型为 'text' 的消息段对象。
"""
return MessageSegment(type="text", data={"text": text})
@staticmethod
def at(user_id: int | str) -> "MessageSegment":
"""
构造 @某人 消息段
创建一个 @某人 消息段
:param user_id: 目标 QQ 号,"all" 表示 @全体成员
:return: MessageSegment 对象
Args:
user_id (int | str): 要提及的 QQ 号。若为 "all",则表示 @全体成员。
Returns:
MessageSegment: 一个类型为 'at' 的消息段对象。
"""
return MessageSegment(type="at", data={"qq": str(user_id)})
@staticmethod
def image(file: str) -> "MessageSegment":
"""
构造图片消息段
创建一个图片消息段
:param file: 图片文件名、URL 或 Base64
:return: MessageSegment 对象
Args:
file (str): 图片的路径、URL 或 Base64 编码的字符串。
Returns:
MessageSegment: 一个类型为 'image' 的消息段对象。
"""
return MessageSegment(type="image", data={"file": file})
@staticmethod
def face(id: int) -> "MessageSegment":
"""
构造表情消息段
创建一个 QQ 表情消息段
:param id: 表情 ID
:return: MessageSegment 对象
Args:
id (int): QQ 表情的 ID。
Returns:
MessageSegment: 一个类型为 'face' 的消息段对象。
"""
return MessageSegment(type="face", data={"id": str(id)})