解析消息
约 1696 字大约 6 分钟
2025-04-05
消息类
此类型包括群聊消息和私聊消息.
群聊消息类为 GroupMessage
类, 私聊消息类为 PrivateMessage
类, 它们均为 BaseMessage
的派生类. 下面只介绍 BaseMessage
类.
我们称 BaseMessage
实例为消息.
三个类的具体代码位置为 ncatbot.core.message
.
查看简介.
主要成员
msg.user_id: Union(str, int)
: 消息发送者 QQ 号.msg.group_id: Union(str, int)
: 消息来源群群号(如果是群聊消息).msg.message_id: Union(str, int)
: 消息 ID.msg.message_type: str
: 消息类型(group
/private
), 群聊或私聊.msg.raw_message: str
: 符合 OneBot11 标准的消息字符串, 需手动解析, 不建议使用.msg.sender: Sender
: 消息发送者实例,详细信息将在下面给出。msg.message: List[dict]
: 符合 OneBot11 标准的数组格式消息, 推荐使用它来进行逻辑判断, 详细解析方式将在下面给出。msg.self_id: Union(str, int)
: 机器人 QQ 号.msg.time: int
: 事件发生时间戳.
其它成员
msg.sub_type: str
: 消息子类型(friend
,group
,other
).msg.sub_type: str
: 消息子类型(friend
,group
,other
).msg.message_format: str
: 消息格式(string
/json
/markdown
), 作用不明msg.raw_message: str
: 符合 OneBot11 标准的消息字符串, 需手动解析, 不建议使用.
内置方法
BaseMessage.reply
用于快捷调用 API 回复消息。
该接口有同步版本,reply_sync
。
sender 成员
BaseMessage
类的 sender
成员为 Sender
类, Sender
类包含以下成员:
msg.sender.user_id = "123456" # 消息发送者 QQ 号.
msg.sender.nickname = "昵称" # 消息发送者 QQ 昵称.
msg.sender.card = "群昵称" # 消息发送者群卡片昵称(如果是群聊消息).
message 成员
注意
接下来的叙述中包含多重定语和嵌套递归定义, 容易引起混淆. 请注意区分消息段、消息、消息段列表、消息列表的定义。区分格式和类型的区别。
BaseMessage.message
是一个字典的列表(list[dict]
), 我们称它为消息段列表, 称 dict
为消息段.
消息段列表有不同种类, 具体如下:
组合类型消息段列表
组合类型消息段列表可以包含除了 forward
类型消息段之外的其它任意多个任意消息段的有序组合。
组合类型消息段列表包含以下几种类型消息段的组合.
text 类型消息段
msg.message = [
{
'type': 'text',
'data': {
'text': '123456'
}
}
]
at 类型消息段
msg.message = [
{
'type': 'at',
'data': {
'qq': 12345678
}
}
]
当 qq
字段为 all
时, 表示@全体成员.
reply 类型消息段
msg.message = [
{
'type': 'reply',
'data': {
'id': '671936880', # 表示所回复的消息的 id
}
}
]
当包含 reply
类型消息段时, reply
消息段一定位于消息段列表的第一个位置.
face 类型消息段
msg.message = [
{
'type': 'face',
'data': {
'id': 277 # 表示表情的 id
'raw': {
'faceIndex': 277, # 表情 id
'faceText': '[汪汪]', # 表情描述文本
'faceType': 2 # 表情类型, 其实我也不知道什么意思
}
}
}
]
image 类型消息段
msg.message = [{
'type': 'image',
'data': {
'file': '17F7844DD051F03B0CF2198CAAD887A0.jpg', # 文件名, 很重要, 传给 get_image 可以拿到本地已经下载的图片的路径
'url': 'http://example.com/fndsnajfasndkgjnasjk.jpg', # 这是假链接没啥用
'summary': '[图片]'
}
}]
使用 get_image 传入 file
字段可以获取真实的图片路径或者下载链接。
get_image
返回一个 dict
,结构如下:
{
"status": "ok",
"data": {
"file": "a path on device of napcat NOT ncatbot",
"url": "use this for download"
}
}
video 类型消息段
msg.message = [{
'type': 'video',
'data': {
'file': '17F7844DD051F03B0CF2198CAAD887A0.mp4' # 文件名, 几乎没用
'url': 'http://example.com/fndsnajfasndkgjnasjk' # 视频间接下载链接, 无法直接下载, 也无法直接使用
'summary': '[视频]'
}
}]
视频目前只能通过 url
下载源文件后**手动修改后缀名为 .mp4
**后查看, 未来将实现自动修改和识别.
file 类型消息段
msg.message = [
{
'type': 'file',
'data': {
'file': '0d7520ca-4b60-4fcd-a87b-581f69da3540.mp4', # 文件名, 几乎没用
'file_id': '9423e3b5f95b09df4de35ea1c783c368_feec4190-1243-11f0-bf38-8307ae91f46d', # 文件 id, 很有用
'file_size': '1177324' # 文件大小, 几乎没用
}
}
]
通过 file_id
可以获取更加细节的文件信息, 接口为 get_file。
合并转发消息段列表
合并转发消息段列表表表示一个合并转发消息,或者说是消息卡片。
合并转发消息段列表一定只包含一个消息段,这个消息段称为 forward 类型消息段,具有两种格式。
消息 ID 格式
msg.message = [{'type': 'forward', 'data': {'id': '7489856252632721587'}}]
这个很长的 id
字段没用, 如果要获取转发消息的内容, 必须使用 message 成员的 message_id
字段和 get_msg 方法(此方法请在该链接中搜索) 可以获取到消息的详细信息, 获取的数据如下:
result = {
# 其它字段略去, 只关注 'message' 字段, 由于该类型是 `forward` 类型, 所以消息段列表 `message` 只有它一个成员.
'message': [
{
'type': 'forward',
'data': {
'id': '7489858069394438109',
'content': [
# 格式参考下面
]
}
}
]
}
提取 result["message"]
得到的结果被定义为 content 格式的 forward 类型消息段.
content 格式
格式如下:
msg.message = [
{
'type': 'forward',
'data': {
'id': '7489858069394438109',
'content': [
{
'self_id': 123456,
'user_id': 12345678,
'time': 1743869088,
'message_id': 671936880,
'message_seq': 671936880,
'real_id': 671936880,
'real_seq': '0',
'message_type': 'private',
'sender': {'user_id': 12345678, 'nickname': '幻影彭', 'card': ''}, 'raw_message': '123456',
'font': 14,
'sub_type': 'friend',
'message': [{'type': 'text', 'data': {'text': '123456'}}],
'message_format': 'array',
'post_type': 'message'
}, {
'message': [{'type': 'text', 'data': {'text': '666666'}}]
}, {
'message': [{'type': 'text', 'data': {'text': '测试'}}],
}
]
}
}
]
一个 content 格式 forward 类型消息段 主要包含一份 data['content']
(msg.message[0]['data']['content']
),它是一个 list[dict]
, dict
表示一个消息(不是消息段), 这个 dict
的结构和 BaseMessage.__dict__
基本一致, data['content']
被称为消息列表.
消息列表->消息->消息段列表->消息段
而 data['content']
里包含的第四级消息段又可以是 content 格式的 forward 类型的消息段, 所以说, 这里的定义是递归的.
上面的示例省略了消息列表中后两条消息的其它数据, 只保留了 message
字段. 可以对比一下一条消息的 key 以及 BaseMessage
的 成员列表.
注意, 这里的消息段所带的 data['content']
里面也可以包含带有 forward 类型的消息段的消息, 这和 forward 作为消息段列表中的唯一元素不矛盾, 因为 data['content']
本质是消息列表, 而不是消息段列表. 但是一条消息所带的消息段列表中, 如果出现了 forward
类型的消息段, 那么该消息段就是唯一的消息段.
参考资料
版权所有
版权归属:huan-yp