Mainstream messaging

Slack

可透過 Slack 應用程式整合,在 DM 和頻道中達到生產環境可用。預設模式為 Socket Mode;也支援 HTTP Request URLs。

選擇 Socket Mode 或 HTTP Request URLs

兩種傳輸方式都已可用於生產環境,並且在訊息、slash commands、App Home 和互動功能上達到功能一致。請依部署型態選擇,而不是依功能選擇。

考量 Socket Mode(預設) HTTP Request URLs
公開 Gateway URL 不需要 需要(DNS、TLS、反向代理或通道)
輸出網路 必須能連到 wss-primary.slack.com 的輸出 WSS 無輸出 WS;僅限輸入 HTTPS
需要的 Token Bot token (xoxb-...) + 具備 connections:write 的 App-Level Token (xapp-...) Bot token (xoxb-...) + Signing Secret
開發筆電 / 位於防火牆後方 可直接運作 需要公開通道(ngrok、Cloudflare Tunnel、Tailscale Funnel)或預備環境 Gateway
水平擴充 每個 app 每台主機一個 Socket Mode 工作階段;多個 Gateways 需要個別 Slack apps 無狀態 POST 處理常式;多個 Gateway 複本可在負載平衡器後共用同一個 app
單一 Gateway 上的多帳號 支援;每個帳號會開啟自己的 WS 支援;每個帳號都需要唯一的 webhookPath(預設 /slack/events),避免註冊衝突
Slash command 傳輸 透過 WS 連線遞送;會忽略 slash_commands[].url Slack 會 POST 至 slash_commands[].url;此欄位為命令分派的必要欄位
請求簽署 不使用(驗證使用 App-Level Token) Slack 會簽署每個請求;OpenClaw 使用 signingSecret 驗證
連線中斷復原 Slack SDK 會自動重新連線;會套用 gateway 的 pong-timeout 傳輸調校 沒有會中斷的持久連線;重試由 Slack 逐請求處理

快速設定

Socket Mode (default)

  • Create a new Slack app

    開啟 api.slack.com/appsCreate New AppFrom a manifest → 選取你的工作區 → 貼上下方其中一份 manifest → NextCreate

    Recommended
    {"display_information": {"name": "OpenClaw","description": "Slack connector for OpenClaw"},"features": {"bot_user": { "display_name": "OpenClaw", "always_online": true },"app_home": {"home_tab_enabled": true,"messages_tab_enabled": true,"messages_tab_read_only_enabled": false},"slash_commands": [{"command": "/openclaw","description": "Send a message to OpenClaw","should_escape": false}]},"oauth_config": {"scopes": {"bot": ["app_mentions:read","assistant:write","channels:history","channels:read","chat:write","commands","emoji:read","files:read","files:write","groups:history","groups:read","im:history","im:read","im:write","mpim:history","mpim:read","mpim:write","pins:read","pins:write","reactions:read","reactions:write","usergroups:read","users:read"]}},"settings": {"socket_mode_enabled": true,"event_subscriptions": {"bot_events": ["app_home_opened","app_mention","channel_rename","member_joined_channel","member_left_channel","message.channels","message.groups","message.im","message.mpim","pin_added","pin_removed","reaction_added","reaction_removed"]}}}
    Minimal
    {"display_information": {"name": "OpenClaw","description": "Slack connector for OpenClaw"},"features": {"bot_user": { "display_name": "OpenClaw", "always_online": true },"app_home": {"home_tab_enabled": true,"messages_tab_enabled": true,"messages_tab_read_only_enabled": false},"slash_commands": [{"command": "/openclaw","description": "Send a message to OpenClaw","should_escape": false}]},"oauth_config": {"scopes": {"bot": ["app_mentions:read","assistant:write","channels:history","channels:read","chat:write","commands","groups:history","groups:read","im:history","im:read","im:write","users:read"]}},"settings": {"socket_mode_enabled": true,"event_subscriptions": {"bot_events": ["app_home_opened","app_mention","message.channels","message.groups","message.im"]}}}

    Slack 建立 app 後:

    • Basic Information → App-Level Tokens → Generate Token and Scopes:新增 connections:write、儲存,並複製 xapp-... 值。
    • Install App → Install to Workspace:複製 xoxb-... Bot User OAuth Token。
  • Configure OpenClaw

    建議的 SecretRef 設定:

    bash
    export SLACK_APP_TOKEN=xapp-...export SLACK_BOT_TOKEN=xoxb-...cat > slack.socket.patch.json5 <<'JSON5'{channels: {slack: {enabled: true,mode: "socket",appToken: { source: "env", provider: "default", id: "SLACK_APP_TOKEN" },botToken: { source: "env", provider: "default", id: "SLACK_BOT_TOKEN" },},},}JSON5openclaw config patch --file ./slack.socket.patch.json5 --dry-runopenclaw config patch --file ./slack.socket.patch.json5

    Env 備援(僅限預設帳號):

    bash
    SLACK_APP_TOKEN=xapp-...SLACK_BOT_TOKEN=xoxb-...
  • Start gateway

    bash
    openclaw gateway
  • HTTP Request URLs

  • Create a new Slack app

    開啟 api.slack.com/appsCreate New AppFrom a manifest → 選取你的工作區 → 貼上下方其中一份 manifest → 將 https://gateway-host.example.com/slack/events 替換為你的公開 Gateway URL → NextCreate

    Recommended
    {"display_information": {"name": "OpenClaw","description": "Slack connector for OpenClaw"},"features": {"bot_user": { "display_name": "OpenClaw", "always_online": true },"app_home": {"home_tab_enabled": true,"messages_tab_enabled": true,"messages_tab_read_only_enabled": false},"slash_commands": [{"command": "/openclaw","description": "Send a message to OpenClaw","should_escape": false,"url": "https://gateway-host.example.com/slack/events"}]},"oauth_config": {"scopes": {"bot": ["app_mentions:read","assistant:write","channels:history","channels:read","chat:write","commands","emoji:read","files:read","files:write","groups:history","groups:read","im:history","im:read","im:write","mpim:history","mpim:read","mpim:write","pins:read","pins:write","reactions:read","reactions:write","usergroups:read","users:read"]}},"settings": {"event_subscriptions": {"request_url": "https://gateway-host.example.com/slack/events","bot_events": ["app_home_opened","app_mention","channel_rename","member_joined_channel","member_left_channel","message.channels","message.groups","message.im","message.mpim","pin_added","pin_removed","reaction_added","reaction_removed"]},"interactivity": {"is_enabled": true,"request_url": "https://gateway-host.example.com/slack/events","message_menu_options_url": "https://gateway-host.example.com/slack/events"}}}
    Minimal
    {"display_information": {"name": "OpenClaw","description": "Slack connector for OpenClaw"},"features": {"bot_user": { "display_name": "OpenClaw", "always_online": true },"app_home": {"home_tab_enabled": true,"messages_tab_enabled": true,"messages_tab_read_only_enabled": false},"slash_commands": [{"command": "/openclaw","description": "Send a message to OpenClaw","should_escape": false,"url": "https://gateway-host.example.com/slack/events"}]},"oauth_config": {"scopes": {"bot": ["app_mentions:read","assistant:write","channels:history","channels:read","chat:write","commands","groups:history","groups:read","im:history","im:read","im:write","users:read"]}},"settings": {"event_subscriptions": {"request_url": "https://gateway-host.example.com/slack/events","bot_events": ["app_home_opened","app_mention","message.channels","message.groups","message.im"]},"interactivity": {"is_enabled": true,"request_url": "https://gateway-host.example.com/slack/events","message_menu_options_url": "https://gateway-host.example.com/slack/events"}}}

    Slack 建立應用程式後:

    • Basic Information → App Credentials:複製 Signing Secret 以進行請求驗證。
    • Install App → Install to Workspace:複製 xoxb-... Bot User OAuth Token。
  • Configure OpenClaw

    建議的 SecretRef 設定:

    bash
    export SLACK_BOT_TOKEN=xoxb-...export SLACK_SIGNING_SECRET=...cat > slack.http.patch.json5 <<'JSON5'{channels: {slack: {enabled: true,mode: "http",botToken: { source: "env", provider: "default", id: "SLACK_BOT_TOKEN" },signingSecret: { source: "env", provider: "default", id: "SLACK_SIGNING_SECRET" },webhookPath: "/slack/events",},},}JSON5openclaw config patch --file ./slack.http.patch.json5 --dry-runopenclaw config patch --file ./slack.http.patch.json5
  • Start gateway

    bash
    openclaw gateway
  • Socket Mode 傳輸調校

    OpenClaw 預設會將 Socket Mode 的 Slack SDK 用戶端 pong 逾時設為 15 秒。只有在需要針對工作區或主機做特定調校時,才覆寫傳輸設定:

    json5
    {  channels: {    slack: {      mode: "socket",      socketMode: {        clientPingTimeout: 20000,        serverPingTimeout: 30000,        pingPongLoggingEnabled: false,      },    },  },}

    只有在 Socket Mode 工作區記錄 Slack websocket pong/server-ping 逾時,或執行於已知事件迴圈飢餓的主機上時,才使用此設定。clientPingTimeout 是 SDK 傳送用戶端 ping 後等待 pong 的時間;serverPingTimeout 是等待 Slack 伺服器 ping 的時間。應用程式訊息和事件仍屬於應用程式狀態,不是傳輸存活訊號。

    資訊清單與 scope 檢查清單

    基礎 Slack 應用程式資訊清單對 Socket Mode 和 HTTP Request URLs 都相同。只有 settings 區塊(以及斜線命令 url)不同。

    基礎資訊清單(Socket Mode 預設):

    json
    {  "display_information": {    "name": "OpenClaw",    "description": "Slack connector for OpenClaw"  },  "features": {    "bot_user": { "display_name": "OpenClaw", "always_online": true },    "app_home": {      "home_tab_enabled": true,      "messages_tab_enabled": true,      "messages_tab_read_only_enabled": false    },    "slash_commands": [      {        "command": "/openclaw",        "description": "Send a message to OpenClaw",        "should_escape": false      }    ]  },  "oauth_config": {    "scopes": {      "bot": [        "app_mentions:read",        "assistant:write",        "channels:history",        "channels:read",        "chat:write",        "commands",        "emoji:read",        "files:read",        "files:write",        "groups:history",        "groups:read",        "im:history",        "im:read",        "im:write",        "mpim:history",        "mpim:read",        "mpim:write",        "pins:read",        "pins:write",        "reactions:read",        "reactions:write",        "usergroups:read",        "users:read"      ]    }  },  "settings": {    "socket_mode_enabled": true,    "event_subscriptions": {      "bot_events": [        "app_home_opened",        "app_mention",        "channel_rename",        "member_joined_channel",        "member_left_channel",        "message.channels",        "message.groups",        "message.im",        "message.mpim",        "pin_added",        "pin_removed",        "reaction_added",        "reaction_removed"      ]    }  }}

    對於 HTTP Request URLs 模式,請以 HTTP 變體取代 settings,並將 url 加到每個斜線命令。需要公開 URL:

    json
    {  "features": {    "slash_commands": [      {        "command": "/openclaw",        "description": "Send a message to OpenClaw",        "should_escape": false,        "url": "https://gateway-host.example.com/slack/events"      }    ]  },  "settings": {    "event_subscriptions": {      "request_url": "https://gateway-host.example.com/slack/events",      "bot_events": [        "app_home_opened",        "app_mention",        "channel_rename",        "member_joined_channel",        "member_left_channel",        "message.channels",        "message.groups",        "message.im",        "message.mpim",        "pin_added",        "pin_removed",        "reaction_added",        "reaction_removed"      ]    },    "interactivity": {      "is_enabled": true,      "request_url": "https://gateway-host.example.com/slack/events",      "message_menu_options_url": "https://gateway-host.example.com/slack/events"    }  }}

    其他資訊清單設定

    呈現可延伸上述預設值的不同功能。

    預設資訊清單會啟用 Slack App Home 的 Home 分頁,並訂閱 app_home_opened。當工作區成員開啟 Home 分頁時,OpenClaw 會使用 views.publish 發佈安全的預設 Home 檢視;不會包含對話 payload 或私密設定。Messages 分頁仍會為 Slack 私訊啟用。

    Optional native slash commands

    可使用多個原生斜線命令取代單一已設定命令,但有以下細節:

    • 使用 /agentstatus 而不是 /status,因為 /status 命令是保留命令。
    • 一次最多只能提供 25 個斜線命令。

    將現有的 features.slash_commands 區段取代為可用命令的子集:

    Socket Mode (default)

    json
    {"slash_commands": [{"command": "/new","description": "Start a new session","usage_hint": "[model]"},{"command": "/reset","description": "Reset the current session"},{"command": "/compact","description": "Compact the session context","usage_hint": "[instructions]"},{"command": "/stop","description": "Stop the current run"},{"command": "/session","description": "Manage thread-binding expiry","usage_hint": "idle <duration|off> or max-age <duration|off>"},{"command": "/think","description": "Set the thinking level","usage_hint": "<level>"},{"command": "/verbose","description": "Toggle verbose output","usage_hint": "on|off|full"},{"command": "/fast","description": "Show or set fast mode","usage_hint": "[status|on|off]"},{"command": "/reasoning","description": "Toggle reasoning visibility","usage_hint": "[on|off|stream]"},{"command": "/elevated","description": "Toggle elevated mode","usage_hint": "[on|off|ask|full]"},{"command": "/exec","description": "Show or set exec defaults","usage_hint": "host=<auto|sandbox|gateway|node> security=<deny|allowlist|full> ask=<off|on-miss|always> node=<id>"},{"command": "/model","description": "Show or set the model","usage_hint": "[name|#|status]"},{"command": "/models","description": "List providers/models","usage_hint": "[provider] [page] [limit=<n>|size=<n>|all]"},{"command": "/help","description": "Show the short help summary"},{"command": "/commands","description": "Show the generated command catalog"},{"command": "/tools","description": "Show what the current agent can use right now","usage_hint": "[compact|verbose]"},{"command": "/agentstatus","description": "Show runtime status, including provider usage/quota when available"},{"command": "/tasks","description": "List active/recent background tasks for the current session"},{"command": "/context","description": "Explain how context is assembled","usage_hint": "[list|detail|json]"},{"command": "/whoami","description": "Show your sender identity"},{"command": "/skill","description": "Run a skill by name","usage_hint": "<name> [input]"},{"command": "/btw","description": "Ask a side question without changing session context","usage_hint": "<question>"},{"command": "/side","description": "Ask a side question without changing session context","usage_hint": "<question>"},{"command": "/usage","description": "Control the usage footer or show cost summary","usage_hint": "off|tokens|full|cost"}]}

    HTTP Request URLs

    使用與上方 Socket Mode 相同的 slash_commands 清單,並將 "url": "https://gateway-host.example.com/slack/events" 加到每個項目。例如:

    json
    {"slash_commands": [{"command": "/new","description": "Start a new session","usage_hint": "[model]","url": "https://gateway-host.example.com/slack/events"},{"command": "/help","description": "Show the short help summary","url": "https://gateway-host.example.com/slack/events"}]}

    在清單中的每個命令都重複該 url 值。

    選用的作者身分範圍(寫入操作)

    如果你希望外送訊息使用作用中代理程式身分(自訂使用者名稱與圖示),而不是預設的 Slack app 身分,請加入 chat:write.customize bot 範圍。

    如果你使用 emoji 圖示,Slack 會預期採用 :emoji_name: 語法。

    選用的使用者權杖範圍(讀取操作)

    如果你設定 channels.slack.userToken,典型的讀取範圍為:

    • channels:history, groups:history, im:history, mpim:history
    • channels:read, groups:read, im:read, mpim:read
    • users:read
    • reactions:read
    • pins:read
    • emoji:read
    • search:read(如果你依賴 Slack 搜尋讀取)

    權杖模型

    • botToken + appToken 是 Socket Mode 的必要項目。
    • HTTP 模式需要 botToken + signingSecret
    • botTokenappTokensigningSecretuserToken 可接受明文 字串或 SecretRef 物件。
    • 設定權杖會覆寫 env 後援。
    • SLACK_BOT_TOKEN / SLACK_APP_TOKEN env 後援只套用至預設帳戶。
    • userToken (xoxp-...) 僅能透過設定提供(沒有 env 後援),且預設為唯讀行為(userTokenReadOnly: true)。

    狀態快照行為:

    • Slack 帳戶檢查會追蹤每個憑證的 *Source*Status 欄位(botTokenappTokensigningSecretuserToken)。
    • 狀態為 availableconfigured_unavailablemissing
    • configured_unavailable 表示帳戶已透過 SecretRef 或其他非內嵌秘密來源設定,但目前的命令/執行階段路徑 無法解析實際值。
    • 在 HTTP 模式中,會包含 signingSecretStatus;在 Socket Mode 中, 必要配對是 botTokenStatus + appTokenStatus

    動作與門檻

    Slack 動作由 channels.slack.actions.* 控制。

    目前 Slack 工具中可用的動作群組:

    群組 預設
    訊息 已啟用
    回應 已啟用
    釘選 已啟用
    成員資訊 已啟用
    emoji 清單 已啟用

    目前 Slack 訊息動作包含 sendupload-filedownload-filereadeditdeletepinunpinlist-pinsmember-infoemoji-listdownload-file 接受入站檔案預留位置中顯示的 Slack 檔案 ID,並針對圖片回傳圖片預覽,或針對其他檔案類型回傳本機檔案中繼資料。

    存取控制與路由

    DM 政策

    channels.slack.dmPolicy 控制 DM 存取。channels.slack.allowFrom 是正式的 DM 允許清單。

    • pairing(預設)
    • allowlist
    • open(需要 channels.slack.allowFrom 包含 "*"
    • disabled

    DM 旗標:

    • dm.enabled(預設為 true)
    • channels.slack.allowFrom
    • dm.allowFrom(舊版)
    • dm.groupEnabled(群組 DM 預設為 false)
    • dm.groupChannels(選用 MPIM 允許清單)

    多帳戶優先順序:

    • channels.slack.accounts.default.allowFrom 只套用至 default 帳戶。
    • 已命名帳戶在自身 allowFrom 未設定時,會繼承 channels.slack.allowFrom
    • 已命名帳戶不會繼承 channels.slack.accounts.default.allowFrom

    舊版 channels.slack.dm.policychannels.slack.dm.allowFrom 仍會為了相容性而讀取。openclaw doctor --fix 在可不改變存取權的情況下,會將它們遷移至 dmPolicyallowFrom

    DM 中的配對使用 openclaw pairing approve slack <code>

    頻道政策

    channels.slack.groupPolicy 控制頻道處理:

    • open
    • allowlist
    • disabled

    頻道允許清單位於 channels.slack.channels 下,且必須使用穩定的 Slack 頻道 ID(例如 C12345678)作為設定鍵。

    執行階段注意事項:如果完全缺少 channels.slack(僅 env 設定),執行階段會後援為 groupPolicy="allowlist" 並記錄警告(即使已設定 channels.defaults.groupPolicy)。

    名稱/ID 解析:

    • 頻道允許清單項目和 DM 允許清單項目會在啟動時,在權杖存取允許的情況下解析
    • 無法解析的頻道名稱項目會保留其設定,但預設會在路由中忽略
    • 入站授權和頻道路由預設以 ID 優先;直接的使用者名稱/slug 比對需要 channels.slack.dangerouslyAllowNameMatching: true

    提及與頻道使用者

    頻道訊息預設受提及門檻控管。

    提及來源:

    • 明確的 app 提及(<@botId>
    • 當 bot 使用者是該使用者群組成員時的 Slack 使用者群組提及(<!subteam^S...>);需要 usergroups:read
    • 提及 regex 模式(agents.list[].groupChat.mentionPatterns,後援為 messages.groupChat.mentionPatterns
    • 隱含的回覆 bot 執行緒行為(當 thread.requireExplicitMentiontrue 時停用)

    每頻道控制(channels.slack.channels.<id>;名稱只能透過啟動解析或 dangerouslyAllowNameMatching 使用):

    • requireMention
    • users(允許清單)
    • allowBots
    • skills
    • systemPrompt
    • tools, toolsBySender
    • toolsBySender 鍵格式:channel:id:e164:username:name:,或 "*" 萬用字元 (舊版未加前綴的鍵仍只會對應至 id:

    對於頻道和私人頻道,allowBots 採保守策略:只有在傳送 bot 明確列於該聊天室的 users 允許清單中,或目前至少有一個來自 channels.slack.allowFrom 的明確 Slack 擁有者 ID 是聊天室成員時,才會接受由 bot 撰寫的聊天室訊息。萬用字元和顯示名稱擁有者項目不符合擁有者存在條件。擁有者存在使用 Slack conversations.members;請確保 app 具備符合該聊天室類型的讀取範圍(公開頻道為 channels:read,私人頻道為 groups:read)。如果成員查詢失敗,OpenClaw 會丟棄由 bot 撰寫的聊天室訊息。

    執行緒、工作階段與回覆標籤

    • DM 路由為 direct;頻道路由為 channel;MPIM 路由為 group
    • Slack 路由繫結接受原始對等 ID,以及 Slack 目標形式,例如 channel:C12345678user:U12345678<@U12345678>
    • 使用預設 session.dmScope=main 時,Slack DM 會收斂至代理程式主工作階段。
    • 頻道工作階段:agent:<agentId>:slack:channel:<channelId>
    • 適用時,執行緒回覆可建立執行緒工作階段後綴(:thread:<threadTs>)。
    • 在 OpenClaw 不需要明確提及即可處理頂層訊息的頻道中,非 offreplyToMode 會將每個已處理的根訊息路由至 agent:<agentId>:slack:channel:<channelId>:thread:<rootTs>,讓可見的 Slack 執行緒從第一輪開始對應到一個 OpenClaw 工作階段。
    • channels.slack.thread.historyScope 預設為 threadthread.inheritParent 預設為 false
    • channels.slack.thread.initialHistoryLimit 控制新執行緒工作階段啟動時,要擷取多少既有執行緒訊息(預設 20;設為 0 可停用)。
    • channels.slack.thread.requireExplicitMention(預設 false):當為 true 時,會抑制隱含執行緒提及,因此即使 bot 已參與該執行緒,bot 也只會回應執行緒內明確的 @bot 提及。若沒有此設定,bot 已參與執行緒中的回覆會略過 requireMention 門檻。

    回覆執行緒控制:

    • channels.slack.replyToMode: off|first|all|batched(預設 off
    • channels.slack.replyToModeByChatType: 針對每個 direct|group|channel
    • 直接聊天的舊版後援:channels.slack.dm.replyToMode

    支援手動回覆標籤:

    • [[reply_to_current]]
    • [[reply_to:<id>]]

    若要從 message 工具明確傳送 Slack 執行緒回覆,請搭配 action: "send"threadIdreplyTo 設定 replyBroadcast: true,要求 Slack 也將執行緒回覆廣播到上層頻道。這會對應至 Slack 的 chat.postMessage reply_broadcast 旗標,且僅支援文字或 Block Kit 傳送,不支援媒體上傳。

    message 工具呼叫在 Slack 執行緒內執行且目標為同一個頻道時,OpenClaw 通常會根據 replyToMode 繼承目前的 Slack 執行緒。在 action: "send"action: "upload-file" 上設定 topLevel: true,可強制傳送新的上層頻道訊息。threadId: null 也會被接受為相同的頂層退出選項。

    確認回應

    ackReaction 會在 OpenClaw 處理入站訊息時傳送確認 emoji。

    解析順序:

    • channels.slack.accounts.<accountId>.ackReaction
    • channels.slack.ackReaction
    • messages.ackReaction
    • 代理程式身分 emoji 後援(agents.list[].identity.emoji,否則為 "👀")

    注意事項:

    • Slack 預期使用短碼(例如 "eyes")。
    • 使用 "" 可停用 Slack 帳戶或全域的回應。

    文字串流

    channels.slack.streaming 控制即時預覽行為:

    • off:停用即時預覽串流。
    • partial(預設):以最新的部分輸出取代預覽文字。
    • block:附加分塊預覽更新。
    • progress:產生期間顯示進度狀態文字,然後傳送最終文字。
    • streaming.preview.toolProgress:草稿預覽啟用時,將工具/進度更新路由到同一則已編輯預覽訊息(預設:true)。設為 false 可保留個別工具/進度訊息。
    • streaming.preview.commandText / streaming.progress.commandText:設為 status 可在隱藏原始 command/exec 文字的同時,保留精簡工具進度行(預設:raw)。

    隱藏原始 command/exec 文字,同時保留精簡進度行:

    json
    {  "channels": {    "slack": {      "streaming": {        "mode": "progress",        "progress": {          "toolProgress": true,          "commandText": "status"        }      }    }  }}

    channels.slack.streaming.modepartial 時,channels.slack.streaming.nativeTransport 會控制 Slack 原生文字串流(預設:true)。

    • 必須有可用的回覆執行緒,原生文字串流和 Slack assistant 執行緒狀態才會顯示。執行緒選擇仍會遵循 replyToMode
    • 當原生串流不可用,或沒有回覆執行緒時,頻道、群組聊天和頂層 DM 根仍可使用一般草稿預覽。
    • 頂層 Slack DM 預設保持不進入執行緒,因此不會顯示 Slack 執行緒樣式的原生串流/狀態預覽;OpenClaw 會改為在 DM 中發佈並編輯草稿預覽。
    • 媒體和非文字承載內容會回退到一般傳遞。
    • 媒體/錯誤最終內容會取消待處理的預覽編輯;符合條件的文字/區塊最終內容只會在能就地編輯預覽時才會清空送出。
    • 如果串流在回覆中途失敗,OpenClaw 會對剩餘承載內容回退到一般傳遞。

    使用草稿預覽,而不是 Slack 原生文字串流:

    json5
    {  channels: {    slack: {      streaming: {        mode: "partial",        nativeTransport: false,      },    },  },}

    舊版鍵:

    • channels.slack.streamMode (replace | status_final | append) 是 channels.slack.streaming.mode 的舊版執行階段別名。
    • 布林值 channels.slack.streamingchannels.slack.streaming.modechannels.slack.streaming.nativeTransport 的舊版執行階段別名。
    • 舊版 channels.slack.nativeStreamingchannels.slack.streaming.nativeTransport 的執行階段別名。
    • 執行 openclaw doctor --fix,將已保存的 Slack 串流設定重寫為標準鍵。

    輸入中反應備援

    typingReaction 會在 OpenClaw 處理回覆時,向傳入的 Slack 訊息加入暫時反應,並在執行完成時移除。這在執行緒回覆之外最有用,因為執行緒回覆會使用預設的「正在輸入...」狀態指示器。

    解析順序:

    • channels.slack.accounts.<accountId>.typingReaction
    • channels.slack.typingReaction

    注意事項:

    • Slack 預期使用短代碼(例如 "hourglass_flowing_sand")。
    • 反應採盡力而為,並會在回覆或失敗路徑完成後自動嘗試清理。

    媒體、分塊與傳遞

    Inbound attachments

    Slack 檔案附件會從 Slack 託管的私人 URL 下載(權杖驗證請求流程),並在擷取成功且大小限制允許時寫入媒體儲存區。檔案預留位置包含 Slack fileId,因此 agent 可使用 download-file 擷取原始檔案。

    下載會使用有界限的閒置和總逾時。如果 Slack 檔案擷取停滯或失敗,OpenClaw 會繼續處理訊息,並回退到檔案預留位置。

    執行階段傳入大小上限預設為 20MB,除非由 channels.slack.mediaMaxMb 覆寫。

    Outbound text and files
    • 文字分塊使用 channels.slack.textChunkLimit(預設 4000)
    • channels.slack.chunkMode="newline" 啟用段落優先分割
    • 檔案傳送使用 Slack 上傳 API,並可包含執行緒回覆(thread_ts
    • 已設定時,傳出媒體上限會遵循 channels.slack.mediaMaxMb;否則頻道傳送會使用媒體管線中的 MIME 種類預設值
    Delivery targets

    偏好的明確目標:

    • user:<id> 用於 DM
    • channel:<id> 用於頻道

    僅含文字/區塊的 Slack DM 可直接發佈到使用者 ID;檔案上傳和執行緒傳送會先透過 Slack conversation API 開啟 DM,因為這些路徑需要具體的對話 ID。

    指令與斜線行為

    斜線指令在 Slack 中會顯示為單一已設定指令或多個原生指令。設定 channels.slack.slashCommand 以變更指令預設值:

    • enabled: false
    • name: "openclaw"
    • sessionPrefix: "slack:slash"
    • ephemeral: true
    txt
    /openclaw /help

    原生指令需要在你的 Slack app 中使用額外 manifest 設定,並改由 channels.slack.commands.native: true 啟用,或在全域設定中使用 commands.native: true 啟用。

    • Slack 的原生指令自動模式為關閉,因此 commands.native: "auto" 不會啟用 Slack 原生指令。
    txt
    /help

    原生引數選單使用自適應轉譯策略,會在分派所選選項值之前顯示確認互動視窗:

    • 最多 5 個選項:按鈕區塊
    • 6-100 個選項:靜態選取選單
    • 超過 100 個選項:當 interactivity 選項處理常式可用時,使用具非同步選項篩選的外部選取
    • 超出 Slack 限制:編碼後的選項值會回退為按鈕
    txt
    /think

    斜線工作階段使用像 agent:<agentId>:slack:slash:<userId> 這樣的隔離鍵,並仍會使用 CommandTargetSessionKey 將指令執行路由到目標對話工作階段。

    互動式回覆

    Slack 可以轉譯 agent 撰寫的互動式回覆控制項,但此功能預設為停用。

    全域啟用:

    json5
    {  channels: {    slack: {      capabilities: {        interactiveReplies: true,      },    },  },}

    或僅為一個 Slack 帳戶啟用:

    json5
    {  channels: {    slack: {      accounts: {        ops: {          capabilities: {            interactiveReplies: true,          },        },      },    },  },}

    啟用後,代理可以發出僅限 Slack 的回覆指令:

    • [[slack_buttons: Approve:approve, Reject:reject]]
    • [[slack_select: Choose a target | Canary:canary, Production:production]]

    這些指令會編譯成 Slack Block Kit,並透過既有的 Slack 互動事件路徑路由點擊或選取。

    注意:

    • 這是 Slack 專用 UI。其他通道不會將 Slack Block Kit 指令轉譯成自己的按鈕系統。
    • 互動回呼值是 OpenClaw 產生的不透明權杖,而不是代理撰寫的原始值。
    • 如果產生的互動區塊會超過 Slack Block Kit 限制,OpenClaw 會退回原始文字回覆,而不是傳送無效的 blocks payload。

    Slack 中的 exec 核准

    Slack 可以作為具備互動按鈕與互動的原生核准用戶端,而不是退回 Web UI 或終端機。

    • Exec 核准使用 channels.slack.execApprovals.* 進行原生 DM/頻道路由。
    • 當請求已經落在 Slack 中,且核准 id 種類為 plugin: 時,Plugin 核准仍可透過相同的 Slack 原生按鈕介面解析。
    • 仍會強制執行核准者授權:只有識別為核准者的使用者可以透過 Slack 核准或拒絕請求。

    這使用與其他通道相同的共用核准按鈕介面。當你的 Slack app 設定中啟用 interactivity 時,核准提示會直接在對話中呈現為 Block Kit 按鈕。 當這些按鈕存在時,它們就是主要核准 UX;OpenClaw 只有在工具結果表示聊天核准無法使用,或手動核准是唯一途徑時, 才應包含手動 /approve 指令。

    組態路徑:

    • channels.slack.execApprovals.enabled
    • channels.slack.execApprovals.approvers(可選;可行時會退回 commands.ownerAllowFrom
    • channels.slack.execApprovals.targetdm | channel | both,預設值:dm
    • agentFiltersessionFilter

    enabled 未設定或為 "auto",且至少解析出一位核准者時,Slack 會自動啟用原生 exec 核准。設定 enabled: false 可明確停用 Slack 作為原生核准用戶端。 設定 enabled: true 可在解析出核准者時強制開啟原生核准。

    沒有明確 Slack exec 核准組態時的預設行為:

    json5
    {  commands: {    ownerAllowFrom: ["slack:U12345678"],  },}

    只有在你想覆寫核准者、新增篩選器,或 選擇加入來源聊天傳遞時,才需要明確的 Slack 原生組態:

    json5
    {  channels: {    slack: {      execApprovals: {        enabled: true,        approvers: ["U12345678"],        target: "both",      },    },  },}

    共用的 approvals.exec 轉發是分開的。只有當 exec 核准提示也必須 路由到其他聊天或明確的頻外目標時才使用它。共用的 approvals.plugin 轉發也是 分開的;當這些請求已經落在 Slack 中時,Slack 原生按鈕仍可解析 Plugin 核准。

    同一聊天中的 /approve 也可在已支援指令的 Slack 頻道與 DM 中運作。請參閱 Exec 核准,了解完整的核准轉發模型。

    事件與操作行為

    • 訊息編輯/刪除會對應成系統事件。
    • 執行緒廣播(「也傳送到頻道」的執行緒回覆)會作為一般使用者訊息處理。
    • 新增/移除反應事件會對應成系統事件。
    • 成員加入/離開、頻道建立/重新命名,以及新增/移除釘選事件會對應成系統事件。
    • 啟用 configWrites 時,channel_id_changed 可以遷移頻道組態鍵。
    • 頻道主題/用途中繼資料會被視為不受信任的脈絡,並可注入路由脈絡。
    • 適用時,執行緒起始訊息與初始執行緒歷史脈絡種子會依設定的寄件者允許清單篩選。
    • 區塊動作與 modal 互動會發出結構化的 Slack interaction: ... 系統事件,並包含豐富的 payload 欄位:
      • 區塊動作:選取值、標籤、選擇器值,以及 workflow_* 中繼資料
      • modal view_submissionview_closed 事件,包含已路由頻道中繼資料與表單輸入

    組態參考

    主要參考:組態參考 - Slack

    高訊號 Slack 欄位
    • 模式/驗證:modebotTokenappTokensigningSecretwebhookPathaccounts.*
    • DM 存取:dm.enableddmPolicyallowFrom(舊版:dm.policydm.allowFrom)、dm.groupEnableddm.groupChannels
    • 相容性切換:dangerouslyAllowNameMatching(緊急破窗;除非需要,否則保持關閉)
    • 頻道存取:groupPolicychannels.*channels.*.userschannels.*.requireMention
    • 執行緒/歷史:replyToModereplyToModeByChatTypethread.*historyLimitdmHistoryLimitdms.*.historyLimit
    • 傳遞:textChunkLimitchunkModemediaMaxMbstreamingstreaming.nativeTransportstreaming.preview.toolProgress
    • 展開預覽:unfurlLinksunfurlMedia,用於 chat.postMessage 連結/媒體預覽控制
    • 維運/功能:configWritescommands.nativeslashCommand.*actions.*userTokenuserTokenReadOnly

    疑難排解

    頻道中沒有回覆

    依序檢查:

    • groupPolicy
    • 頻道允許清單(channels.slack.channels)— 鍵必須是頻道 IDC12345678),而不是名稱(#channel-name)。在 groupPolicy: "allowlist" 下,名稱型鍵會無聲失敗,因為頻道路由預設以 ID 優先。若要尋找 ID:在 Slack 中以右鍵點擊頻道 → 複製連結 — URL 結尾的 C... 值就是頻道 ID。
    • requireMention
    • 每頻道 users 允許清單

    實用指令:

    bash
    openclaw channels status --probeopenclaw logs --followopenclaw doctor
    DM 訊息被忽略

    檢查:

    • channels.slack.dm.enabled
    • channels.slack.dmPolicy(或舊版 channels.slack.dm.policy
    • 配對核准 / 允許清單項目
    • Slack Assistant DM 事件:提到 drop message_changed 的詳細記錄 通常表示 Slack 傳送了一個已編輯的 Assistant-thread 事件,但訊息中繼資料中 沒有可復原的人類寄件者
    bash
    openclaw pairing list slack
    Socket mode 未連線

    在 Slack app 設定中驗證 bot + app 權杖與 Socket Mode 啟用狀態。

    如果 openclaw channels status --probe --json 顯示 botTokenStatusappTokenStatus: "configured_unavailable",表示 Slack 帳戶已 設定,但目前執行階段無法解析由 SecretRef 支援的 值。

    HTTP mode not receiving events

    驗證:

    • 簽署密鑰
    • webhook 路徑
    • Slack Request URL(Events + Interactivity + Slash Commands)
    • 每個 HTTP 帳戶都有唯一的 webhookPath

    如果帳戶快照中出現 signingSecretStatus: "configured_unavailable", 表示 HTTP 帳戶已設定,但目前執行階段無法解析以 SecretRef 支援的簽署密鑰。

    Native/slash commands not firing

    確認你原本預期使用的是:

    • 原生命令模式(channels.slack.commands.native: true),並已在 Slack 註冊相符的 slash commands
    • 或單一 slash command 模式(channels.slack.slashCommand.enabled: true

    也請檢查 commands.useAccessGroups 和頻道/使用者允許清單。

    附件視覺參考

    當 Slack 檔案下載成功且大小限制允許時,Slack 可以將下載的媒體附加到 agent turn。圖片檔案可以透過媒體理解路徑傳遞,或直接傳給具備視覺能力的回覆模型;其他檔案則會保留為可下載的檔案情境,而不是被視為圖片輸入。

    支援的媒體類型

    媒體類型 來源 目前行為 備註
    JPEG / PNG / GIF / WebP 圖片 Slack 檔案 URL 下載並附加到該 turn,以供具備視覺能力的處理使用 單檔上限:channels.slack.mediaMaxMb(預設 20 MB)
    PDF 檔案 Slack 檔案 URL 下載並公開為檔案情境,以供 download-filepdf 等工具使用 Slack 入站不會自動將 PDF 轉換為圖片視覺輸入
    其他檔案 Slack 檔案 URL 可行時下載並公開為檔案情境 二進位檔案不會被視為圖片輸入
    執行緒回覆 執行緒起始檔案 當回覆沒有直接媒體時,可將根訊息檔案補水為情境 只有檔案的起始訊息會使用附件佔位符
    多圖片訊息 多個 Slack 檔案 每個檔案都會獨立評估 Slack 處理每則訊息最多八個檔案

    入站管線

    當帶有檔案附件的 Slack 訊息抵達時:

    1. OpenClaw 會使用 bot token(xoxb-...)從 Slack 的私有 URL 下載檔案。
    2. 成功後,檔案會寫入媒體儲存區。
    3. 下載的媒體路徑和內容類型會加入入站情境。
    4. 支援圖片的模型/工具路徑可以使用該情境中的圖片附件。
    5. 非圖片檔案仍會作為檔案中繼資料或媒體參照,供能處理它們的工具使用。

    執行緒根附件繼承

    當訊息抵達執行緒中(具有 thread_ts 父項)時:

    • 如果回覆本身沒有直接媒體,且包含的根訊息有檔案,Slack 可以將根檔案補水為執行緒起始情境。
    • 直接回覆附件優先於根訊息附件。
    • 只有檔案且沒有文字的根訊息會以附件佔位符表示,使 fallback 仍可包含其檔案。

    多附件處理

    當單一 Slack 訊息包含多個檔案附件時:

    • 每個附件都會透過媒體管線獨立處理。
    • 下載的媒體參照會彙總到訊息情境中。
    • 處理順序遵循事件 payload 中的 Slack 檔案順序。
    • 某個附件下載失敗不會阻擋其他附件。

    大小、下載與模型限制

    • 大小上限:預設每個檔案 20 MB。可透過 channels.slack.mediaMaxMb 設定。
    • 下載失敗:Slack 無法提供的檔案、過期 URL、無法存取的檔案、超出大小限制的檔案,以及 Slack 驗證/登入 HTML 回應,都會被略過,而不是回報為不支援的格式。
    • 視覺模型:圖片分析會在現用回覆模型支援視覺時使用該模型,否則使用 agents.defaults.imageModel 設定的圖片模型。

    已知限制

    情境 目前行為 替代方式
    過期的 Slack 檔案 URL 略過檔案;不顯示錯誤 在 Slack 中重新上傳檔案
    未設定視覺模型 圖片附件會儲存為媒體參照,但不會作為圖片分析 設定 agents.defaults.imageModel,或使用具備視覺能力的回覆模型
    非常大的圖片(預設 > 20 MB) 依大小上限略過 如果 Slack 允許,請提高 channels.slack.mediaMaxMb
    轉寄/共享附件 文字和 Slack 託管的圖片/檔案媒體會以盡力而為方式處理 直接在 OpenClaw 執行緒中重新分享
    PDF 附件 儲存為檔案/媒體情境,不會自動經由圖片視覺路徑處理 使用 download-file 取得檔案中繼資料,或使用 pdf 工具進行 PDF 分析

    相關文件

    相關

    Was this useful?