Appservice #

Appservice(Application Service 的简称)是 Matrix 内建的扩展机制。一个 Appservice 是一个被主机服务器 信任 的外部程序,它可以:

  • 在它拥有的命名空间下创建并操作虚拟用户(例如 @slack_*:your-server)
  • 在它拥有的命名空间下创建并操作虚拟房间(例如 #_discord_*:your-server)
  • 接收主机服务器里所有命中它命名空间的事件的推送流

你在 桥接 一节里看到的每一个桥接,底层都是 Appservice。但你也可以自己写一个——用于自定义机器人、集成、数据分析、后台工具,或者对接 Hagency 默认没有出厂的网络。

本页讲清概念,说明什么时候要用 Appservice 而不是普通机器人,并演示如何在 Hagency 工作区里注册一个 Appservice。

Appservice 与机器人的区别 #

普通机器人Appservice
身份一个 Matrix 用户账户一整段命名空间下的虚拟用户(例如 @myint_*)
认证Access token,与普通用户相同两个共享密钥 token:as_token、hs_token
收事件只能收到机器人用户能看见的事件所有命中 AS 命名空间的事件,通过 HTTP 推送
创建用户否——机器人是单一身份是——按需创建,无需走注册流程
创建房间可以,和普通用户一样可以,还能创建"只通过别名访问"的命名空间房间
典型用途!weather 机器人、提醒机器人、GitHub 通知桥接、批量集成、机器人农场、后台仪表板

经验法则: 如果你的集成只需要一个身份、只对"@它的消息"做出反应,用普通机器人即可。如果需要多个身份(每个外部用户一个)、或者需要看到房间里的 全部 消息却又不在房间里,就得用 Appservice。

registration.yaml 文件 #

Appservice 通过一份 注册文件 向主机服务器登记——一份简短的 YAML,声明:

  • 一个 ID(唯一的字符串)
  • 一个 URL,主机服务器把事件推到这里
  • 两个随机长 token:as_token(Appservice → 主机服务器)和 hs_token(主机服务器 → Appservice)
  • 一个 sender localpart(这个 AS 的"默认"用户)
  • 一组命名空间模式:用户、别名、房间

示例 #

yaml
id: hagency-weatherbot
url: https://weather.example.com/_matrix
as_token: as_7f3a... # 你自己生成的随机长字符串
hs_token: hs_b1c9... # 另一个随机长字符串
sender_localpart: weatherbot
rate_limited: false
namespaces:
  users:
    - exclusive: true
      regex: '@weather_.*:your-name\.hagency\.com'
  aliases:
    - exclusive: true
      regex: '#weather_.*:your-name\.hagency\.com'
  rooms: []

独占命名空间(exclusive) 意味着同一主机服务器上不会再有其他人注册符合该正则的用户或别名。请让正则尽可能精准——不要写 @.*:your-server,否则会屏蔽普通用户注册。

在 Hagency 上注册 Appservice #

第 1 步——生成 token #

任意随机密钥生成器都可以。常见方式:

bash
openssl rand -hex 32   # 跑两次,一次给 as_token,一次给 hs_token

两个 token 都保存好。这两个 token 不会被自动轮转,一旦丢失就必须重新注册。

第 2 步——写 registration.yaml #

以上面的例子为模板,修改成你集成需要的样子。id 取一个可读的名字;url 必须是可达的 HTTPS endpoint,Hagency 主机服务器会把事件 POST 到这里。

第 3 步——上传到 Hagency #

在 Hagency 仪表板里:

  1. 服务器 → Appservice。
  2. 点 导入 registration.yaml(或选 Custom Appservice 模板),然后粘贴完整的 YAML / 上传文件。下方的结构化字段会自动填好——请核对一遍。
  3. 点 安装。

如果某条注册的独占(exclusive)命名空间正则与另一个已有 appservice 完全相同,Hagency 会拒绝它。注册会存进主机服务器数据库并立即生效——无需重启。

你可以点开任意已安装的 appservice(点击该行展开)来复制它的 token、下载它的 registration.yaml,或就地 编辑——编辑会保留启用/禁用状态,并保持同一个 ID。

第 4 步——启动你的 Appservice #

你的外部程序需要做这些事:

  1. 在你声明的 URL 暴露一个 HTTP 服务。 Matrix 会往那里 PUT 成批的事件。这个 endpoint 必须能从 Hagency 集群访问到(公网 HTTPS,或用隧道服务)。
  2. 验证入站请求。 主机服务器的每一次 PUT 都会在 query string 里带 ?access_token=<hs_token>,token 不对的请求必须拒绝。
  3. 反向调用主机服务器的 Matrix client-server API,请求头里放 Authorization: Bearer <as_token>。用这个 token 可以创建命名空间下的任意用户(POST /_matrix/client/v3/register?kind=user,body 里 type: m.login.application_service),以这些用户的身份发消息、建房间等等。

最常用的参考 SDK:Node.js 用 matrix-appservice-bridge,Python 用 matrix-nio。Rust 也有一个 crate:matrix-sdk-appservice。

注销 Appservice #

不再需要时:

  1. 仪表板 服务器 → Appservice。
  2. 按 ID 找到那条记录,点 删除。
  3. Hagency 会把它从主机服务器数据库里移除,其 token 立即失效。(若只想临时停用而不丢配置,改用 禁用。)

Appservice 创建过的虚拟用户会留在数据库里(在房间历史里还能看到),但 Appservice 再也无法推送事件或以它们的身份行动。

套餐限制 #

  • Free——不支持自定义 Appservice。
  • Starter / Pro / Enterprise——支持注册自定义 Appservice。

Appservice 当前以"启用 / 不启用"为粒度区分套餐,并不存在按个数计费的硬性配额。Hagency 管理的桥接(Telegram、Slack、Discord 等)独立计入桥接配额,与你自己注册的 Appservice 不冲突。

安全提示 #

  • Appservice 是 可信代码,可以在它的命名空间里冒充任意用户,如果命名空间写得太宽,甚至可能冒充管理员。把 token 当 root 密钥对待。
  • 永远不要把 registration.yaml 提交到公开的 git——它里面有两把 token。
  • 怀疑 token 泄漏时,注销 Appservice 并用新 token 重新注册。
  • rate_limited: false 会为来自该 AS 的流量关闭速率限制。只对真正高吞吐量的集成这样写,其他情况保持默认 true(或者干脆不写)。

调试 #

  • 事件没到你的 endpoint: 在 Hagency 仪表板 服务器 → 日志 → Appservice 查看 HTTP 错误响应。常见原因:URL 错了、TLS 过期、hs_token 不对。
  • 无法创建用户: 检查命名空间正则是否加了 exclusive: true——没有这个字段,主机服务器不会允许 AS 创建该模式下的用户。
  • "命名空间冲突": 已有另一个 Appservice(大概率是出厂的桥接之一)声明了重叠的用户或别名。把正则写得更精准一些。

下一步 #

  • 桥接——Hagency 出厂的 Appservice
  • 安全 → API 密钥——如果你的集成只是一个机器人,不需要 Appservice
  • Matrix 协议——如果你对用户、房间、命名空间还不够清楚