MessageArray 消息容器
约 746 字大约 2 分钟
2025-9-26
本页介绍消息容器 MessageArray
的核心概念、构造方式、解析/序列化流程、常用 API 与示例,以及合并转发消息的特殊规则与常见问题。
阅读后,你应能将上游事件中的消息解析为段列表,并以编程方式构造要发送的复合消息。
术语与关系
- MessageSegment: 单个消息段的抽象基类,子类包含
Text
、Image
、At
、Face
、Reply
、Node
、Forward
等。 - MessageArray: 消息段列表的容器,支持从字符串(CQ 码)、
dict
、MessageSegment
(或它们的迭代器)构造,支持追加、过滤与序列化。收发消息时,均使用MessageArray
作为消息容器。 - PlainText 与 Text: 均表示
type=text
。过滤时filter(Text)
会同时匹配PlainText
与Text
。 - Node / Forward: 合并转发相关的消息段,具备特殊的格式限制与获取内容方式。
构造方式
1) 从消息段直接构造
from ncatbot.core.event.message_segment import MessageArray, Text, At, Image
# 多参数直接传入(推荐)
msg = MessageArray(Text("你好 "), At("123456"), Image(file="local.png"))
# 或传入单个列表
msg = MessageArray([Text("你好 "), At("123456"), Image(file="local.png")])
# 或使用 from_list(列表可混合 dict 与 MessageSegment)
msg = MessageArray.from_list([
{"type": "text", "data": {"text": "你好 "}},
At("123456"),
])
- Text 会自动解析 CQ 码,PlainText 不会。
- 参考消息段。
2) 从字符串(CQ 码)构造
MessageArray
传入字符串时,会将字符串当作 CQ 码进行解析(支持转义):
from ncatbot.core.event.message_segment import MessageArray
from ncatbot.core.event.message_segment import Text, At, Image
msg = MessageArray("[CQ:image,file=img001.jpg]这是一段文本[CQ:face,id=123]")
msg = MessageArray(Image(file="img001.jpg"), Text("这是一段文本"), Face(123))
# 上下两个 msg 等价
解析规则要点:
- 匹配模式:
[CQ:<type>(,<k=v>...)]
;CQ 前后的普通文本会转成text
段。 - HTML 实体反转义:
&
→&
,[
→[
,]
→]
,,
→,
。
3) 追加构造
msg = MessageArray()
msg.add_text("Hello ") \
.add_at("123456") \
.add_image("img001.jpg") \
.add_reply("987654321")
可用追加方法:
add_by_list(list)
:添加一个由list
描述的消息段(支持混合dict
与MessageSegment
)add_by_segment(MessageSegment)
:添加一个MessageSegment
段add_by_dict(dict)
:添加一个由dict
描述的消息段add_text(str)
:添加一个Text
段add_image(file: str)
:添加一个Image
段add_at(Union[int, str])
:添加一个At
段add_at_all()
:添加一个AtAll
段add_reply(int)
:添加一个Reply
段
4) 操作符拼接
msg = MessageArray(Text("前缀 ")) + [Image(file="a.png"), At("123")] + " 后缀"
支持的追加类型:
MessageSegment
:单个消息段list[MessageSegment | dict]
:消息段列表str
:文本,会被转为Text
段MessageArray
:另一个消息容器
解析与序列化
1) 过滤与查询
from ncatbot.core.event.message_segment import Text, At, Image, Face
# msg: MessageArray
texts: list[Text] = msg.filter(Text) # 同时包含 Text 与 PlainText
ats: list[At] = msg.filter(At)
images: list[Image] = msg.filter(Image)
faces: list[Face] = msg.filter(Face)
# 便捷方法
msg.filter_text()
msg.filter_at()
msg.filter_image()
msg.filter_video()
msg.filter_face()
# 是否 @ 了某人(或 @全体)
mentioned = msg.is_user_at("123456")
only_direct = msg.is_user_at("123456", all_except=True)
2) 逐个解析
MessageArray
实现了迭代器协议,可逐个访问其中的消息段:
for segment in msg: # segment: MessageSegment; msg: MessageArray
if isinstance(segment, Text):
print("文本:", segment.text)
elif isinstance(segment, At):
print("提及:", segment.qq)
elif isinstance(segment, Image):
print("图片:", segment.file)
...
版权所有
版权归属:huan-yp