消息内容的数据结构

消息内容,由于有文本、语音、图片等多种类型,因此需要特定的数据结构来表示。在 OneBot 标准中,主要有两种格式,来表示消息内容的数据结构:字符串(string)和数组(array)。

在 melobot 中,你不需要手动处理消息内容的数据结构,但是了解消息内容的数据结构,有助于你使用 melobot 提供的相关方法

注意

本页以下部分为保证阅读流畅性,直接复制了来源于 OneBot 标准的一些内容。

字符串格式

在字符串格式中,无论纯文本还是图片、表情、链接分享等多媒体内容都放在同一个字符串里,即,一条消息对应一个字符串。以下是一个字符串格式消息的例子:

[CQ:face,id=178]看看我刚拍的照片[CQ:image,file=123.jpg]

CQ 码格式

消息中的多媒体内容使用 CQ 码来表示,形如 [CQ:face,id=178]。其中,[CQ:] 是固定格式;face 是「功能名」,除了 face 还有许多不同的功能名;id=178 是「参数」,某些功能不需要参数,而另一些需要多个参数,当有多个参数时,参数间使用逗号分隔。

一些 CQ 码的例子如下:

[CQ:shake]
[CQ:face,id=178]
[CQ:share,title=标题,url=http://baidu.com]

更多 CQ 码功能请参考 消息段类型

注意

CQ 码中不应有多余的空格,例如不应该使用 [CQ:face, id=178]

CQ 码的参数值可以包含空格、换行、除 [],& 之外的特殊符号等。在解析时,应直接取 [CQ: 后、第一个 ,] 前的部分为功能名,第一个 , 之后到 ] 之间的部分为参数,按 , 分割后,每个部分第一个 = 前的内容为参数名,之后的部分为参数值。例如 [CQ:share,title=标题中有=等号,url=http://baidu.com] 中,功能名为 sharetitle 参数值为 标题中有=等号url 参数值为 http://baidu.com

CQ 码转义

CQ 码中包含一些特殊字符:[], 等,而 CQ 码又是可能混杂在纯文本内容之中的,因此消息中的纯文本内容需要对特殊字符进行转义,以避免歧义。具体的转义规则如下:

转义前

转义后

&

&

[

[

]

]

例如,一个纯文本消息转义前内容如下:

- [x] 使用 `&data` 获取地址

转义后如下:

- [x] 使用 `&data` 获取地址

另一方面,CQ 码内部的参数值也可能出现特殊字符,也是需要转义的。由于 ,(半角逗号)在 CQ 码中用于分隔参数,因此除了上面的转义规则,还需要对 , 进行转义,如下:

转义前

转义后

&

&

[

[

]

]

,

,

例如,一个链接分享消息的 CQ 码可能如下:

[CQ:share,title=震惊,小伙睡觉前居然...,url=http://baidu.com/?a=1&b=2]

数组格式

数组格式将消息表示为一系列消息段对象的数组,在基本语义上与字符串格式等价,可以相互转换,但数组格式的表达能力更强,例如可以嵌套、规定参数数据类型等。

消息段

在字符串格式中,使用 CQ 码表示多媒体内容,例如 [CQ:image,file=123.jpg],这里 CQ 码功能名为 image,参数为 file=123.jpg,也即一个键值对。

消息段是 CQ 码在数组格式中的表示形式,基本格式如下:

{
    "type": "image",
    "data": {
        "file": "123.jpg"
    }
}

其中 type 字段的类型为字符串,对应 CQ 码中的「功能名」;data 字段的类型为对象,对应 CQ 码的「参数」,此字段可为 null。目前,除了合并转发相关的特殊消息段外,几乎所有消息段参数值类型均为字符串,以支持与 CQ 码的相互转换

由于消息段不会将纯文本和多媒体内容放在一起,也就意味着任意一个字段的值都是真实值,而不再需要转义。

为了使用消息段表示纯文本,引入一个特殊消息段类型 text,并在 data 中使用 text 字段来指示纯文本内容,例如:

{
    "type": "text",
    "data": {
        "text": "这是一段纯文本"
    }
}

在将上面的消息段转成 CQ 码时,将会直接变成纯文本字符串,而不是真的转成 CQ 码。

更多消息段类型请参考 消息段类型

消息段数组

了解了消息段概念之后,就不难理解消息的数组格式了,即消息段组成的数组。

例如,字符串格式下的这样一条消息:

[第一部分][CQ:image,file=123.jpg]图片之后的部分,表情:[CQ:face,id=123]

表示成数组格式即为:

[
    {
        "type": "text",
        "data": {
            "text": "[第一部分]"
        }
    },
    {
        "type": "image",
        "data": {
            "file": "123.jpg"
        }
    },
    {
        "type": "text",
        "data": {
            "text": "图片之后的部分,表情:"
        }
    },
    {
        "type": "face",
        "data": {
            "id": "123"
        }
    }
]

melobot 中的表示

在 melobot 中:

  • CQ 字符串使用字符串类型 str 表示

  • 消息段对象,使用类型注解为 MsgSegment 的字典表示