Skip to main content

Mattermost(外掛程式)

狀態:透過外掛程式支援(bot token + WebSocket 事件)。支援頻道、群組和 DM。 Mattermost 是可自行託管的團隊訊息平台;請參閱官方網站 mattermost.com 了解產品詳情和下載。

需要外掛程式

Mattermost 以外掛程式形式發布,未隨核心安裝捆綁。 透過 CLI 安裝(npm registry):
openclaw plugins install @openclaw/mattermost
本地 checkout(從 git repo 執行時):
openclaw plugins install ./extensions/mattermost
若你在設定/上線過程中選擇 Mattermost,且偵測到 git checkout,OpenClaw 將自動提供本地安裝路徑。 詳情:Plugins

快速設定

  1. 安裝 Mattermost 外掛程式。
  2. 建立 Mattermost bot 帳號並複製 bot token
  3. 複製 Mattermost base URL(例如 https://chat.example.com)。
  4. 設定 OpenClaw 並啟動 gateway。
最小設定:
{
  channels: {
    mattermost: {
      enabled: true,
      botToken: "mm-token",
      baseUrl: "https://chat.example.com",
      dmPolicy: "pairing",
    },
  },
}

原生斜線指令

原生斜線指令需要選擇啟用。啟用後,OpenClaw 透過 Mattermost API 註冊 oc_* 斜線指令,並在 gateway HTTP server 上接收 callback POST。
{
  channels: {
    mattermost: {
      commands: {
        native: true,
        nativeSkills: true,
        callbackPath: "/api/channels/mattermost/command",
        // 當 Mattermost 無法直接連接 gateway 時使用(反向代理/公開 URL)。
        callbackUrl: "https://gateway.example.com/api/channels/mattermost/command",
      },
    },
  },
}
注意:
  • native: "auto" 對 Mattermost 預設為停用。設定 native: true 啟用。
  • 若省略 callbackUrl,OpenClaw 從 gateway host/port + callbackPath 推導。
  • 對於多帳號設定,commands 可在頂層或 channels.mattermost.accounts.<id>.commands 下設定(帳號值覆蓋頂層欄位)。
  • 指令 callback 使用每個指令的 token 驗證,token 檢查失敗時拒絕。
  • 可連線需求:callback 端點必須可從 Mattermost server 連接。
    • 除非 Mattermost 和 OpenClaw 在同一主機/網路命名空間執行,否則不要將 callbackUrl 設定為 localhost
    • 除非該 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
  • Mattermost 出站 allowlist 需求:
    • 若你的 callback 目標是私有/tailnet/內部位址,請在 Mattermost ServiceSettings.AllowedUntrustedInternalConnections 中加入 callback host/domain。
    • 使用 host/domain 條目,而非完整 URL。
      • 正確:gateway.tailnet-name.ts.net
      • 錯誤:https://gateway.tailnet-name.ts.net

環境變數(預設帳號)

若偏好使用環境變數,在 gateway 主機上設定:
  • MATTERMOST_BOT_TOKEN=...
  • MATTERMOST_URL=https://chat.example.com
環境變數只適用於預設帳號(default)。其他帳號必須使用設定值。

聊天模式

Mattermost 自動回覆 DM。頻道行為由 chatmode 控制:
  • oncall(預設):只在頻道中被 @mention 時回覆。
  • onmessage:回覆每條頻道訊息。
  • onchar:當訊息以觸發前綴開頭時回覆。
設定範例:
{
  channels: {
    mattermost: {
      chatmode: "onchar",
      oncharPrefixes: [">", "!"],
    },
  },
}
注意:
  • onchar 仍回覆明確的 @mention。
  • channels.mattermost.requireMention 在舊版設定中受尊重,但 chatmode 是建議方式。

Threading(討論串)和工作階段

使用 channels.mattermost.replyToMode 控制頻道和群組回覆是保留在主頻道中還是在觸發文章下開始討論串。
  • off(預設):只有在入站文章已在討論串中時才在討論串中回覆。
  • first:對頂層頻道/群組文章,在該文章下開始討論串,並將對話路由到串作用域的工作階段。
  • all:目前在 Mattermost 上與 first 行為相同。
  • 私訊忽略此設定,保持非串式。
設定範例:
{
  channels: {
    mattermost: {
      replyToMode: "all",
    },
  },
}
注意:
  • 串作用域的工作階段使用觸發文章 ID 作為串根。
  • firstall 目前等效,因為一旦 Mattermost 有了串根,後續的分塊和媒體會繼續在同一討論串中。

存取控制(DM)

  • 預設:channels.mattermost.dmPolicy = "pairing"(未知發送者收到配對碼)。
  • 透過以下核准:
    • openclaw pairing list mattermost
    • openclaw pairing approve mattermost <CODE>
  • 公開 DM:channels.mattermost.dmPolicy="open" 加上 channels.mattermost.allowFrom=["*"]

頻道(群組)

  • 預設:channels.mattermost.groupPolicy = "allowlist"(需要 mention)。
  • 使用 channels.mattermost.groupAllowFrom 指定允許的發送者(建議使用用戶 ID)。
  • @username 匹配是可變的,只有在 channels.mattermost.dangerouslyAllowNameMatching: true 時才啟用。
  • 開放頻道:channels.mattermost.groupPolicy="open"(需要 mention)。
  • 執行時注意:若 channels.mattermost 完全缺失(僅環境變數設定),執行時會退回到 groupPolicy="allowlist" 進行群組檢查(即使設定了 channels.defaults.groupPolicy)。

出站傳遞目標

openclaw message send 或 cron/webhook 中使用這些目標格式:
  • channel:<id> 用於頻道
  • user:<id> 用於 DM
  • @username 用於 DM(透過 Mattermost API 解析)
純 ID 被視為頻道。

Reactions(訊息工具)

  • 使用 message action=react 搭配 channel=mattermost
  • messageId 是 Mattermost post id。
  • emoji 接受 thumbsup:+1: 等名稱(冒號可選)。
  • 設定 remove=true(布林值)移除 reaction。
  • Reaction 新增/移除事件作為系統事件轉發到路由的 agent 工作階段。
範例:
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:啟用/停用 reaction 動作(預設 true)。
  • 每帳號覆蓋:channels.mattermost.accounts.<id>.actions.reactions

互動按鈕(訊息工具)

傳送帶有可點擊按鈕的訊息。當用戶點擊按鈕時,agent 收到選擇並可回應。 透過在頻道能力中新增 inlineButtons 啟用按鈕:
{
  channels: {
    mattermost: {
      capabilities: ["inlineButtons"],
    },
  },
}
使用帶有 buttons 參數的 message action=send。按鈕是 2D 陣列(按鈕列):
message action=send channel=mattermost target=channel:<channelId> buttons=[[{"text":"Yes","callback_data":"yes"},{"text":"No","callback_data":"no"}]]
按鈕欄位:
  • text(必要):顯示標籤。
  • callback_data(必要):點擊時返回的值(用作動作 ID)。
  • style(選用):"default""primary""danger"
當用戶點擊按鈕時:
  1. 所有按鈕被替換為確認行(例如「✓ Yes selected by @user」)。
  2. Agent 收到選擇作為入站訊息並回應。
注意:
  • 按鈕 callback 使用 HMAC-SHA256 驗證(自動,無需設定)。
  • Mattermost 從 API 回應中去除 callback data(安全功能),因此所有按鈕在點擊時都被移除——無法部分移除。
  • 包含連字號或底線的動作 ID 會自動清理(Mattermost 路由限制)。
設定:
  • channels.mattermost.capabilities:能力字串陣列。新增 "inlineButtons" 在 agent system prompt 中啟用按鈕工具描述。
  • channels.mattermost.interactions.callbackBaseUrl:選用的按鈕 callback 外部 base URL(例如 https://gateway.example.com)。當 Mattermost 無法直接連接 gateway 的綁定主機時使用。
  • 多帳號設定中,也可在 channels.mattermost.accounts.<id>.interactions.callbackBaseUrl 下設定相同欄位。
  • 若省略 interactions.callbackBaseUrl,OpenClaw 從 gateway.customBindHost + gateway.port 推導 callback URL,然後退回到 http://localhost:<port>
  • 可連線規則:按鈕 callback URL 必須可從 Mattermost server 連接。localhost 只有在 Mattermost 和 OpenClaw 在同一主機/網路命名空間執行時才有效。
  • 若你的 callback 目標是私有/tailnet/內部的,請將其 host/domain 加入 Mattermost ServiceSettings.AllowedUntrustedInternalConnections

直接 API 整合(外部指令碼)

外部指令碼和 webhook 可以直接透過 Mattermost REST API 發布按鈕,而無需透過 agent 的 message 工具。盡量使用擴展功能中的 buildButtonAttachments();若發布原始 JSON,請遵循以下規則: Payload 結構:
{
  channel_id: "<channelId>",
  message: "Choose an option:",
  props: {
    attachments: [
      {
        actions: [
          {
            id: "mybutton01", // 僅限英數字元——見下方
            type: "button", // 必要,否則點擊被靜默忽略
            name: "Approve", // 顯示標籤
            style: "primary", // 選用:"default"、"primary"、"danger"
            integration: {
              url: "https://gateway.example.com/mattermost/interactions/default",
              context: {
                action_id: "mybutton01", // 必須匹配按鈕 id(用於名稱查詢)
                action: "approve",
                // ... 任何自訂欄位 ...
                _token: "<hmac>", // 見下方 HMAC 章節
              },
            },
          },
        ],
      },
    ],
  },
}
關鍵規則:
  1. Attachments 放在 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 token 生成: Gateway 使用 HMAC-SHA256 驗證按鈕點擊。外部指令碼必須生成與 gateway 驗證邏輯匹配的 token:
  1. 從 bot token 推導 secret: HMAC-SHA256(key="openclaw-mattermost-interactions", data=botToken)
  2. 建立包含所有欄位(除了 _token)的 context 物件。
  3. 使用排序鍵無空格序列化(gateway 使用 JSON.stringify 搭配排序鍵,產生緊湊輸出)。
  4. 簽署:HMAC-SHA256(key=secret, data=serializedContext)
  5. 在 context 中將結果的十六進位摘要加入 _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}
常見 HMAC 陷阱:
  • Python 的 json.dumps 預設加空格({"key": "val"})。使用 separators=(",", ":") 匹配 JavaScript 的緊湊輸出({"key":"val"})。
  • 始終簽署所有 context 欄位(減去 _token)。Gateway 去除 _token 後對其餘所有內容簽署。簽署子集會導致靜默驗證失敗。
  • 使用 sort_keys=True——gateway 在簽署前排序鍵,而 Mattermost 在儲存 payload 時可能重新排列 context 欄位。
  • 從 bot token 推導 secret(確定性的),而非隨機位元組。Secret 在建立按鈕的進程和驗證的 gateway 之間必須相同。

目錄適配器

Mattermost 外掛程式包含目錄適配器,透過 Mattermost API 解析頻道和用戶名稱。這使得 openclaw message send 和 cron/webhook 傳遞中可以使用 #channel-name@username 目標。 無需設定——適配器使用帳號設定中的 bot token。

多帳號

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" },
      },
    },
  },
}

疑難排解

  • 頻道中無回覆:確認 bot 在頻道中並 mention 它(oncall),使用觸發前綴(onchar),或設定 chatmode: "onmessage"
  • 驗證錯誤:檢查 bot token、base URL 和帳號是否啟用。
  • 多帳號問題:環境變數只適用於 default 帳號。
  • 按鈕顯示為白色方塊:agent 可能傳送了格式錯誤的按鈕資料。確認每個按鈕都有 textcallback_data 欄位。
  • 按鈕顯示但點擊無反應:驗證 Mattermost server 設定中的 AllowedUntrustedInternalConnections 包含 127.0.0.1 localhost,且 ServiceSettings 中的 EnablePostActionIntegrationtrue
  • 點擊按鈕返回 404:按鈕 id 可能包含連字號或底線。Mattermost 的動作路由器在非英數字元 ID 上出錯。只使用 [a-zA-Z0-9]
  • Gateway 日誌顯示 invalid _token:HMAC 不匹配。確認你簽署了所有 context 欄位(而非子集),使用排序鍵,並使用緊湊 JSON(無空格)。參見上方 HMAC 章節。
  • Gateway 日誌顯示 missing _token in context:按鈕的 context 中缺少 _token 欄位。建立整合 payload 時確保包含它。
  • 確認顯示原始 ID 而非按鈕名稱:context.action_id 與按鈕的 id 不匹配。將兩者設定為相同的清理值。
  • Agent 不知道按鈕:在 Mattermost 頻道設定中新增 capabilities: ["inlineButtons"]