Skip to content

消息编码

Satori 中的消息使用消息元素 (Message Element) 进行编码。消息元素的语法与 XHTML 类似。

语法

消息元素的语法与 HTML 类似,但是不完全相同。

字符

你可以在消息元素内使用任何字符。不过部分特殊字符需要转义:

原始字符转义写法
""
&&
<&lt;
>&gt;

根据上下文的不同,有些字符可能不需要被转义或使用其他的转义方式。

除此以外,你可以使用十进制或十六进制转义任何字符。例如 ' 也可以被书写成 &#39;&#x27;

标签

使用一对尖括号包裹元素名,加上可选的属性、闭合指示符,就构成了一个标签。

元素名由小写字母、数字和连字符组成,且必须以字母开头。在元素名前后添加 / 表示这是一个结束标签或自闭合标签,没有 / 符号时则表示这是一个起始标签:

  • <tag> 一个起始标签
  • </tag> 一个结束标签
  • <tag/> 一个自闭合标签

属性

起始或自闭合标签的元素名后接受可选的属性列表。每个属性必须形如以下形式:

  • key
  • key="value" (此时 value 中的 " 需要被转义)
  • key='value' (此时 value 中的 ' 需要被转义)

下面是一段示例:

html
<tag foo="1" bar/>

元素

一个元素要么是自闭合标签,要么由一对同名的起始标签和结束标签构成。元素的内容指起始标签和结束标签中间的部分,可以包含文本内容或其他元素。对于自闭合标签,元素的内容为空。下面是一段示例:

html
<parent>
  text content
  <child/>
</parent>

当存在未配对的元素时,将自动视为文本内容的一部分。文本内容前后如果存在包含换行符的连续空白字符,则会被忽略。这意味着下面两段代码是等价的:

html
<tag>
  <foo> bar
  <!-- comment -->
</tag>
html
<tag>&lt;foo&gt; bar</tag>

注释

使用成对的 <!----> 插入一段注释。注释中的部分不会被渲染。

资源反向代理

一些平台会使用 ID 标识资源文件 (例如 Lark)。当你接收到来自平台的消息时,拿到的是资源 ID 而非资源链接。此时你需要将资源 ID 转换为资源链接,才能构造合法的资源元素。

TIP

Telegram 是另一种特殊情况。尽管其提供的资源链接是可用的,但这个链接中会明文包含机器人令牌,并非可以公开使用的链接。因此 Telegram 和其他类似平台也适用于这一节的内容。

TIP

一种不推荐的做法是直接下载资源,并转存为 data: 链接放入消息中。之所以不推荐,是因为这种做法有两大致命缺点:

  1. 这些图片本来可以按需加载,但现在却被强制下载到本地,造成额外的带宽消耗。
  2. 编码为 data: 会导致消息体积大幅增加,极大影响消息处理的性能。

对于这种情况,我们建议使用实现资源反向代理。SDK 额外提供一个用于访问资源的路由 (类似 /v1/assets/xxx),将资源 ID 映射到资源链接,并编码到消息元素中。这样一来,上面提到的两个问题也就都解决了。

标准元素

关于 Satori 内置的消息元素,请参考 标准元素