# OneBot 消息内容的数据结构 消息内容有文本、语音、图片等多种类型,需要特定的数据结构来表示。在 OneBot 标准中主要有两种格式,来表示消息内容的数据结构:字符串(string)和数组(array)。 在 melobot 中,你不需要手动处理消息内容的数据结构,**但是了解消息内容的数据结构,有助于你使用 melobot 提供的相关方法**。 ```{admonition} 注意 :class: caution 本页以下部分为保证阅读流畅性,直接复制了来源于 [OneBot 标准](https://github.com/botuniverse/onebot-11)的一些内容。 ``` ## 字符串格式 在字符串格式中,无论纯文本还是图片、表情、链接分享等多媒体内容都放在同一个字符串里,即,一条消息对应一个字符串。以下是一个字符串格式消息的例子: ``` [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 码功能请参考 [消息段类型](https://github.com/botuniverse/onebot-11/blob/master/message/segment.md)。 ```{admonition} 注意 :class: caution CQ 码中不应有多余的空格,例如不应该使用 `[CQ:face, id=178]`。 CQ 码的参数值可以包含空格、换行、除 `[],&` 之外的特殊符号等。在解析时,应直接取 `[CQ:` 后、第一个 `,` 或 `]` 前的部分为功能名,第一个 `,` 之后到 `]` 之间的部分为参数,按 `,` 分割后,每个部分第一个 `=` 前的内容为参数名,之后的部分为参数值。例如 `[CQ:share,title=标题中有=等号,url=http://baidu.com]` 中,功能名为 `share`,`title` 参数值为 `标题中有=等号`,`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 码在数组格式中的表示形式,基本格式如下: ```json { "type": "image", "data": { "file": "123.jpg" } } ``` 其中 `type` 字段的类型为字符串,对应 CQ 码中的「功能名」;`data` 字段的类型为对象,对应 CQ 码的「参数」,此字段可为 null。**目前,除了合并转发相关的特殊消息段外,几乎所有消息段参数值类型均为字符串,以支持与 CQ 码的相互转换**。 **由于消息段不会将纯文本和多媒体内容放在一起,也就意味着任意一个字段的值都是真实值,而不再需要转义。** 为了使用消息段表示纯文本,引入一个特殊消息段类型 `text`,并在 `data` 中使用 `text` 字段来指示纯文本内容,例如: ```json { "type": "text", "data": { "text": "这是一段纯文本" } } ``` 在将上面的消息段转成 CQ 码时,将会直接变成纯文本字符串,而不是真的转成 CQ 码。 更多消息段类型请参考 [消息段类型](https://github.com/botuniverse/onebot-11/blob/master/message/segment.md)。 ### 消息段数组 了解了消息段概念之后,就不难理解消息的数组格式了,即消息段组成的数组。 例如,字符串格式下的这样一条消息: ``` [第一部分][CQ:image,file=123.jpg]图片之后的部分,表情:[CQ:face,id=123] ``` 表示成数组格式即为: ```json [ { "type": "text", "data": { "text": "[第一部分]" } }, { "type": "image", "data": { "file": "123.jpg" } }, { "type": "text", "data": { "text": "图片之后的部分,表情:" } }, { "type": "face", "data": { "id": "123" } } ] ``` ## melobot 中的表示 在 melobot 中,都是使用消息段来表示消息内容。但是你仍然可以将消息段转换为 cq 字符串,不过不推荐这样做,会存在一定的注入风险。