跳轉到主要內容
Status:可下載的外掛(Bot Token + WebSocket 事件)。支援頻道、私人頻道、群組 DM 和 DM。Mattermost 是可自行託管的團隊訊息平台(mattermost.com)。

安裝

openclaw plugins install @openclaw/mattermost
詳細資訊:外掛

快速設定

1

確認外掛可用

使用上述命令安裝 @openclaw/mattermost,如果閘道已在執行,請重新啟動閘道。
2

建立 Mattermost Bot

建立 Mattermost Bot 帳戶,複製 Bot Token,並將 Bot 新增到它應讀取的團隊和頻道。
3

複製基底 URL

複製 Mattermost 基底 URL(例如 https://chat.example.com)。結尾的 /api/v4 會自動移除。
4

設定 OpenClaw 並啟動閘道

最小設定:
{
  channels: {
    mattermost: {
      enabled: true,
      botToken: "mm-token",
      baseUrl: "https://chat.example.com",
      dmPolicy: "pairing",
    },
  },
}
非互動式替代方式:
openclaw channels add --channel mattermost --bot-token <token> --http-url https://chat.example.com
私人/LAN/tailnet 位址上的自託管 Mattermost:對外 Mattermost API 請求會通過 SSRF 防護,預設會封鎖私人與內部 IP。使用 channels.mattermost.network.dangerouslyAllowPrivateNetwork: true 選擇啟用(每個帳戶:channels.mattermost.accounts.<id>.network.dangerouslyAllowPrivateNetwork)。

原生斜線命令

原生斜線命令為選擇啟用。啟用時,OpenClaw 會在 Bot 所屬的每個團隊上註冊 oc_* 斜線命令,並在閘道 HTTP 伺服器上接收 callback POST。
{
  channels: {
    mattermost: {
      commands: {
        native: true,
        nativeSkills: true,
        callbackPath: "/api/channels/mattermost/command",
        // 當 Mattermost 無法直接連到閘道時使用(反向代理/公開 URL)。
        callbackUrl: "https://gateway.example.com/api/channels/mattermost/command",
      },
    },
  },
}
已註冊命令:/oc_status/oc_model/oc_models/oc_new/oc_help/oc_think/oc_reasoning/oc_verbose/oc_queue。搭配 nativeSkills: true 時,技能命令也會註冊為 /oc_<skill>
  • nativenativeSkills 預設為 "auto",對 Mattermost 解析為停用。請明確將它們設為 true
  • callbackPath 預設為 /api/channels/mattermost/command
  • 如果省略 callbackUrl,OpenClaw 會推導出 http://<gateway.customBindHost or localhost>:<gateway.port, default 18789><callbackPath>。萬用字元綁定位址(0.0.0.0::)會回退到 localhost
  • 對於多帳戶設定,commands 可設定在頂層,或設定於 channels.mattermost.accounts.<id>.commands 底下(帳戶值會覆寫頂層欄位)。
  • 由其他整合以相同觸發字建立的現有斜線命令會保持不變(註冊會略過它們);Bot 建立的命令會在 callback URL 漂移時更新或重新建立。
  • 命令 callback 會使用 Mattermost 在 OpenClaw 註冊 oc_* 命令時傳回的個別命令 Token 進行驗證。
  • OpenClaw 會在接受每個 callback 前重新整理目前的 Mattermost 命令註冊,因此已刪除或重新產生的斜線命令所留下的過期 Token,無需重新啟動閘道就會停止被接受。
  • 如果 Mattermost API 無法確認命令仍為目前版本,callback 驗證會失敗關閉;失敗的驗證會短暫快取,並行查詢會合併,而新的查詢開始會針對每個命令進行速率限制,以限制重放壓力。
  • 當註冊失敗、啟動不完整,或 callback Token 不符合已解析命令的已註冊 Token 時,斜線 callback 會失敗關閉(對某個命令有效的 Token 無法對不同命令進行上游驗證)。
  • 已接受的 callback 會以短暫可見的「Processing…」回覆確認;真正的答案會作為一般訊息送達。
callback 端點必須能從 Mattermost 伺服器連線。
  • 除非 Mattermost 與 OpenClaw 在相同主機/網路命名空間中執行,否則不要將 callbackUrl 設為 localhost
  • 除非該 URL 會將 /api/channels/mattermost/command 反向代理到 OpenClaw,否則不要將 callbackUrl 設為你的 Mattermost 基底 URL。
  • 快速檢查為 curl https://<gateway-host>/api/channels/mattermost/command;GET 應該從 OpenClaw 傳回 405 Method Not Allowed,而不是 404
如果你的 callback 目標是私人/tailnet/內部位址,請設定 Mattermost ServiceSettings.AllowedUntrustedInternalConnections 以包含 callback 主機/網域。使用主機/網域項目,而不是完整 URL。
  • 正確:gateway.tailnet-name.ts.net
  • 錯誤:https://gateway.tailnet-name.ts.net

環境變數(預設帳戶)

如果你偏好使用環境變數,請在閘道主機上設定:
  • MATTERMOST_BOT_TOKEN=...
  • MATTERMOST_URL=https://chat.example.com
環境變數只會套用到預設帳戶(default)。其他帳戶必須使用設定值。MATTERMOST_URL 不能從工作區 .env 設定;請參閱工作區 .env 檔案

聊天模式

Mattermost 會自動回應 DM。頻道行為由 chatmode 控制:
僅在頻道中被 @提及時回應。
設定範例:
{
  channels: {
    mattermost: {
      chatmode: "onchar",
      oncharPrefixes: [">", "!"], // default
    },
  },
}
備註:
  • onchar 仍會回應明確的 @提及。
  • channels.mattermost.requireMention 仍會被遵循,但優先使用 chatmode。每個頻道的 groups.<channelId>.requireMention 設定優先於兩者。
  • Bot 在頻道執行緒中傳送可見回覆後,該同一執行緒中的後續訊息無需新的 @提及或 onchar 前綴也會得到回答,因此多輪執行緒對話會保持流暢。參與狀態會在 Bot 最後於該執行緒回覆後記住 7 天,並會在閘道重新啟動後持續存在。Bot 只觀察過的執行緒不受影響;請開始新的頂層訊息以再次要求明確提及。

執行緒與工作階段

使用 channels.mattermost.replyToMode 控制頻道和群組回覆是留在主要頻道中,還是在觸發貼文下方開始執行緒。
  • off(預設):只有當傳入貼文已經在執行緒中時,才在執行緒中回覆。
  • first:對頂層頻道/群組貼文,在該貼文下方開始執行緒,並將對話路由到執行緒範圍的工作階段。
  • allbatched:目前對 Mattermost 而言行為與 first 相同,因為 Mattermost 一旦有執行緒根,後續片段和媒體會繼續留在同一個執行緒中。
  • 直接訊息會忽略此設定,並保持非執行緒形式。
{
  channels: {
    mattermost: {
      replyToMode: "all",
    },
  },
}
執行緒範圍的工作階段使用觸發貼文 ID 作為執行緒根。

存取控制(DM)

  • 預設:channels.mattermost.dmPolicy = "pairing"(未知傳送者會取得配對碼)。其他值:allowlistopendisabled
  • 透過以下方式核准:
    • openclaw pairing list mattermost
    • openclaw pairing approve mattermost <CODE>
  • 公開 DM:channels.mattermost.dmPolicy="open" 加上 channels.mattermost.allowFrom=["*"](設定 schema 會強制要求萬用字元)。
  • channels.mattermost.allowFrom 接受使用者 ID(建議)和 accessGroup:<name> 項目。請參閱存取群組

頻道(群組)

  • 預設:channels.mattermost.groupPolicy = "allowlist"(以提及作為門檻)。
  • 使用 channels.mattermost.groupAllowFrom 將傳送者加入允許清單(建議使用使用者 ID)。
  • channels.mattermost.groupAllowFrom 接受 accessGroup:<name> 項目。請參閱存取群組
  • 每個頻道的提及覆寫位於 channels.mattermost.groups.<channelId>.requireMention 底下,或以 channels.mattermost.groups["*"].requireMention 作為預設。
  • @username 比對是可變的,且只有在 channels.mattermost.dangerouslyAllowNameMatching: true 時才會啟用。
  • 開放頻道:channels.mattermost.groupPolicy="open"(以提及作為門檻)。
  • 解析順序:channels.mattermost.groupPolicy,然後是 channels.defaults.groupPolicy,然後是 "allowlist"
  • 執行階段備註:如果完全缺少 channels.mattermost 區段,執行階段會對群組檢查失敗關閉為 groupPolicy="allowlist"(即使已設定 channels.defaults.groupPolicy),並記錄一次性警告。
範例:
{
  channels: {
    mattermost: {
      groupPolicy: "open",
      groups: {
        "*": { requireMention: true },
        "team-channel-id": { requireMention: false },
      },
    },
  },
}

對外傳遞目標

將這些目標格式與 openclaw message send 或排程/網路鉤子搭配使用:
目標傳遞到
channel:<id>依 ID 指定的頻道
channel:<name>#channel-name依名稱指定的頻道,會在 Bot 所屬的團隊中搜尋
user:<id>mattermost:<id>與該使用者的 DM
@usernameDM(透過 Mattermost API 解析使用者名稱)
對外傳送每則訊息最多支援一個附件;請將多個檔案拆分為多次傳送。
裸露的不透明 ID(例如 64ifufp...)在 Mattermost 中是模糊的(使用者 ID 與頻道 ID)。OpenClaw 會使用者優先解析它們:
  • 如果該 ID 作為使用者存在(GET /api/v4/users/<id> 成功),OpenClaw 會透過 /api/v4/channels/direct 解析直接頻道並傳送 DM
  • 否則該 ID 會被視為頻道 ID
如果你需要確定性的行為,請一律使用明確前綴(user:<id> / channel:<id>)。

DM 頻道重試

當 OpenClaw 傳送到 Mattermost DM 目標且需要先解析直接頻道時,預設會重試暫時性的直接頻道建立失敗。 使用 channels.mattermost.dmChannelRetry 為 Mattermost 外掛全域調整該行為,或使用 channels.mattermost.accounts.<id>.dmChannelRetry 為單一帳戶調整。預設值:
{
  channels: {
    mattermost: {
      dmChannelRetry: {
        maxRetries: 3,
        initialDelayMs: 1000,
        maxDelayMs: 10000,
        timeoutMs: 30000,
      },
    },
  },
}
備註:
  • 這只套用於 DM 頻道建立(/api/v4/channels/direct),而不是每個 Mattermost API 呼叫。
  • 重試會使用帶有 jitter 的指數退避,並套用於暫時性失敗,例如速率限制、5xx 回應,以及網路或逾時錯誤。
  • 除了 429 以外的 4xx 用戶端錯誤會被視為永久錯誤,不會重試。

預覽串流

Mattermost 會將思考、工具活動和部分回覆文字串流到單一 草稿預覽貼文,並在最終答案可安全送出時就地定稿。預覽會在同一個貼文 ID 上更新,而不是用逐區塊訊息洗版頻道。媒體/錯誤的最終訊息會取消待處理的預覽編輯,並改用一般傳遞方式,而不是送出一次性的預覽貼文。 預覽串流在 partial 模式中預設啟用。透過 channels.mattermost.streaming 設定(模式字串、布林值,或像 { mode: "progress" } 這樣的物件):
{
  channels: {
    mattermost: {
      streaming: "partial", // off | partial | block | progress
    },
  },
}
  • partial(預設):一則預覽貼文,會隨著回覆增加而編輯,然後以完整答案定稿。
  • block 會在預覽貼文內使用附加樣式的草稿區塊。
  • progress 會在產生期間顯示狀態預覽,並且只在完成時張貼最終答案。
  • off 會停用預覽串流。
  • 如果串流無法就地定稿(例如貼文在串流中途被刪除),OpenClaw 會退回為傳送新的最終貼文,確保回覆不會遺失。
  • 純思考承載內容會從頻道貼文中抑制,包括以 > Thinking 區塊引用抵達的文字。設定 /reasoning on 可在其他介面查看思考;Mattermost 最終貼文只保留答案。
  • 請參閱串流了解頻道對應矩陣。

回應(訊息工具)

  • 使用 message action=react 並搭配 channel=mattermost
  • messageId 是 Mattermost 貼文 ID。
  • emoji 接受像 thumbsup:+1: 這樣的名稱(冒號可省略)。
  • 設定 remove=true(布林值)以移除回應。
  • 回應新增/移除事件會作為系統事件轉發到路由後的代理工作階段,並受與訊息相同的 DM/群組政策檢查約束。
範例:
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

互動式按鈕(訊息工具)

傳送包含可點擊按鈕的訊息。當使用者點擊按鈕時,代理會收到選取項目並可回應。 按鈕來自語義化 presentation 承載內容(在一般代理回覆和 message action=send 中)。OpenClaw 會將值按鈕呈現為 Mattermost 互動式按鈕,讓 URL 按鈕在訊息文字中可見,並將選取選單降級為可讀文字。
message action=send channel=mattermost target=channel:<channelId> presentation={"blocks":[{"type":"buttons","buttons":[{"label":"Yes","value":"yes"},{"label":"No","value":"no"}]}]}
呈現按鈕欄位:
label
string
必填
顯示標籤(別名:text)。
value
string
點擊時送回的值,用作動作 ID(別名:callback_datacallbackData)。除非設定 url,否則可點擊按鈕需要此欄位。
url
string
連結按鈕;在訊息本文中呈現為 label: url 文字,而不是互動式按鈕。
style
"primary" | "secondary" | "success" | "danger"
按鈕樣式。Mattermost 會將預設樣式套用到它不支援的值。
若要在代理系統提示中宣告按鈕支援,請將 inlineButtons 新增至頻道能力:
{
  channels: {
    mattermost: {
      capabilities: ["inlineButtons"],
    },
  },
}
當使用者點擊按鈕時:
1

Access check

點擊者必須通過與訊息傳送者相同的 DM/群組政策檢查;未授權的點擊會收到暫時通知並被忽略。
2

Buttons replaced with confirmation

所有按鈕都會替換為確認行(例如:「✓ Yes selected by @user」)。
3

Agent receives the selection

代理會收到選取項目作為傳入訊息(外加一個系統事件)並回應。
  • 按鈕回呼使用 HMAC-SHA256 驗證(自動執行,不需要設定)。
  • 點擊時會替換整個附件區塊,因此所有按鈕會一起移除,無法部分移除。
  • 包含連字號或底線的動作 ID 會自動清理(Mattermost 路由限制)。
  • action_id 與原始貼文上的動作不符的點擊,會以 403(「Unknown action」)拒絕。
  • channels.mattermost.capabilities:能力字串陣列。新增 "inlineButtons" 可在代理系統提示中啟用按鈕工具描述。
  • channels.mattermost.interactions.callbackBaseUrl:按鈕回呼的選用外部基底 URL(例如 https://gateway.example.com)。當 Mattermost 無法直接透過閘道的繫結主機存取閘道時使用此項。
  • 在多帳號設定中,你也可以在 channels.mattermost.accounts.<id>.interactions.callbackBaseUrl 下設定相同欄位。
  • 如果省略 interactions.callbackBaseUrl,OpenClaw 會從 gateway.customBindHost + gateway.port(預設 18789)衍生回呼 URL,然後退回到 http://localhost:<port>。回呼路徑是 /mattermost/interactions/<accountId>
  • 可達性規則:按鈕回呼 URL 必須可從 Mattermost 伺服器存取。localhost 只有在 Mattermost 和 OpenClaw 在同一主機/網路命名空間上執行時才有效。
  • channels.mattermost.interactions.allowedSourceIps:按鈕回呼的來源 IP 允許清單。若未設定,僅接受回送來源(127.0.0.1::1),因此遠端 Mattermost 伺服器必須在此加入允許清單,否則其點擊會以 403 拒絕。在反向代理後方時,也請設定 gateway.trustedProxies,讓真實用戶端 IP 可從轉發標頭衍生。
  • 如果你的回呼目標是私有/tailnet/內部目標,請將其主機/網域新增到 Mattermost ServiceSettings.AllowedUntrustedInternalConnections

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

外部指令碼和網路鉤子可以透過 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
                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;閘道會拒絕 action_id 不存在於貼文上的點擊。
  6. context.action_id 是必要欄位,缺少它時互動處理器會傳回 400。
  7. 回呼來源 IP 必須被允許(請參閱上方 interactions.allowedSourceIps)。
HMAC 權杖產生 閘道會使用 HMAC-SHA256 驗證按鈕點擊。外部指令碼必須產生符合閘道驗證邏輯的權杖:
1

Derive the secret from the bot token

HMAC-SHA256(key="openclaw-mattermost-interactions", data=botToken),十六進位編碼。
2

Build the context object

建立包含 _token 以外所有欄位的內容物件。
3

Serialize with sorted keys

使用遞迴排序的鍵不含空格序列化(閘道也會將巢狀物件正規化,並產生精簡 JSON)。
4

Sign the payload

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

Add the token

將產生的十六進位摘要作為 _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)。閘道會移除 _token,然後簽署其餘所有內容。簽署子集會造成靜默驗證失敗。
  • 使用 sort_keys=True,閘道會在簽署前排序鍵,而 Mattermost 在儲存承載內容時可能會重新排序內容欄位。
  • 從 Bot 權杖衍生密鑰(決定性),不要使用隨機位元組。建立按鈕的程序和驗證的閘道必須使用相同密鑰。

目錄配接器

Mattermost 外掛包含一個目錄配接器,可透過 Mattermost API 解析頻道和使用者名稱。這會在 openclaw message send 以及排程/網路鉤子傳遞中啟用 #channel-name@username 目標。 不需要設定,配接器會使用帳號設定中的 Bot 權杖。

多帳號

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" },
      },
    },
  },
}
帳號值會覆寫頂層欄位;channels.mattermost.defaultAccount 會選擇在未指定帳號時使用哪個帳號。

疑難排解

確認 Bot 已在頻道中並提及它(oncall)、使用觸發前綴(onchar),或設定 chatmode: "onmessage"
  • 檢查 Bot 權杖、基底 URL,以及帳號是否已啟用。
  • 多帳號問題:環境變數只會套用到 default 帳號。
  • 私有/LAN Mattermost 主機需要 network.dangerouslyAllowPrivateNetwork: true(SSRF 防護預設會封鎖私有 IP)。
  • Unauthorized: invalid command token.:OpenClaw 未接受回呼權杖。典型原因:
    • 斜線命令註冊在啟動時失敗或只部分完成
    • 回呼打到錯誤的閘道/帳號
    • Mattermost 仍有指向先前回呼目標的舊命令
    • 閘道重新啟動後未重新啟用斜線命令
  • 如果原生斜線命令停止運作,請檢查日誌中是否有 mattermost: failed to register slash commandsmattermost: native slash commands enabled but no commands could be registered
  • 如果省略 callbackUrl,且日誌警告回呼解析為像 http://localhost:18789/... 這樣的 loopback URL,該 URL 可能只有在 Mattermost 與 OpenClaw 在同一主機/網路命名空間執行時才能連線。請改為設定明確且可從外部連線的 commands.callbackUrl
  • 按鈕顯示為白色方框或完全不顯示:按鈕資料格式錯誤。每個呈現按鈕都需要 labelvalue(缺少任一者的按鈕都會被丟棄)。
  • 按鈕有呈現但點擊沒有反應:請確認 Mattermost 伺服器能連線到閘道、Mattermost 伺服器 IP 已包含在 channels.mattermost.interactions.allowedSourceIps 中(未設定時只接受 loopback),且 ServiceSettings.AllowedUntrustedInternalConnections 包含私有目標的回呼主機。
  • 按鈕點擊時回傳 404:按鈕 id 可能包含連字號或底線。Mattermost 的動作路由器會在非英數字元的 ID 上失效。只使用 [a-zA-Z0-9]
  • 閘道日誌顯示 rejected callback source:點擊來自 interactions.allowedSourceIps 之外的 IP。將 Mattermost 伺服器或你的入口加入允許清單,並在反向代理後方設定 gateway.trustedProxies
  • 閘道日誌顯示 invalid _token:HMAC 不相符。請確認你簽署所有脈絡欄位(不是子集)、使用排序後的鍵,並使用精簡 JSON(無空格)。請參閱上方 HMAC 章節。
  • 閘道日誌顯示 missing _token in context_token 欄位不在按鈕的脈絡中。請確保建立整合酬載時包含它。
  • 閘道以 Unknown action 拒絕點擊:context.action_id 不符合貼文上任何動作 id。將兩者設定為相同的清理後值。
  • Agent 未提供按鈕:在 Mattermost 頻道設定中加入 capabilities: ["inlineButtons"]

相關