跳转至

Synology Chat

Synology Chat 通过一对 webhook 与 OpenClaw 连接:Synology Chat 的出站(outgoing)webhook 将入站直接消息发布到 Gateway,回复则通过 Synology Chat 的入站(incoming)webhook 返回。

状态:官方插件,单独安装。仅支持直接消息;支持文本和托管文件发送。

安装

openclaw plugins install @openclaw/synology-chat

本地检出(从 git 仓库运行时):

openclaw plugins install ./path/to/local/synology-chat-plugin

详情:插件

快速设置

  1. 安装插件(见上文)。
  2. 在 Synology Chat 集成中:
  3. 创建入站 webhook 并复制其 URL。
  4. 使用你的密钥令牌创建出站 webhook。
  5. 将出站 webhook URL 指向你的 OpenClaw Gateway:
  6. 默认为 https://gateway-host/webhook/synology。
  7. 或使用你自己的自定义 channels.synology-chat.webhookPath。
  8. 将该确切的外部可访问 HTTPS URL 记录为 channels.synology-chat.webhookUrl,以便 NAS 可以取回托管的附件。
  9. 在 OpenClaw 中完成设置。Synology Chat 会出现在两种流程的同一频道设置列表中:
  10. 引导式:openclaw onboard 或 openclaw channels add
  11. 直接式:openclaw channels add --channel synology-chat --token <token> --url <incoming-webhook-url> --webhook-url <public-outgoing-webhook-url>
  12. 检查 openclaw channels status --probe,然后向 Synology Chat 机器人发送一条直接消息。如果 Gateway 离线,请启动它;配置更改遵循热重载。

Webhook 认证详情:

  • OpenClaw 依次接受来自 body.token、?token=... 以及请求头的出站 webhook 令牌。
  • 支持的请求头格式:
  • x-synology-token
  • x-webhook-token
  • x-openclaw-token
  • Authorization: Bearer <token>
  • 空或缺失的令牌将默认拒绝(fail closed)。
  • 负载可以是 application/x-www-form-urlencoded 或 application/json;token、user_id 和 text 为必填项。

入站持久性

在令牌、发送者策略和速率限制检查通过后,OpenClaw 会从存储的信封中移除 webhook 令牌,并在确认事件之前将其持久化排队。只有在该追加操作成功后,路由才会返回 204;持久化失败则返回 503,以便 Synology Chat 可以重试,而不是静默丢失消息。持久化的 204 会携带 x-openclaw-delivery-accepted: durable 标记;认证、验证和存储错误响应则不包含该标记,因此反向代理可以要求该标记,以区分持久化接受与普通响应。

待处理或可重试的事件在 Gateway 重启后仍然存在。只要存在相应的活动或保留的完成记录,Synology 稳定的 post_id 就能抑制重复的队列条目。从队列到 agent 的交接过程中,投递保持至少一次(at least once)语义,因此在该边界发生崩溃时仍可能重放一轮对话。

最小配置:

{
  channels: {
    "synology-chat": {
      enabled: true,
      token: "synology-outgoing-token",
      incomingUrl: "https://nas.example.com/webapi/entry.cgi?api=SYNO.Chat.External&method=incoming&version=2&token=...",
      webhookUrl: "https://gateway.example.com/webhook/synology",
      webhookPath: "/webhook/synology",
      dmPolicy: "allowlist",
      allowedUserIds: ["123456"],
      rateLimitPerMinute: 30,
      allowInsecureSsl: false,
    },
  },
}

环境变量

对于默认账户,你可以使用环境变量:

  • SYNOLOGY_CHAT_TOKEN
  • SYNOLOGY_CHAT_INCOMING_URL
  • SYNOLOGY_NAS_HOST
  • SYNOLOGY_ALLOWED_USER_IDS(逗号分隔)
  • SYNOLOGY_RATE_LIMIT
  • OPENCLAW_BOT_NAME

配置值会覆盖环境变量。

SYNOLOGY_CHAT_INCOMING_URL 和 SYNOLOGY_NAS_HOST 不能从工作区的 .env 文件中设置;请参阅工作区 .env 文件。

直接消息策略与访问控制

  • 支持的 dmPolicy 值:allowlist(默认)、open 和 disabled。Synology Chat 没有配对流程;通过将发送者的数字 Synology 用户 ID 添加到 allowedUserIds 来批准发送者。
  • allowedUserIds 接受 Synology 用户 ID 的列表(或逗号分隔的字符串)。
  • 在 allowlist 模式下,空的 allowedUserIds 列表被视为配置错误,webhook 路由将不会启动。
  • dmPolicy: "open" 仅当 allowedUserIds 包含 "*" 时才允许公开直接消息;如果包含限制性条目,则只有匹配的用户可以聊天。open 配合空的 allowedUserIds 列表也会拒绝启动该路由。
  • dmPolicy: "disabled" 阻止直接消息。
  • 默认情况下,回复接收者绑定保持在稳定的数字 user_id 上。channels.synology-chat.dangerouslyAllowNameMatching: true 是一种破窗(break-glass)兼容模式,会重新启用可变的用户名/昵称查找来进行回复投递。

出站投递

使用数字 Synology Chat 用户 ID 作为目标。支持 synology-chat:、synology_chat: 和 synology: 前缀。

示例:

openclaw message send --channel synology-chat --target 123456 --message "Hello from OpenClaw"
openclaw message send --channel synology-chat --target synology-chat:123456 --message "Hello again"
openclaw message send --channel synology-chat --target synology:123456 --message "Short prefix"

出站文本按 2000 个字符分块,普通链接保持完整。在受支持的 Chat Server 版本上,请保持 Synology Chat 管理控制台中的在对话和频道中隐藏 URL 预览处于启用状态。

对于附件,OpenClaw 在其受保护的出站媒体策略下加载源文件,将生成的字节冻结在有限的插件级 SQLite 状态中,并通过配置的 webhook 路由向 Synology 提供一个短期的不透明 HTTPS 能力(capability)。NAS 只会收到这个由 OpenClaw 托管的 URL,绝不会收到原始的远程或本地媒体引用。这些能力按账户和路由限定范围,在其十分钟有效期内可重用于延迟的 GET 或 HEAD 请求,并自动过期。文件大小限制为 32 MB。每个账户最多可同时提供四个附件响应,且每分钟最多 128 MB;停滞的响应会在两分钟后关闭。不声明支持字节范围响应。

webhookUrl 和 webhookPath 具有不同作用:

  • webhookUrl 是在 Synology Chat 中配置的、可从外部访问的精确 HTTPS 回调地址。OpenClaw 在创建附件能力时,会使用其公开源、路径以及现有查询字符串。
  • webhookPath 是内部 Gateway 路由。反向代理可以将公开 URL 映射到该路由,但应仅暴露此插件路径,而不是通用的 Gateway HTTP 接口。
  • incomingUrl 指向相反方向:OpenClaw 使用它向 NAS 发送回复。

OpenClaw 绝不会从 Host 或 X-Forwarded-* 请求头推导公开 URL,也绝不会回退为转发原始源 URL。如果 webhookUrl 缺失或无效,入站消息和出站文本仍可正常工作,而附件发送会失败并返回可操作的配置错误。

多账户

多个 Synology Chat 账户受支持,位于 channels.synology-chat.accounts 下。 每个账户可以覆盖 token、入站 URL、公开 webhook URL、webhook 路径、DM 策略和限制。 直接消息会话按账户和用户隔离,因此两个不同 Synology 账户上相同的数字 user_id 不会共享转录状态。 为每个启用的账户设置不同的 webhookPath。OpenClaw 会拒绝重复的完全相同路径, 并拒绝启动在多账户设置中仅继承共享 webhook 路径的命名账户。 如果你确实需要为命名账户使用旧式继承,请 在该账户或 channels.synology-chat 上设置 dangerouslyAllowInheritedWebhookPath: true, 但重复的完全相同路径仍会被以 fail-closed 方式拒绝。建议显式使用每个账户独立的路径。

{
  channels: {
    "synology-chat": {
      enabled: true,
      accounts: {
        default: {
          token: "token-a",
          incomingUrl: "https://nas-a.example.com/...token=...",
          webhookUrl: "https://gateway.example.com/webhook/synology",
        },
        alerts: {
          token: "token-b",
          incomingUrl: "https://nas-b.example.com/...token=...",
          webhookUrl: "https://gateway.example.com/webhook/synology-alerts",
          webhookPath: "/webhook/synology-alerts",
          dmPolicy: "allowlist",
          allowedUserIds: ["987654"],
        },
      },
    },
  },
}

安全说明

  • 保持 token 保密,如果泄露请轮换。
  • 除非你明确信任自签名的本地 NAS 证书,否则保持 allowInsecureSsl: false。
  • 入站 webhook 请求会经过 token 验证,并按发送者进行速率限制(rateLimitPerMinute,默认 30)。
  • 无效 token 检查使用恒定时间密钥比较并 fail closed;重复的无效 token 尝试会暂时锁定源 IP。
  • 入站消息文本会针对已知的提示注入模式进行清理,并在 4000 个字符处截断。
  • 生产环境建议优先使用 dmPolicy: "allowlist"。
  • 除非你明确需要旧式的基于用户名的回复投递,否则保持 dangerouslyAllowNameMatching 关闭。
  • 除非你明确接受多账户设置中共享路径路由风险,否则保持 dangerouslyAllowInheritedWebhookPath 关闭。
  • 反向代理访问日志可能会捕获附件能力 token。请禁用查询字符串日志记录,或对 __openclaw_synology_media_token_* 参数进行脱敏,并保持应用日志中不包含完整能力 URL。
  • 托管附件使用 Content-Disposition: attachment、X-Content-Type-Options: nosniff 和 Cache-Control: no-store。声明或命名为 HTML、SVG 或 XML 的文件会被拒绝。在可选编码标记、空白和注释之后,以 UTF-8、UTF-16 或 UTF-32 标记文档开头的冻结字节也会被拒绝;被动文本或源文件中后面出现的字面标签不会使这些文件成为活动文档。

故障排除

  • Missing required fields (token, user_id, text):
  • 出站 webhook 负载缺少其中一个必需字段
  • 如果 Synology 在请求头中发送 token,请确保 gateway/proxy 保留这些请求头
  • Invalid token:
  • 出站 webhook 密钥与 channels.synology-chat.token 不匹配
  • 请求命中了错误的账户/webhook 路径
  • 反向代理在请求到达 OpenClaw 之前移除了 token 请求头
  • Rate limit exceeded:
  • 来自同一源的过多无效 token 尝试可能会暂时锁定该源
  • 已认证发送者还有单独的按用户消息速率限制
  • Allowlist is empty. Configure allowedUserIds or use dmPolicy=open with allowedUserIds=["*"].:
  • 已启用 dmPolicy="allowlist",但未配置任何用户
  • User not authorized:
  • 发送者的数字 user_id 不在 allowedUserIds 中
  • Synology Chat attachments require webhookUrl:
  • 设置该账户精确的、可从外部访问的 HTTPS 出站 webhook 回调 URL
  • 确认反向代理仅将该公开路由映射到 webhookPath
  • 在附件配置未完成期间,文本和入站消息仍可用

本页原文 Markdown:在 AtomGit 查看·内容源自开源项目 cl/openclaw