Files
NeoBot/models/message.py

121 lines
3.5 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
消息段模型模块
该模块定义了 `MessageSegment` 类,用于构建和表示 OneBot v11 协议中的消息段。
通过此类可以方便地创建文本、图片、At 等不同类型的消息内容,并支持链式操作。
"""
from dataclasses import dataclass
from typing import Any, Dict
@dataclass(slots=True)
class MessageSegment:
"""
表示一个 OneBot v11 消息段。
Attributes:
type (str): 消息段的类型,例如 'text', 'image', 'at'
data (Dict[str, Any]): 消息段的具体数据,是一个键值对字典。
"""
type: str
data: Dict[str, Any]
@property
def text(self) -> str:
"""
当消息段类型为 'text' 时,快速获取其文本内容。
Returns:
str: 消息段的文本内容。如果类型不是 'text',则返回空字符串。
"""
return self.data.get("text", "") if self.type == "text" else ""
@property
def image_url(self) -> str:
"""
当消息段类型为 'image' 时,快速获取其图片 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' (提及) 消息段。
Args:
user_id (int, optional): 如果提供,则进一步检查被提及的 QQ 号是否匹配。
Defaults to None.
Returns:
bool: 如果消息段是 'at' 类型且 user_id 匹配 (如果提供),则返回 True。
"""
if self.type != "at":
return False
if user_id is None:
return True
return str(self.data.get("qq")) == str(user_id)
def __repr__(self):
"""
返回消息段对象的字符串表示形式,便于调试。
"""
return f"[MS:{self.type}:{self.data}]"
# --- 快捷构造方法 ---
@staticmethod
def text(text: str) -> "MessageSegment":
"""
创建一个文本消息段。
Args:
text (str): 文本内容。
Returns:
MessageSegment: 一个类型为 'text' 的消息段对象。
"""
return MessageSegment(type="text", data={"text": text})
@staticmethod
def at(user_id: int | str) -> "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":
"""
创建一个图片消息段。
Args:
file (str): 图片的路径、URL 或 Base64 编码的字符串。
Returns:
MessageSegment: 一个类型为 'image' 的消息段对象。
"""
return MessageSegment(type="image", data={"file": file})
@staticmethod
def face(id: int) -> "MessageSegment":
"""
创建一个 QQ 表情消息段。
Args:
id (int): QQ 表情的 ID。
Returns:
MessageSegment: 一个类型为 'face' 的消息段对象。
"""
return MessageSegment(type="face", data={"id": str(id)})