--- title: 为什么不是 OneBot? --- 样的问题——「Chronocat 推荐使用 Satori。为什么不是 OneBot?」 实际上,这个问题可以拆分成两个问题: 1. **为什么 Chronocat 只提供了 Satori,没有提供 OneBot?** 1. **为什么 Chronocat 推荐使用 Satori,而不是 OneBot?** 第一个问题很好解答:我和我认识的人主要使用 Satori。我个人的 Bot 从很久以前开始就基于 Satori。 所以,Chronocat 不支持 OneBot 只是因为目前我没有使用 OneBot 的需求,也就没有提供 OneBot 的实现。未来如果我有用到 OneBot 的地方,那么也会提供 OneBot 实现的。 但是为什么 Chronocat 推荐使用 Satori 而非 OneBot 呢?让我们先从几个经常遇到的场景开始说起。 --- 111111111111111111111111111111111111111111111111 # 为什么 Satori 数据包中消息使用 string? 如果你还不了解 Satori 或 Satori 消息元素,那么请前往 [Satori 官网] 列举一下各协议传递消息内容的方式,在 Satori 出现以前应当只有这两种: - 使用 String 传递,并定义一种特殊元素 - 使用 JSON 传递 ## 为什么使用 XML 而不是 JSON? ```cs var 消息; // 遍历消息 foreach (var 消息段 in 消息) { // 要判断的是文字消息 if (消息段.类型 == "text") { // 判断内容有无「我超」 if (消息段.内容.包含("我超")) { 发送("原!"); } } } ``` ```cs if (消息.包含("我超")) 发送("原!") ``` 不过,具体到这个问题的话,`alt_message` 呢?一些协议的 ## 既然使用 String,那么表达消息的能力会不会遇到问题? ```html 你好! 我是 Chronocat 。 ``` 这是一段 HTML 文本。把它保存成 `.html` 格式的文件后用浏览器打开,你会发现上面的粗体(b)和斜体(i)都正确得到了渲染(是的,你不需要添加 `` 和 `` 等标签)。很显然,HTML 是 String,并且它的表达能力没有任何问题,因为我们每天都会使用的各个网站全都使用 Web 技术构建。 那么,为什么在机器人开发中,我们就会开始担心 String 的表达能力问题呢?确切地来说,为什么我们会开始担心 **String 相较 JSON 的表达能力问题呢**? 显然,是 OneBot 的 String 形式消息的表达能力出现了问题。这一问题实际上是由 CQ 码带来的。CQ 码只有一个最核心的问题: **CQ 码不支持嵌套。** 不支持嵌套是 CQ 码表达能力出现缺失的根本原因,CQ 码无力表达类似合并转发(``)这样的数据结构。使用 OneBot 的情况下,需要发送合并转发消息时,用户只能使用 JSON 来发送消息,这就使大多数用户都认为「使用 String 的话,表达消息的能力会出现问题」。但这其实是由 CQ 码导致的。 然而,并不是所有时候都可以临时使用 JSON 来解决需要嵌套的问题。OneBot 的 API 支持以两种格式发送消息,而事件推送则同样支持以两种格式推送消息事件。这却给 OneBot 实现侧的开发造成了很大的困难:如果用户配置「希望使用 String 格式接收消息」(在 OneBot 早期,为了方便 Bot 开发,大多数 Bot 开发者都使用 String 格式,go-cqhttp 也将 String 作为默认值),那么 OneBot 实现就必须找到一种方法,将 JSON 之类的复杂数据结构装入 CQ 码里。 **解析 CQ 码时会遇到严重的转义问题。** 当然,也有很多其他的方法绕过这个问题,比如在 CQ 码内只放一个消息 ID,然后另起一个 API 端点用于获取该消息的具体信息;然而这样的做法却会同时增加 Bot 侧和实现侧开发者的工作量,并增加实现和实现之间的分裂。