跳转到主要内容

Documentation Index

Fetch the complete documentation index at: https://docs.openclaw.ai/llms.txt

Use this file to discover all available pages before exploring further.

Status: 可下载插件(机器人 token + WebSocket 事件)。支持渠道、群组和私信。Mattermost 是一个可自托管的团队消息平台;产品详情和下载请参阅官方网站 mattermost.com

安装

配置渠道前,请先安装 Mattermost:
openclaw plugins install @openclaw/mattermost
详情:插件

快速设置

1

Ensure plugin is available

当前打包的 OpenClaw 版本已内置它。较旧或自定义安装可使用上面的命令手动添加。
2

Create a Mattermost bot

创建 Mattermost 机器人账号并复制机器人 token
3

Copy the base URL

复制 Mattermost base URL(例如 https://chat.example.com)。
4

Configure OpenClaw and start the gateway

最小配置:
{
  channels: {
    mattermost: {
      enabled: true,
      botToken: "mm-token",
      baseUrl: "https://chat.example.com",
      dmPolicy: "pairing",
    },
  },
}

原生斜杠命令

原生斜杠命令需要选择启用。启用后,OpenClaw 会通过 Mattermost API 注册 oc_* 斜杠命令,并在 Gateway 网关 HTTP 服务器上接收回调 POST。
{
  channels: {
    mattermost: {
      commands: {
        native: true,
        nativeSkills: true,
        callbackPath: "/api/channels/mattermost/command",
        // Use when Mattermost cannot reach the gateway directly (reverse proxy/public URL).
        callbackUrl: "https://gateway.example.com/api/channels/mattermost/command",
      },
    },
  },
}
  • native: "auto" 对 Mattermost 默认禁用。设置 native: true 以启用。
  • 如果省略 callbackUrl,OpenClaw 会根据 Gateway 网关主机/端口 + callbackPath 推导出一个。
  • 对于多账号设置,commands 可以在顶层设置,也可以在 channels.mattermost.accounts.<id>.commands 下设置(账号值会覆盖顶层字段)。
  • 命令回调会使用 OpenClaw 注册 oc_* 命令时 Mattermost 返回的每命令 token 进行验证。
  • OpenClaw 会在接受每个回调前刷新当前 Mattermost 命令注册,因此已删除或重新生成的斜杠命令中的过期 token 无需重启 Gateway 网关也会停止被接受。
  • 如果 Mattermost API 无法确认该命令仍为当前命令,回调验证会失败并关闭;失败的验证会被短暂缓存,并发查找会被合并,新的查找启动会按命令限速,以限制重放压力。
  • 当注册失败、启动不完整,或回调 token 与解析出的命令已注册 token 不匹配时,斜杠回调会失败并关闭(对一个命令有效的 token 不能访问另一个命令的上游验证)。
回调端点必须能从 Mattermost 服务器访问。
  • 除非 Mattermost 与 OpenClaw 运行在同一主机/网络命名空间中,否则不要将 callbackUrl 设置为 localhost
  • 除非你的 Mattermost base URL 会将 /api/channels/mattermost/command 反向代理到 OpenClaw,否则不要将 callbackUrl 设置为你的 Mattermost base URL。
  • 一个快速检查是 curl https://<gateway-host>/api/channels/mattermost/command;GET 应返回来自 OpenClaw 的 405 Method Not Allowed,而不是 404
如果你的回调目标是私有/tailnet/内部地址,请将 Mattermost ServiceSettings.AllowedUntrustedInternalConnections 设置为包含回调主机/域名。使用主机/域名条目,而不是完整 URL。
  • 正确:gateway.tailnet-name.ts.net
  • 错误:https://gateway.tailnet-name.ts.net

环境变量(默认账号)

如果你更喜欢环境变量,请在 Gateway 网关主机上设置这些变量:
  • MATTERMOST_BOT_TOKEN=...
  • MATTERMOST_URL=https://chat.example.com
环境变量仅适用于默认账号(default)。其他账号必须使用配置值。MATTERMOST_URL 不能从工作区 .env 设置;请参阅工作区 .env 文件

聊天模式

Mattermost 会自动响应私信。渠道行为由 chatmode 控制:
仅在渠道中被 @提及时响应。
配置示例:
{
  channels: {
    mattermost: {
      chatmode: "onchar",
      oncharPrefixes: [">", "!"],
    },
  },
}
注意:
  • onchar 仍会响应显式 @提及。
  • 旧配置仍会遵循 channels.mattermost.requireMention,但首选 chatmode

线程和会话

使用 channels.mattermost.replyToMode 控制渠道和群组回复是留在主渠道中,还是在触发帖下开启一个线程。
  • off(默认):仅当入站帖已经在线程中时,才在线程中回复。
  • first:对于顶层渠道/群组帖,在该帖下开启一个线程,并将对话路由到线程作用域的会话。
  • all:目前在 Mattermost 中行为与 first 相同。
  • 私信会忽略此设置,并保持非线程化。
配置示例:
{
  channels: {
    mattermost: {
      replyToMode: "all",
    },
  },
}
注意:
  • 线程作用域的会话使用触发帖 id 作为线程根。
  • firstall 目前等价,因为一旦 Mattermost 有了线程根,后续分块和媒体都会继续留在同一线程中。

访问控制(私信)

  • 默认:channels.mattermost.dmPolicy = "pairing"(未知发送者会获得配对码)。
  • 通过以下方式批准:
    • openclaw pairing list mattermost
    • openclaw pairing approve mattermost <CODE>
  • 公开私信:channels.mattermost.dmPolicy="open"channels.mattermost.allowFrom=["*"]

渠道(群组)

  • 默认:channels.mattermost.groupPolicy = "allowlist"(由提及门控)。
  • 使用 channels.mattermost.groupAllowFrom 将发送者加入允许列表(建议使用用户 ID)。
  • 每渠道提及覆盖位于 channels.mattermost.groups.<channelId>.requireMention 下,或使用 channels.mattermost.groups["*"].requireMention 作为默认值。
  • @username 匹配是可变的,并且仅在 channels.mattermost.dangerouslyAllowNameMatching: true 时启用。
  • 开放渠道:channels.mattermost.groupPolicy="open"(由提及门控)。
  • 运行时注意事项:如果完全缺少 channels.mattermost,运行时会回退到 groupPolicy="allowlist" 来执行群组检查(即使已设置 channels.defaults.groupPolicy)。
示例:
{
  channels: {
    mattermost: {
      groupPolicy: "open",
      groups: {
        "*": { requireMention: true },
        "team-channel-id": { requireMention: false },
      },
    },
  },
}

出站投递目标

将这些目标格式用于 openclaw message send 或 cron/webhooks:
  • channel:<id> 表示渠道
  • user:<id> 表示私信
  • @username 表示私信(通过 Mattermost API 解析)
裸不透明 ID(如 64ifufp...)在 Mattermost 中是有歧义的(用户 ID 与渠道 ID)。OpenClaw 会按用户优先解析它们:
  • 如果该 ID 作为用户存在(GET /api/v4/users/<id> 成功),OpenClaw 会通过 /api/v4/channels/direct 解析直接渠道并发送私信
  • 否则该 ID 会被视为渠道 ID
如果你需要确定性行为,请始终使用显式前缀(user:<id> / channel:<id>)。

私信渠道重试

当 OpenClaw 发送到 Mattermost 私信目标并且需要先解析直接渠道时,它默认会重试瞬时的直接渠道创建失败。 使用 channels.mattermost.dmChannelRetry 为 Mattermost 插件全局调节该行为,或使用 channels.mattermost.accounts.<id>.dmChannelRetry 为单个账号调节。
{
  channels: {
    mattermost: {
      dmChannelRetry: {
        maxRetries: 3,
        initialDelayMs: 1000,
        maxDelayMs: 10000,
        timeoutMs: 30000,
      },
    },
  },
}
注意:
  • 这仅适用于私信渠道创建(/api/v4/channels/direct),不适用于每个 Mattermost API 调用。
  • 重试适用于瞬时失败,例如速率限制、5xx 响应,以及网络或超时错误。
  • 429 外的 4xx 客户端错误会被视为永久错误,不会重试。

预览流式传输

Mattermost 会将思考、工具活动和部分回复文本流式传输到单个草稿预览帖中,并在最终答案可以安全发送时就地完成。预览会在同一帖 id 上更新,而不是用逐分块消息刷屏。媒体/错误最终结果会取消待处理的预览编辑,并使用正常投递,而不是刷新一个一次性的预览帖。 通过 channels.mattermost.streaming 启用:
{
  channels: {
    mattermost: {
      streaming: "partial", // off | partial | block | progress
    },
  },
}
  • partial 是通常的选择:一个预览帖会随着回复增长而被编辑,然后以完整答案完成。
  • block 在预览帖内使用追加式草稿分块。
  • progress 在生成时显示状态预览,并且只在完成时发布最终答案。
  • off 禁用预览流式传输。
  • 如果流无法就地完成(例如帖子在流式传输中途被删除),OpenClaw 会回退为发送一个新的最终帖,因此回复永远不会丢失。
  • 仅推理的载荷会从渠道帖子中抑制,包括作为 > Reasoning: 块引用到达的文本。设置 /reasoning on 可在其他界面查看思考;Mattermost 最终帖只保留答案。
  • 请参阅流式传输了解渠道映射矩阵。

表情反应(消息工具)

  • message action=reactchannel=mattermost 一起使用。
  • messageId 是 Mattermost 帖子 id。
  • emoji 接受类似 thumbsup:+1: 的名称(冒号可选)。
  • 设置 remove=true(布尔值)以移除表情反应。
  • 表情反应添加/移除事件会作为系统事件转发到被路由的智能体会话。
示例:
message action=react channel=mattermost target=channel:<channelId> messageId=<postId> emoji=thumbsup
message action=react channel=mattermost target=channel:<channelId> messageId=<postId> emoji=thumbsup remove=true
配置:
  • channels.mattermost.actions.reactions:启用/禁用表情反应操作(默认 true)。
  • 每账号覆盖:channels.mattermost.accounts.<id>.actions.reactions

交互式按钮(消息工具)

发送带可点击按钮的消息。当用户点击按钮时,智能体会收到所选内容并可以响应。 通过向渠道能力添加 inlineButtons 来启用按钮:
{
  channels: {
    mattermost: {
      capabilities: ["inlineButtons"],
    },
  },
}
使用带有 buttons 参数的 message action=send。按钮是二维数组(按钮行):
message action=send channel=mattermost target=channel:<channelId> buttons=[[{"text":"Yes","callback_data":"yes"},{"text":"No","callback_data":"no"}]]
按钮字段:
text
string
必填
显示标签。
callback_data
string
必填
点击时发回的值(用作操作 ID)。
style
"default" | "primary" | "danger"
按钮样式。
当用户点击按钮时:
1

按钮被替换为确认信息

所有按钮都会被替换为一行确认信息(例如 “✓ Yes selected by @user”)。
2

智能体接收所选项

智能体会将所选项作为入站消息接收并响应。
  • 按钮回调使用 HMAC-SHA256 验证(自动完成,无需配置)。
  • Mattermost 会从其 API 响应中去除回调数据(安全功能),因此点击后会移除所有按钮,无法部分移除。
  • 包含连字符或下划线的操作 ID 会自动清理(Mattermost 路由限制)。
  • channels.mattermost.capabilities:能力字符串数组。添加 "inlineButtons" 可在智能体系统提示词中启用按钮工具描述。
  • channels.mattermost.interactions.callbackBaseUrl:可选的按钮回调外部基准 URL(例如 https://gateway.example.com)。当 Mattermost 无法直接通过 Gateway 网关的绑定主机访问它时使用此项。
  • 在多账号设置中,你也可以在 channels.mattermost.accounts.<id>.interactions.callbackBaseUrl 下设置相同字段。
  • 如果省略 interactions.callbackBaseUrl,OpenClaw 会从 gateway.customBindHost + gateway.port 推导回调 URL,然后回退到 http://localhost:<port>
  • 可达性规则:按钮回调 URL 必须能从 Mattermost 服务器访问。只有当 Mattermost 和 OpenClaw 运行在同一主机/网络命名空间时,localhost 才有效。
  • 如果你的回调目标是私有/tailnet/内部地址,请将其主机/域名添加到 Mattermost ServiceSettings.AllowedUntrustedInternalConnections

直接 API 集成(外部脚本)

外部脚本和 Webhook 可以通过 Mattermost REST API 直接发布按钮,而不是经过智能体的 message 工具。尽可能使用插件中的 buildButtonAttachments();如果发布原始 JSON,请遵循以下规则: 载荷结构:
{
  channel_id: "<channelId>",
  message: "Choose an option:",
  props: {
    attachments: [
      {
        actions: [
          {
            id: "mybutton01", // alphanumeric only — see below
            type: "button", // required, or clicks are silently ignored
            name: "Approve", // display label
            style: "primary", // optional: "default", "primary", "danger"
            integration: {
              url: "https://gateway.example.com/mattermost/interactions/default",
              context: {
                action_id: "mybutton01", // must match button id (for name lookup)
                action: "approve",
                // ... any custom fields ...
                _token: "<hmac>", // see HMAC section below
              },
            },
          },
        ],
      },
    ],
  },
}
关键规则
  1. 附件放在 props.attachments 中,而不是顶层 attachments(否则会被静默忽略)。
  2. 每个操作都需要 type: "button";没有它,点击会被静默吞掉。
  3. 每个操作都需要 id 字段;Mattermost 会忽略没有 ID 的操作。
  4. 操作 id 必须仅包含字母数字[a-zA-Z0-9])。连字符和下划线会破坏 Mattermost 的服务端操作路由(返回 404)。使用前请移除它们。
  5. context.action_id 必须匹配按钮的 id,这样确认消息才会显示按钮名称(例如 “Approve”),而不是原始 ID。
  6. context.action_id 是必填项;没有它时交互处理器会返回 400。
HMAC 令牌生成 Gateway 网关使用 HMAC-SHA256 验证按钮点击。外部脚本必须生成与 Gateway 网关验证逻辑匹配的令牌:
1

从机器人令牌派生密钥

HMAC-SHA256(key="openclaw-mattermost-interactions", data=botToken)
2

构建上下文对象

使用除 _token 以外的所有字段构建上下文对象。
3

使用排序键序列化

使用排序键并且不含空格进行序列化(Gateway 网关使用带排序键的 JSON.stringify,会生成紧凑输出)。
4

签名载荷

HMAC-SHA256(key=secret, data=serializedContext)
5

添加令牌

将生成的十六进制摘要作为 _token 添加到上下文中。
Python 示例:
import hmac, hashlib, json

secret = hmac.new(
    b"openclaw-mattermost-interactions",
    bot_token.encode(), hashlib.sha256
).hexdigest()

ctx = {"action_id": "mybutton01", "action": "approve"}
payload = json.dumps(ctx, sort_keys=True, separators=(",", ":"))
token = hmac.new(secret.encode(), payload.encode(), hashlib.sha256).hexdigest()

context = {**ctx, "_token": token}
  • Python 的 json.dumps 默认会添加空格({"key": "val"})。使用 separators=(",", ":") 以匹配 JavaScript 的紧凑输出({"key":"val"})。
  • 始终签名所有上下文字段(减去 _token)。Gateway 网关会移除 _token,然后对剩余的所有内容签名。签名子集会导致静默验证失败。
  • 使用 sort_keys=True;Gateway 网关会在签名前对键排序,而 Mattermost 在存储载荷时可能会重新排列上下文字段。
  • 从机器人令牌派生密钥(确定性),不要使用随机字节。创建按钮的进程和验证按钮的 Gateway 网关必须使用相同密钥。

目录适配器

Mattermost 插件包含一个目录适配器,可通过 Mattermost API 解析渠道和用户名。这会在 openclaw message send 以及 cron/webhook 投递中启用 #channel-name@username 目标。 无需配置;适配器使用账号配置中的机器人令牌。

多账号

Mattermost 支持在 channels.mattermost.accounts 下配置多个账号:
{
  channels: {
    mattermost: {
      accounts: {
        default: { name: "Primary", botToken: "mm-token", baseUrl: "https://chat.example.com" },
        alerts: { name: "Alerts", botToken: "mm-token-2", baseUrl: "https://alerts.example.com" },
      },
    },
  },
}

故障排除

确保机器人在渠道中并提及它(oncall),使用触发前缀(onchar),或设置 chatmode: "onmessage"
  • 检查机器人令牌、基准 URL,以及账号是否已启用。
  • 多账号问题:环境变量只适用于 default 账号。
  • Unauthorized: invalid command token.:OpenClaw 未接受回调令牌。典型原因包括:
    • 斜杠命令注册失败,或启动时只完成了部分注册
    • 回调命中了错误的 Gateway 网关/账号
    • Mattermost 仍有指向先前回调目标的旧命令
    • Gateway 网关重启后未重新激活斜杠命令
  • 如果原生斜杠命令停止工作,请检查日志中是否有 mattermost: failed to register slash commandsmattermost: native slash commands enabled but no commands could be registered
  • 如果省略了 callbackUrl,并且日志警告回调解析为 http://127.0.0.1:18789/...,那么该 URL 可能只有在 Mattermost 与 OpenClaw 运行在同一主机/网络命名空间时才可访问。请改为设置明确的外部可达 commands.callbackUrl
  • 按钮显示为空白框:智能体可能正在发送格式错误的按钮数据。检查每个按钮是否同时具有 textcallback_data 字段。
  • 按钮能渲染但点击没有反应:验证 Mattermost 服务器配置中的 AllowedUntrustedInternalConnections 是否包含 127.0.0.1 localhost,并且 ServiceSettings 中的 EnablePostActionIntegration 是否为 true
  • 按钮点击时返回 404:按钮 id 可能包含连字符或下划线。Mattermost 的操作路由器会在非字母数字 ID 上失效。仅使用 [a-zA-Z0-9]
  • Gateway 网关日志显示 invalid _token:HMAC 不匹配。检查你是否签名了所有上下文字段(而不是子集)、使用排序键,并使用紧凑 JSON(无空格)。参见上面的 HMAC 部分。
  • Gateway 网关日志显示 missing _token in context_token 字段不在按钮上下文中。构建集成载荷时请确保包含它。
  • 确认信息显示原始 ID 而不是按钮名称:context.action_id 与按钮的 id 不匹配。将两者设置为同一个已清理值。
  • 智能体不知道按钮:将 capabilities: ["inlineButtons"] 添加到 Mattermost 渠道配置中。

相关