跳轉到主要內容
OpenClaw 透過官方 Discord 閘道以機器人身分連接 Discord。支援 DM 和伺服器頻道。

配對

Discord DM 預設為配對模式。

斜線命令

原生命令行為與命令目錄。

頻道疑難排解

跨頻道診斷與修復流程。

快速設定

建立一個含機器人的 Discord 應用程式,將機器人加入你的伺服器,並與 OpenClaw 配對。如果可以,請使用私人伺服器;如有需要,請先建立一個Create My Own > For me and my friends)。
1

建立 Discord 應用程式與機器人

Discord Developer Portal 中,按一下 New Application 並為它命名(例如「OpenClaw」)。在側邊欄開啟 Bot,並將 Username 設為你的代理程式名稱。
2

啟用特權 intent

仍在 Bot 頁面中,於 Privileged Gateway Intents 下啟用:
  • Message Content Intent(必要)
  • Server Members Intent(建議;角色允許清單、名稱對 ID 比對,以及頻道受眾存取群組需要)
  • Presence Intent(選用;僅用於狀態更新)
3

複製你的機器人權杖

Bot 頁面中,按一下 Reset Token 並複製權杖。
雖然名稱如此,這會產生你的第一個權杖 — 並沒有任何東西被「重設」。
4

產生邀請 URL 並將機器人加入你的伺服器

在側邊欄開啟 OAuth2。在 OAuth2 URL Generator 中啟用這些 scope:
  • bot
  • applications.commands
在出現的 Bot Permissions 區段中,至少啟用:General Permissions
  • View Channels
Text Permissions
  • Send Messages
  • Read Message History
  • Embed Links
  • Attach Files
  • Add Reactions(選用)
這是一般文字頻道的基準。如果機器人會在討論串中發文,包括建立或接續討論串的論壇或媒體頻道工作流程,也請啟用 Send Messages in Threads複製產生的 URL,在瀏覽器中開啟,選取你的伺服器,然後按一下 Continue。機器人現在應該會出現在你的伺服器中。
5

啟用開發者模式並收集你的 ID

在 Discord 應用程式中,啟用開發者模式,以便複製 ID:
  1. User Settings(齒輪圖示)→ Developer → 開啟 Developer Mode (行動版:App SettingsAdvanced
  2. 以右鍵按一下你的 server iconCopy Server ID
  3. 以右鍵按一下你的個人頭像Copy User ID
將 Server ID 和 User ID 與你的機器人權杖放在一起;下一步需要這三項。
6

允許來自伺服器成員的 DM

若要讓配對運作,Discord 必須允許機器人傳送 DM 給你。以右鍵按一下你的 server iconPrivacy Settings → 開啟 Direct Messages如果你會搭配 OpenClaw 使用 Discord DM,請保持開啟。如果你只使用伺服器頻道,可以在配對後停用。
7

安全設定你的機器人權杖(不要在聊天中傳送)

機器人權杖是秘密。請先在執行 OpenClaw 的機器上設定它,再傳訊息給你的代理程式:
export DISCORD_BOT_TOKEN="YOUR_BOT_TOKEN"
cat > discord.patch.json5 <<'JSON5'
{
  channels: {
    discord: {
      enabled: true,
      token: { source: "env", provider: "default", id: "DISCORD_BOT_TOKEN" },
    },
  },
}
JSON5
openclaw config patch --file ./discord.patch.json5 --dry-run
openclaw config patch --file ./discord.patch.json5
openclaw gateway
如果 OpenClaw 已作為背景服務執行,請透過 OpenClaw Mac 應用程式重新啟動,或停止並重新啟動 openclaw gateway run 程序。 對於受管理的服務安裝,請從已設定 DISCORD_BOT_TOKEN 的 shell 執行 openclaw gateway install,或將變數儲存在 ~/.openclaw/.env,讓服務在重新啟動後可解析 env SecretRef。 如果你的主機遭 Discord 的啟動應用程式查詢封鎖或速率限制,請從 Developer Portal 設定 application/client ID,讓啟動流程可略過該 REST 呼叫:預設帳戶使用 channels.discord.applicationId,或每個機器人使用 channels.discord.accounts.<accountId>.applicationId
8

設定 OpenClaw 並配對

在既有頻道(例如 Telegram)與你的 OpenClaw 代理程式聊天並告訴它。如果 Discord 是你的第一個頻道,請改用命令列介面 / config 分頁。
「我已經在 config 中設定 Discord bot token。請使用 User ID <user_id> 和 Server ID <server_id> 完成 Discord 設定。」
9

核准第一次 DM 配對

閘道開始執行後,在 Discord 中 DM 你的機器人。它會回覆配對碼。
在你的既有頻道將配對碼傳送給代理程式:
「核准這個 Discord 配對碼:<CODE>
配對碼會在 1 小時後過期。核准後,即可在 Discord DM 中與你的代理程式聊天。
權杖解析會感知帳戶。Config token 值優先於 env fallback,而 DISCORD_BOT_TOKEN 只會用於預設帳戶。 如果兩個已啟用的 Discord 帳戶解析為相同的機器人權杖,OpenClaw 只會為該權杖啟動一個閘道監控:來自 config 的權杖優先於 env fallback;否則第一個已啟用帳戶勝出,重複帳戶會回報為已停用,原因為 duplicate bot token。 對於進階 outbound 呼叫(message tool/channel actions),明確的每次呼叫 token 會用於該呼叫。這適用於傳送與 read/probe 風格的動作(read/search/fetch/thread/pins/permissions)。帳戶 policy/retry 設定仍來自作用中 runtime snapshot 裡選取的帳戶。

建議:設定伺服器工作區

DM 可運作後,你可以將伺服器變成完整工作區,讓每個頻道都有自己的代理程式工作階段與自己的脈絡。建議用於只有你和你的機器人的私人伺服器。
1

將你的伺服器加入伺服器允許清單

這會讓你的代理程式可在你伺服器上的任何頻道回應,而不只是 DM。
「將我的 Discord Server ID <server_id> 加入伺服器允許清單」
2

允許不需 @mention 的回應

預設情況下,代理程式只會在伺服器頻道中被 @mentioned 時回應。在私人伺服器上,你可能希望它回應每則訊息。在伺服器頻道中,一般回覆預設會自動發出。對於共享的常駐聊天室,選擇使用 messages.groupChat.visibleReplies: "message_tool",讓代理程式可潛伏,並只在判斷頻道回覆有用時才發文。這最適合最新世代、工具可靠的模型,例如 GPT 5.5。周遭聊天室事件會保持安靜,除非工具送出。完整潛伏模式 config 請參閱周遭聊天室事件如果 Discord 顯示正在輸入,且 logs 顯示 token 用量但沒有發出訊息,請檢查該 turn 是否設定為周遭聊天室事件,或是否選擇使用 message-tool visible replies。
「允許我的代理程式在這個伺服器上回應,不必被 @mentioned」
3

規劃伺服器頻道中的記憶

長期記憶(MEMORY.md)只會在 DM 工作階段中自動載入;伺服器頻道不會載入它。
「當我在 Discord 頻道中提問時,如果你需要來自 MEMORY.md 的長期脈絡,請使用 memory_search 或 memory_get。」
現在建立頻道並開始聊天。代理程式會看見頻道名稱,且每個頻道都是隔離的工作階段 — 設定 #coding#home#research,或任何符合你工作流程的頻道。

Runtime 模型

  • 閘道擁有 Discord 連線。
  • 回覆路由是確定性的:Discord inbound 會回覆到 Discord。
  • Discord 伺服器/頻道中繼資料會作為不受信任脈絡加入模型 prompt,而不是作為使用者可見的回覆前綴。如果模型把該 envelope 複製回來,OpenClaw 會從 outbound 回覆和未來 replay 脈絡中移除複製的中繼資料。
  • 預設情況下(session.dmScope=main),直接聊天會共用代理程式主要工作階段(agent:main:main)。
  • 伺服器頻道是隔離的工作階段 key(agent:<agentId>:discord:channel:<channelId>)。
  • Group DM 預設會被忽略(channels.discord.dm.groupEnabled=false)。
  • 原生斜線命令會在隔離的命令工作階段中執行(agent:<agentId>:discord:slash:<userId>),同時仍攜帶 CommandTargetSessionKey 到路由後的對話工作階段。
  • 傳送到 Discord 的純文字 cron/heartbeat 公告會收斂為最終的 assistant-visible answer,並只傳送一次。當代理程式發出多個可傳遞 payload 時,媒體與結構化元件 payload 仍會是多訊息。

論壇頻道

Discord 論壇和媒體頻道只接受討論串貼文。OpenClaw 支援兩種建立方式:
  • 傳送訊息到論壇父層(channel:<forumId>)以自動建立討論串。討論串標題會使用訊息的第一個非空白行(截斷至 Discord 的 100 字元討論串名稱限制)。
  • 使用 openclaw message thread create 直接建立討論串。請勿對論壇頻道傳入 --message-id
傳送到論壇父層以建立討論串:
openclaw message send --channel discord --target channel:<forumId> \
  --message "Topic title\nBody of the post"
明確建立論壇討論串:
openclaw message thread create --channel discord --target channel:<forumId> \
  --thread-name "Topic title" --message "Body of the post"
論壇父層不接受 Discord 元件。如果你需要元件,請傳送到討論串本身(channel:<threadId>)。

互動式元件

OpenClaw 支援供代理訊息使用的 Discord components v2 容器。使用訊息工具並搭配 components 承載資料。互動結果會像一般傳入訊息一樣路由回代理,並遵循既有的 Discord replyToMode 設定。 支援的區塊:
  • textsectionseparatoractionsmedia-galleryfile
  • 動作列最多允許 5 個按鈕或單一選取選單
  • 選取類型:stringuserrolementionablechannel
預設情況下,元件只能使用一次。設定 components.reusable=true 可允許按鈕、選取項和表單在到期前多次使用。 若要限制誰可以點擊按鈕,請在該按鈕上設定 allowedUsers(Discord 使用者 ID、標籤或 *)。不符合的使用者會收到僅自己可見的拒絕訊息。 元件回呼預設會在 30 分鐘後到期。設定 channels.discord.agentComponents.ttlMs 可變更預設帳號的回呼登錄生命週期,或依帳號設定 channels.discord.accounts.<accountId>.agentComponents.ttlMs。此值以毫秒為單位,必須是正整數,且上限為 86400000(24 小時)。較長的 TTL 適合需要讓按鈕保持可用的審查/核准工作流程,但也會延長舊 Discord 訊息仍可觸發動作的時間範圍。請偏好使用符合需求的最短 TTL,並在過期回呼會令人意外時保留預設值。 /model/models 斜線命令會開啟互動式模型選擇器,其中包含供應商、模型和相容執行階段下拉選單,並有提交步驟。/models add 已棄用,會傳回棄用訊息,而不是從聊天註冊模型。選擇器回覆是僅自己可見的,且只能由呼叫它的使用者使用。Discord 選取選單限制為 25 個選項,因此當你希望選擇器只針對所選供應商(例如 openaivllm)顯示動態探索到的模型時,請將 provider/* 項目加入 agents.defaults.models 檔案附件:
  • file 區塊必須指向附件參照(attachment://<filename>
  • 透過 media/path/filePath 提供附件(單一檔案);多個檔案請使用 media-gallery
  • 當上傳名稱應與附件參照相符時,使用 filename 覆寫上傳名稱
模態表單:
  • 加入 components.modal,最多可包含 5 個欄位
  • 欄位類型:textcheckboxradioselectrole-selectuser-select
  • OpenClaw 會自動加入觸發按鈕
範例:
{
  channel: "discord",
  action: "send",
  to: "channel:123456789012345678",
  message: "Optional fallback text",
  components: {
    reusable: true,
    text: "Choose a path",
    blocks: [
      {
        type: "actions",
        buttons: [
          {
            label: "Approve",
            style: "success",
            allowedUsers: ["123456789012345678"],
          },
          { label: "Decline", style: "danger" },
        ],
      },
      {
        type: "actions",
        select: {
          type: "string",
          placeholder: "Pick an option",
          options: [
            { label: "Option A", value: "a" },
            { label: "Option B", value: "b" },
          ],
        },
      },
    ],
    modal: {
      title: "Details",
      triggerLabel: "Open form",
      fields: [
        { type: "text", label: "Requester" },
        {
          type: "select",
          label: "Priority",
          options: [
            { label: "Low", value: "low" },
            { label: "High", value: "high" },
          ],
        },
      ],
    },
  },
}

存取控制與路由

channels.discord.dmPolicy 控制 DM 存取。channels.discord.allowFrom 是標準 DM 允許清單。
  • pairing(預設)
  • allowlist(至少需要一個 allowFrom 傳送者)
  • open(需要 channels.discord.allowFrom 包含 "*"
  • disabled
如果 DM 政策不是開放,未知使用者會被封鎖(或在 pairing 模式中被提示配對)。多帳號優先順序:
  • channels.discord.accounts.default.allowFrom 只套用至 default 帳號。
  • 對單一帳號而言,allowFrom 優先於舊版 dm.allowFrom
  • 當具名帳號本身的 allowFrom 和舊版 dm.allowFrom 未設定時,會繼承 channels.discord.allowFrom
  • 具名帳號不會繼承 channels.discord.accounts.default.allowFrom
為了相容性,仍會讀取舊版 channels.discord.dm.policychannels.discord.dm.allowFromopenclaw doctor --fix 會在不變更存取權的情況下,將它們遷移到 dmPolicyallowFrom傳遞用的 DM 目標格式:
  • user:<id>
  • <@id> 提及
當頻道預設值啟用時,裸數字 ID 通常會解析為頻道 ID,但列在帳號有效 DM allowFrom 中的 ID,為了相容性會被視為使用者 DM 目標。

以角色為基礎的代理路由

使用 bindings[].match.roles 依角色 ID 將 Discord 伺服器成員路由到不同代理。以角色為基礎的繫結只接受角色 ID,且會在對等或父對等繫結之後、僅伺服器繫結之前評估。如果繫結也設定其他比對欄位(例如 peer + guildId + roles),所有已設定欄位都必須符合。
{
  bindings: [
    {
      agentId: "opus",
      match: {
        channel: "discord",
        guildId: "123456789012345678",
        roles: ["111111111111111111"],
      },
    },
    {
      agentId: "sonnet",
      match: {
        channel: "discord",
        guildId: "123456789012345678",
      },
    },
  ],
}

原生命令與命令授權

  • commands.native 預設為 "auto",並對 Discord 啟用。
  • 依頻道覆寫:channels.discord.commands.native
  • commands.native=false 會在啟動期間略過 Discord 斜線命令註冊與清理。先前註冊的命令可能仍會在 Discord 中可見,直到你從 Discord 應用程式移除它們。
  • 原生命令驗證使用與一般訊息處理相同的 Discord 允許清單/政策。
  • 未授權使用者仍可能在 Discord UI 中看到命令;執行時會強制套用 OpenClaw 驗證並回覆「未授權」。
  • 預設斜線命令設定:ephemeral: truechannels.discord.slashCommand.ephemeral)。
請參閱斜線命令了解命令目錄與行為。

功能詳細資料

Discord 支援代理程式輸出中的回覆標籤:
  • [[reply_to_current]]
  • [[reply_to:<id>]]
channels.discord.replyToMode 控制:
  • off(預設):沒有隱含的回覆串接;明確的 [[reply_to_*]] 標籤仍會被遵守
  • first:將隱含的原生回覆參照附加到該回合的第一則外送 Discord 訊息
  • all:附加到每一則外送訊息
  • batched:只有在傳入事件是多則訊息的防抖批次時才附加;適合你主要想在模糊、突發的聊天中使用原生回覆,而不是每個單一訊息回合都使用
訊息 ID 會在脈絡/歷史中公開,因此代理程式可以鎖定特定訊息。
Discord 預設會為 URL 產生豐富連結嵌入。OpenClaw 預設會抑制外送 Discord 訊息上這些產生的嵌入,因此代理程式傳送的 URL 會維持純連結,除非你選擇啟用:
{
  channels: {
    discord: {
      suppressEmbeds: false,
    },
  },
}
設定 channels.discord.accounts.<id>.suppressEmbeds 以覆寫單一帳戶。代理程式訊息工具傳送也可以針對單一訊息傳入 suppressEmbeds: false。明確的 Discord embeds 酬載不會被預設連結預覽設定抑制。
OpenClaw 可以透過傳送暫時訊息並在文字抵達時編輯它,來串流草稿回覆。channels.discord.streaming.mode 接受 off | partial | block | progress(未設定 streaming/舊版 streamMode 鍵時的預設值)。streamMode 是舊版別名;執行 openclaw doctor --fix 以將持久化設定重寫為標準巢狀 streaming 形狀。
{
  channels: {
    discord: {
      streaming: {
        mode: "progress",
        progress: {
          label: "auto",
          maxLines: 8,
          maxLineChars: 120,
          toolProgress: true,
          commentary: false,
        },
      },
    },
  },
}
  • off 停用 Discord 預覽編輯。
  • partial 會在 token 抵達時編輯單一預覽訊息。
  • block 會送出草稿大小的區塊;使用 streaming.preview.chunkminCharsmaxCharsbreakPreference)調整大小與斷點,並限制在 textChunkLimit 內。明確啟用區塊串流時,OpenClaw 會略過預覽串流以避免雙重串流。
  • progress 會保留一則可編輯的狀態草稿,並以工具進度更新它,直到最終傳送;共用起始標籤是一行滾動文字,因此一旦出現足夠工作內容,它就會像其餘內容一樣捲離。
  • 媒體、錯誤和明確回覆的最終訊息會取消待處理的預覽編輯。
  • streaming.preview.toolProgress(預設 true)控制工具/進度更新是否重用預覽訊息。
  • 工具/進度列會在可用時以精簡的表情符號 + 標題 + 詳細資料呈現,例如 🛠️ Bash: run tests🔎 Web Search: for "query"
  • streaming.progress.commentary(預設 false)選擇在暫時進度草稿中納入助理評論/前言文字。評論會在顯示前清理,保持暫時性,且不會改變最終答案傳送。
  • streaming.progress.maxLineChars 控制每行進度預覽預算。散文會在字詞邊界縮短;命令與路徑詳細資料會保留有用的後綴。
  • streaming.preview.commandText / streaming.progress.commandText 控制精簡進度列中的命令/執行詳細資料:raw(預設)或 status(僅工具標籤)。
隱藏原始命令/執行文字,同時保留精簡進度列:
{
  "channels": {
    "discord": {
      "streaming": {
        "mode": "progress",
        "progress": {
          "toolProgress": true,
          "commandText": "status"
        }
      }
    }
  }
}
預覽串流僅支援文字;媒體回覆會退回一般傳送。
伺服器歷史脈絡:
  • channels.discord.historyLimit 預設 20
  • 備援:messages.groupChat.historyLimit
  • 0 停用
DM 歷史控制:
  • channels.discord.dmHistoryLimit
  • channels.discord.dms["<user_id>"].historyLimit
討論串行為:
  • Discord 討論串會以頻道工作階段路由,並繼承父頻道設定,除非已覆寫。
  • 討論串工作階段會繼承父頻道的工作階段層級 /model 選擇,作為僅模型的備援;討論串本地 /model 選擇優先,且除非啟用逐字稿繼承,否則不會複製父逐字稿歷史。
  • channels.discord.thread.inheritParent(預設 false)會讓新的自動討論串選擇從父逐字稿植入。依帳戶覆寫:channels.discord.accounts.<id>.thread.inheritParent
  • 訊息工具反應可以解析 user:<id> DM 目標。
  • guilds.<guild>.channels.<channel>.requireMention: false 會在回覆階段啟用備援期間保留。
頻道主題會以不受信任脈絡注入。允許清單會控管誰能觸發代理程式,而不是完整的補充脈絡修訂邊界。
Discord 可以將討論串綁定到工作階段目標,讓該討論串中的後續訊息持續路由到相同工作階段(包含子代理程式工作階段)。命令:
  • /focus <target> 將目前/新討論串綁定到子代理程式/工作階段目標
  • /unfocus 移除目前討論串綁定
  • /agents 顯示作用中執行與綁定狀態
  • /session idle <duration|off> 檢查/更新聚焦綁定的不活動自動取消聚焦
  • /session max-age <duration|off> 檢查/更新聚焦綁定的硬性最大期限
設定:
{
  session: {
    threadBindings: {
      enabled: true,
      idleHours: 24,
      maxAgeHours: 0,
    },
  },
  channels: {
    discord: {
      threadBindings: {
        enabled: true,
        idleHours: 24,
        maxAgeHours: 0,
        spawnSessions: true,
        defaultSpawnContext: "fork",
      },
    },
  },
}
附註:
  • session.threadBindings.* 設定全域預設值;channels.discord.threadBindings.* 覆寫 Discord 行為。
  • spawnSessions 控制 sessions_spawn({ thread: true }) 和 ACP 討論串生成的自動建立/綁定討論串。預設:true
  • defaultSpawnContext 控制討論串綁定生成的原生子代理程式脈絡。預設:"fork"
  • 已棄用的 spawnSubagentSessions/spawnAcpSessions 鍵會由 openclaw doctor --fix 遷移。
  • 如果某個帳戶停用討論串綁定,/focus 和相關討論串綁定操作將不可用。
請參閱子代理程式ACP 代理程式設定參考
對於穩定的「always-on」ACP 工作區,請設定頂層型別化 ACP 綁定,目標為 Discord 對話。設定路徑:bindings[],搭配 type: "acp"match.channel: "discord"
{
  agents: {
    list: [
      {
        id: "codex",
        runtime: {
          type: "acp",
          acp: {
            agent: "codex",
            backend: "acpx",
            mode: "persistent",
            cwd: "/workspace/openclaw",
          },
        },
      },
    ],
  },
  bindings: [
    {
      type: "acp",
      agentId: "codex",
      match: {
        channel: "discord",
        accountId: "default",
        peer: { kind: "channel", id: "222222222222222222" },
      },
      acp: { label: "codex-main" },
    },
  ],
  channels: {
    discord: {
      guilds: {
        "111111111111111111": {
          channels: {
            "222222222222222222": {
              requireMention: false,
            },
          },
        },
      },
    },
  },
}
附註:
  • /acp spawn codex --bind here 會就地綁定目前頻道或討論串,並讓未來訊息維持在相同 ACP 工作階段。討論串訊息會繼承父頻道綁定。
  • 在已綁定的頻道或討論串中,/new/reset 會就地重設相同 ACP 工作階段。暫時討論串綁定可以在作用中時覆寫目標解析。
  • spawnSessions 透過 --thread auto|here 控管子討論串建立/綁定。
請參閱 ACP 代理程式了解綁定行為詳細資料。
每個伺服器的反應通知模式(guilds.<id>.reactionNotifications):
  • off
  • own(預設)
  • all
  • allowlist(使用 guilds.<id>.users
反應事件會轉換為系統事件,並附加到已路由的 Discord 工作階段。
ackReaction 會在 OpenClaw 處理傳入訊息時傳送確認表情符號。解析順序:
  • channels.discord.accounts.<accountId>.ackReaction
  • channels.discord.ackReaction
  • messages.ackReaction
  • 代理程式身分表情符號備援(agents.list[].identity.emoji,否則為 ”👀”)
附註:
  • Discord 接受 unicode 表情符號或自訂表情符號名稱。
  • 使用 "" 停用頻道或帳戶的反應。
範圍(messages.ackReactionScope):值:"all"(DM + 群組,包含周遭聊天室事件)、"direct"(僅 DM)、"group-all"(除了周遭聊天室事件之外的每則群組訊息,無 DM)、"group-mentions"(機器人被提及時的群組;無 DM,預設)、"off" / "none"(停用)。
預設範圍("group-mentions")不會在直接訊息或周遭聊天室事件中觸發確認反應。若要在傳入 Discord DM 和安靜聊天室事件上取得確認反應,請將 messages.ackReactionScope 設為 "all"
預設啟用由頻道啟動的設定寫入。這會影響 /config set|unset 流程(啟用命令功能時)。停用:
{
  channels: {
    discord: {
      configWrites: false,
    },
  },
}
透過 channels.discord.proxy 使用 HTTP(S) 代理路由 Discord 閘道 WebSocket 流量與啟動 REST 查詢(應用程式 ID + 允許清單解析)。 Discord 閘道 WebSocket 代理是明確的;WebSocket 連線不會繼承閘道程序的環境代理變數。設定 channels.discord.proxy 時,啟動 REST 查詢會使用此代理。
{
  channels: {
    discord: {
      proxy: "http://proxy.example:8080",
    },
  },
}
依帳戶覆寫:
{
  channels: {
    discord: {
      accounts: {
        primary: {
          proxy: "http://proxy.example:8080",
        },
      },
    },
  },
}
啟用 PluralKit 解析,以將代理訊息對應到系統成員身分:
{
  channels: {
    discord: {
      pluralkit: {
        enabled: true,
        token: "pk_live_...", // 選填;私人系統需要
      },
    },
  },
}
備註:
  • 允許清單可使用 pk:<memberId>
  • 只有在 channels.discord.dangerouslyAllowNameMatching: true 時,才會依名稱/slug 比對成員顯示名稱
  • 查詢會使用原始訊息 ID 查詢 PluralKit API
  • 如果查詢失敗,代理訊息會被視為機器人訊息並丟棄,除非 allowBots 允許它們通過
當代理需要對已知 Discord 使用者進行確定性的傳出提及時,請使用 mentionAliases。鍵是不含前置 @ 的 handle;值是 Discord 使用者 ID。未知 handle、@everyone@here,以及 Markdown 程式碼範圍內的提及會保持不變。
{
  channels: {
    discord: {
      mentionAliases: {
        SupportLead: "123456789012345678",
      },
      accounts: {
        ops: {
          mentionAliases: {
            OpsLead: "234567890123456789",
          },
        },
      },
    },
  },
}
當你設定狀態或活動欄位,或啟用自動狀態時,會套用狀態更新。僅狀態:
{
  channels: {
    discord: {
      status: "idle",
    },
  },
}
活動(設定 activity 時,自訂狀態是預設活動類型):
{
  channels: {
    discord: {
      activity: "專注時間",
      activityType: 4,
    },
  },
}
串流:
{
  channels: {
    discord: {
      activity: "即時寫程式",
      activityType: 1,
      activityUrl: "https://twitch.tv/openclaw",
    },
  },
}
活動類型對照表:
  • 0: 遊玩中
  • 1: 串流中(需要 activityUrlactivityUrl 也需要 activityType: 1
  • 2: 聆聽中
  • 3: 觀看中
  • 4: 自訂(使用活動文字作為狀態狀態;表情符號為選填)
  • 5: 競賽中
自動狀態(執行階段健康訊號):
{
  channels: {
    discord: {
      autoPresence: {
        enabled: true,
        intervalMs: 30000,
        minUpdateIntervalMs: 15000,
        exhaustedText: "權杖已耗盡",
      },
    },
  },
}
自動狀態會將執行階段可用性對應到 Discord 狀態:健康 => 線上,降級或未知 => 閒置,已耗盡或不可用 => 請勿打擾。預設值:intervalMs 30000,minUpdateIntervalMs 15000(必須小於或等於 intervalMs)。選填文字覆寫:
  • autoPresence.healthyText
  • autoPresence.degradedText
  • autoPresence.exhaustedText(支援 {reason} placeholder)
Discord 支援在私訊中使用按鈕式核准處理,也可選擇在原始頻道中張貼核准提示。設定路徑:
  • channels.discord.execApprovals.enabled
  • channels.discord.execApprovals.approvers(選填;可行時會退回使用 commands.ownerAllowFrom
  • channels.discord.execApprovals.targetdm | channel | both,預設:dm
  • agentFiltersessionFiltercleanupAfterResolve
enabled 未設定或為 "auto",且至少能解析出一位核准者時,Discord 會自動啟用原生 exec 核准;核准者可來自 execApprovals.approverscommands.ownerAllowFrom。Discord 不會從頻道 allowFrom、舊版 dm.allowFrom 或直接訊息 defaultTo 推斷 exec 核准者。若要明確停用 Discord 作為原生核准用戶端,請設定 enabled: false對於 /diagnostics/export-trajectory 等敏感的僅限擁有者群組命令,OpenClaw 會私下傳送核准提示和最終結果。當發起命令的擁有者有 Discord 擁有者路由時,它會先嘗試 Discord 私訊;否則會退回使用 commands.ownerAllowFrom 中第一個可用的擁有者路由,例如 Telegram。targetchannelboth 時,核准提示會在頻道中可見。只有已解析的核准者可以使用按鈕;其他使用者會收到暫時性的拒絕訊息。核准提示會包含命令文字,因此只應在受信任的頻道中啟用頻道傳遞。如果無法從工作階段鍵推導出頻道 ID,OpenClaw 會退回使用私訊傳遞。Discord 會呈現其他聊天頻道使用的共用核准按鈕;原生 Discord 配接器主要新增核准者私訊路由和頻道扇出。當這些按鈕存在時,它們是主要核准使用者體驗;OpenClaw 只有在工具結果表示聊天核准不可用,或手動核准是唯一路徑時,才應包含手動 /approve 命令。如果 Discord 原生核准執行階段未啟用,OpenClaw 會保持本機確定性的 /approve <id> <decision> 提示可見。如果執行階段已啟用,但原生卡片無法傳遞到任何目標,OpenClaw 會在同一聊天中傳送備援通知,並包含待處理核准中的確切 /approve 命令。閘道驗證和核准解析遵循共用的閘道用戶端合約(plugin: ID 透過 plugin.approval.resolve 解析;其他 ID 透過 exec.approval.resolve 解析)。核准預設會在 30 分鐘後過期。請參閱 Exec 核准

工具和動作閘門

Discord 訊息動作涵蓋傳訊、頻道管理、審核、狀態和中繼資料。 核心範例:
  • 傳訊:sendMessagereadMessageseditMessagedeleteMessagethreadReply
  • 反應:reactreactionsemojiList
  • 審核:timeoutkickban
  • 狀態:setPresence
event-create 動作接受選填的 image 參數(URL 或本機檔案路徑),用於設定排程活動封面圖片。 動作閘門位於 channels.discord.actions.* 下。 預設閘門行為:
動作群組預設
reactions, messages, threads, pins, polls, search, memberInfo, roleInfo, channelInfo, channels, voiceStatus, events, stickers, emojiUploads, stickerUploads, permissions已啟用
roles已停用
moderation已停用
presence已停用

Components v2 UI

OpenClaw 使用 Discord components v2 進行 exec 核准和跨情境標記。Discord 訊息動作也可以接受 components 來建立自訂 UI(進階;需要透過 discord 工具建構 component payload),而舊版 embeds 仍可使用,但不建議。
  • channels.discord.ui.components.accentColor 設定 Discord component 容器使用的強調色(十六進位)。各帳號:channels.discord.accounts.<id>.ui.components.accentColor
  • channels.discord.agentComponents.ttlMs 控制已傳送的 Discord component callback 保持註冊的時間長度(預設 1800000,最大 86400000)。各帳號:channels.discord.accounts.<id>.agentComponents.ttlMs
  • 當 components v2 存在時,會忽略 embeds
  • 純 URL 預覽預設會被抑制。當單一傳出連結應展開時,請在訊息動作上設定 suppressEmbeds: false
範例:
{
  channels: {
    discord: {
      ui: {
        components: {
          accentColor: "#5865F2",
        },
      },
    },
  },
}

語音

Discord 有兩種不同的語音介面:即時語音頻道(連續對話)和語音訊息附件(波形預覽格式)。閘道同時支援兩者。

語音頻道

設定檢查清單:
  1. 在 Discord Developer Portal 啟用 Message Content Intent。
  2. 使用角色/使用者允許清單時,啟用 Server Members Intent。
  3. 使用 botapplications.commands scope 邀請機器人。
  4. 在目標語音頻道中授予 Connect、Speak、Send Messages 和 Read Message History。
  5. 啟用原生命令(commands.nativechannels.discord.commands.native)。
  6. 設定 channels.discord.voice
使用 /vc join|leave|status 控制工作階段。此命令使用帳號預設代理,並遵循與其他 Discord 命令相同的允許清單和群組政策規則。
/vc join channel:<voice-channel-id>
/vc status
/vc leave
加入前若要檢查機器人的有效權限:
openclaw channels capabilities --channel discord --target channel:<voice-channel-id>
自動加入範例:
{
  channels: {
    discord: {
      voice: {
        enabled: true,
        model: "openai/gpt-5.5",
        autoJoin: [
          {
            guildId: "123456789012345678",
            channelId: "234567890123456789",
          },
        ],
        allowedChannels: [
          {
            guildId: "123456789012345678",
            channelId: "234567890123456789",
          },
        ],
        daveEncryption: true,
        decryptionFailureTolerance: 24,
        connectTimeoutMs: 30000,
        reconnectGraceMs: 15000,
        realtime: {
          provider: "openai",
          model: "gpt-realtime-2",
          speakerVoice: "cedar",
        },
      },
    },
  },
}
備註:
  • Discord 語音對純文字設定是選用功能;設定 channels.discord.voice.enabled=true(或保留既有的 channels.discord.voice 區塊)即可啟用 /vc 指令、語音執行階段,以及 GuildVoiceStates 閘道意圖。channels.discord.intents.voiceStates 可以明確覆寫意圖訂閱;若不設定,則會跟隨實際的語音啟用狀態。
  • voice.mode 控制對話路徑。預設值是 agent-proxy:即時語音前端會處理回合時序、中斷與播放,透過 openclaw_agent_consult 將實質工作委派給路由到的 OpenClaw 代理程式,並將結果視為該說話者輸入的 Discord 文字提示。stt-tts 保留較舊的批次 STT 加 TTS 流程。bidi 讓即時模型直接對話,同時公開 openclaw_agent_consult 給 OpenClaw 大腦使用。
  • voice.agentSession 控制哪個 OpenClaw 對話會接收語音回合。若不設定,會使用語音頻道自己的工作階段;也可以設定 { mode: "target", target: "channel:<text-channel-id>" },讓語音頻道成為既有 Discord 文字頻道工作階段(例如 #maintainers)的麥克風/喇叭延伸。
  • voice.model 會覆寫 Discord 語音回應與即時諮詢所使用的 OpenClaw 代理大腦。若不設定,會繼承路由到的代理模型。它與 voice.realtime.model 是分開的。
  • voice.followUsers 讓機器人可與選定使用者一起加入、移動及離開 Discord 語音。請參閱在語音中跟隨使用者
  • agent-proxy 會透過 discord-voice 路由語音,這會保留說話者與目標工作階段的正常擁有者/工具授權,但會隱藏代理程式的 tts 工具,因為 Discord 語音負責播放。預設情況下,agent-proxy 會對擁有者說話者提供完整的擁有者等效工具存取權(voice.realtime.toolPolicy: "owner"),並強烈偏好在給出實質回答前先諮詢 OpenClaw 代理程式(voice.realtime.consultPolicy: "always")。在該預設的 always 模式下,即時層不會在諮詢答案前自動說出填充語;它會擷取並轉錄語音,然後說出路由後的 OpenClaw 答案。如果 Discord 仍在播放第一個答案時有多個強制諮詢答案完成,後續的精確語音答案會排入佇列,直到播放閒置後再播放,而不是在句子中途替換語音。
  • stt-tts 模式中,STT 使用 tools.media.audiovoice.model 不會影響轉錄。
  • 在即時模式中,voice.realtime.providervoice.realtime.modelvoice.realtime.speakerVoice 會設定即時音訊工作階段。若要搭配 Codex 大腦使用 OpenAI Realtime 2,請使用 voice.realtime.model: "gpt-realtime-2"voice.model: "openai/gpt-5.5"
  • 即時語音模式預設會在即時提供者指令中包含小型 IDENTITY.mdUSER.mdSOUL.md 設定檔,讓快速直接回合保有與路由到的 OpenClaw 代理程式相同的身分、使用者根據與角色設定。將 voice.realtime.bootstrapContextFiles 設為子集合可自訂此行為,或設為 [] 可停用。僅支援這些設定檔;AGENTS.md 仍會留在一般代理程式上下文中。注入的設定檔上下文不會取代 openclaw_agent_consult 在工作區工作、目前事實、記憶查詢或工具支援動作中的用途。
  • 在 OpenAI agent-proxy 即時模式中,設定 voice.realtime.requireWakeName: true,即可讓 Discord 即時語音在轉錄以喚醒名稱開頭或結尾之前保持靜默。設定的喚醒名稱必須是一個或兩個詞。如果未設定 voice.realtime.wakeNames,OpenClaw 會使用路由到的代理程式 name 加上 OpenClaw,並在需要時退回代理程式 ID 加上 OpenClaw。喚醒名稱閘控會停用即時提供者自動回應,將接受的回合透過 OpenClaw 代理程式諮詢路徑路由,並在最終轉錄抵達前,若從部分轉錄辨識到前置喚醒名稱,就給出簡短的語音確認。
  • OpenAI 即時提供者接受目前的 Realtime 2 事件名稱,以及與舊版 Codex 相容的輸出音訊與轉錄事件別名,因此相容的提供者快照即使漂移,也不會遺失助理音訊。
  • voice.realtime.bargeIn 控制 Discord 說話者開始事件是否會中斷使用中的即時播放。若未設定,會跟隨即時提供者的輸入音訊中斷設定。
  • voice.realtime.minBargeInAudioEndMs 控制 OpenAI 即時插話截斷音訊前,助理播放的最短持續時間。預設值:250。在低回音房間中可設為 0 以立即中斷;在回音較重的喇叭環境中可提高此值。
  • voice.tts 只會針對 stt-tts 語音播放覆寫 messages.tts;即時模式改用 voice.realtime.speakerVoice。若要在 Discord 播放中使用 OpenAI 語音,請設定 voice.tts.provider: "openai",並在 voice.tts.providers.openai.speakerVoice 下選擇文字轉語音聲音。cedar 在目前的 OpenAI TTS 模型上是很適合的偏陽性聲音選項。
  • 每個 Discord 頻道的 systemPrompt 覆寫會套用到該語音頻道的語音轉錄回合。
  • 語音轉錄回合會從 Discord allowFrom(或 dm.allowFrom)推導擁有者狀態,用於需要擁有者權限的指令與頻道動作。代理程式工具可見性會跟隨路由工作階段設定的工具政策。
  • 如果 voice.autoJoin 對同一個伺服器有多個項目,OpenClaw 會加入該伺服器最後設定的頻道。
  • voice.allowedChannels 是選用的駐留允許清單。若不設定,會允許 /vc join 加入任何已授權的 Discord 語音頻道。設定後,/vc join、啟動時自動加入,以及機器人語音狀態移動,都會限制在列出的 { guildId, channelId } 項目。將其設為空陣列可拒絕所有 Discord 語音加入。如果 Discord 將機器人移到允許清單之外,OpenClaw 會離開該頻道,並在有可用目標時重新加入設定的自動加入目標。
  • voice.daveEncryptionvoice.decryptionFailureTolerance 會傳遞給 @discordjs/voice 加入選項;上游預設值是 daveEncryption=truedecryptionFailureTolerance=24
  • OpenClaw 使用內建的 libopus-wasm 編解碼器來接收 Discord 語音與播放即時原始 PCM。它隨附固定版本的 libopus WebAssembly 建置,不需要原生 opus 附加元件。
  • voice.connectTimeoutMs 控制 /vc join 與自動加入嘗試時,初始等待 @discordjs/voice Ready 的時間。預設值:30000
  • voice.reconnectGraceMs 控制 OpenClaw 在銷毀已中斷連線的語音工作階段前,等待其開始重新連線的時間。預設值:15000
  • stt-tts 模式中,語音播放不會只因為另一位使用者開始說話就停止。為避免回授迴圈,OpenClaw 會在 TTS 播放期間忽略新的語音擷取;請在播放結束後再說話以進入下一回合。即時模式會將說話者開始事件轉送為傳給即時提供者的插話訊號。
  • 在即時模式中,喇叭回音進入開放麥克風可能看起來像插話並中斷播放。對於回音較重的 Discord 房間,請設定 voice.realtime.providers.openai.interruptResponseOnInputAudio: false,避免 OpenAI 因輸入音訊而自動中斷。若仍希望 Discord 說話者開始事件中斷使用中的播放,請加入 voice.realtime.bargeIn: true。OpenAI 即時橋接會將短於 voice.realtime.minBargeInAudioEndMs 的播放截斷視為可能的回音/雜訊並略過記錄,而不是清除 Discord 播放。
  • voice.captureSilenceGraceMs 控制 Discord 回報說話者停止後,OpenClaw 在為 STT 最終化該音訊片段前等待的時間。預設值:2000;如果 Discord 將正常停頓切成斷續的部分轉錄,請提高此值。
  • 當 ElevenLabs 是選定的 TTS 提供者時,Discord 語音播放會使用串流 TTS,並從提供者回應串流開始。沒有串流支援的提供者會退回合成暫存檔路徑。
  • OpenClaw 會監看接收解密失敗,並在短時間內重複失敗後,透過離開並重新加入語音頻道自動復原。
  • 如果更新後接收記錄反覆顯示 DecryptionFailed(UnencryptedWhenPassthroughDisabled),請收集相依性報告與記錄。內建的 @discordjs/voice 版本包含來自 discord.js PR #11449 的上游填補修正,該修正已關閉 discord.js issue #11419。
  • OpenClaw 最終化已擷取的說話者片段時,預期會出現 The operation was aborted 接收事件;它們是詳細診斷,不是警告。
  • 詳細 Discord 語音記錄會針對每個接受的說話者片段包含一行有界的 STT 轉錄預覽,因此偵錯時能同時看到使用者端與代理程式回覆端,而不會傾印無界轉錄文字。
  • agent-proxy 模式中,強制諮詢備援會略過可能不完整的轉錄片段,例如以 ... 結尾的文字,或像「and」這類結尾連接詞,以及像「be right back」或「bye」這類明顯無法採取動作的結語。當這避免了陳舊的佇列答案時,記錄會顯示 forced agent consult skipped reason=...

在語音中跟隨使用者

當你希望 Discord 語音機器人跟隨一位或多位已知 Discord 使用者,而不是在啟動時加入固定頻道或等待 /vc join 時,請使用 voice.followUsers
{
  channels: {
    discord: {
      voice: {
        enabled: true,
        followUsersEnabled: true,
        followUsers: ["discord:123456789012345678"],
        allowedChannels: [
          {
            guildId: "123456789012345678",
            channelId: "234567890123456789",
          },
        ],
      },
    },
  },
}
行為:
  • followUsers 接受原始 Discord 使用者 ID 與 discord:<id> 值。OpenClaw 會在比對語音狀態事件前正規化這兩種形式。
  • 設定 followUsers 時,followUsersEnabled 預設為 true。將其設為 false 可保留已儲存清單,但停止自動語音跟隨。
  • 當被跟隨的使用者加入允許的語音頻道時,OpenClaw 會加入該頻道。當使用者移動時,OpenClaw 會跟著移動。當目前被跟隨的使用者中斷連線時,OpenClaw 會離開。
  • 如果同一個伺服器中有多位被跟隨的使用者,且目前被跟隨的使用者離開,OpenClaw 會先移動到另一位被追蹤跟隨使用者的頻道,再離開該伺服器。如果多位被跟隨的使用者同時移動,最新觀察到的語音狀態事件優先。
  • allowedChannels 仍會套用。位於不允許頻道中的被跟隨使用者會被忽略,而跟隨擁有的工作階段會移動到另一位被跟隨使用者,或離開。
  • OpenClaw 會在啟動時及以有界間隔調和遺漏的語音狀態事件。調和會取樣已設定的伺服器,並限制每次執行的 REST 查詢數,因此非常大的 followUsers 清單可能需要超過一個間隔才能收斂。
  • 如果 Discord 或管理員在機器人跟隨使用者時移動它,OpenClaw 會重建語音工作階段,並在目的地允許時保留跟隨所有權。如果機器人被移到 allowedChannels 之外,OpenClaw 會離開,並在有設定目標時重新加入。
  • DAVE 接收復原可能會在重複解密失敗後離開並重新加入同一個頻道。跟隨擁有的工作階段會在該復原路徑中保留跟隨所有權,因此之後被跟隨使用者中斷連線時仍會離開該頻道。
選擇加入模式:
  • 對於個人或操作員設定,若機器人應在你進入語音時自動出現在語音中,請使用 followUsers
  • 對於即使沒有被追蹤使用者在語音中也應存在的固定房間機器人,請使用 autoJoin
  • 對於一次性加入,或自動語音存在會令人意外的房間,請使用 /vc join
Discord 語音編解碼器:
  • 語音接收記錄會顯示 discord voice: opus decoder: libopus-wasm
  • 即時播放會先使用相同的內建 libopus-wasm 套件,將原始 48 kHz 立體聲 PCM 編碼為 Opus,再將封包交給 @discordjs/voice
  • 檔案與提供者串流播放會使用 ffmpeg 轉碼為原始 48 kHz 立體聲 PCM,然後使用 libopus-wasm 產生傳送到 Discord 的 Opus 封包串流。
STT 加 TTS 管線:
  • Discord PCM 擷取內容會轉換成 WAV 暫存檔。
  • tools.media.audio 處理 STT,例如 openai/gpt-4o-mini-transcribe
  • 轉錄文字會透過 Discord 輸入與路由傳送,而回應 LLM 會以語音輸出政策執行,該政策會隱藏代理的 tts 工具並要求回傳文字,因為 Discord 語音負責最終的 TTS 播放。
  • voice.model 設定後,只會覆寫此語音頻道回合的回應 LLM。
  • voice.tts 會覆蓋合併到 messages.tts;支援串流的提供者會直接送入播放器,否則會在已加入的頻道中播放產生的音訊檔案。
預設 agent-proxy 語音頻道工作階段範例:
{
  channels: {
    discord: {
      voice: {
        enabled: true,
        model: "openai/gpt-5.5",
        followUsersEnabled: true,
        followUsers: ["123456789012345678"],
        realtime: {
          provider: "openai",
          model: "gpt-realtime-2",
          speakerVoice: "cedar",
        },
      },
    },
  },
}
沒有 voice.agentSession 區塊時,每個語音頻道都會取得自己的已路由 OpenClaw 工作階段。例如,/vc join channel:234567890123456789 會與該 Discord 語音頻道的工作階段對話。即時模型只是語音前端;實質請求會交給已設定的 OpenClaw 代理。如果即時模型在未呼叫諮詢工具的情況下產生最終轉錄文字,OpenClaw 會強制執行諮詢作為後援,因此預設行為仍會像是在與代理對話。 舊版 STT 加 TTS 範例:
{
  channels: {
    discord: {
      voice: {
        enabled: true,
        mode: "stt-tts",
        model: "openai/gpt-5.4-mini",
        tts: {
          provider: "openai",
          providers: {
            openai: {
              model: "gpt-4o-mini-tts",
              speakerVoice: "cedar",
            },
          },
        },
      },
    },
  },
}
即時雙向範例:
{
  channels: {
    discord: {
      voice: {
        enabled: true,
        mode: "bidi",
        model: "openai/gpt-5.5",
        realtime: {
          provider: "openai",
          model: "gpt-realtime-2",
          speakerVoice: "cedar",
          toolPolicy: "safe-read-only",
          consultPolicy: "always",
        },
      },
    },
  },
}
將語音作為既有 Discord 頻道工作階段的延伸:
{
  channels: {
    discord: {
      voice: {
        enabled: true,
        mode: "agent-proxy",
        model: "openai/gpt-5.5",
        agentSession: {
          mode: "target",
          target: "channel:123456789012345678",
        },
        realtime: {
          provider: "openai",
          model: "gpt-realtime-2",
          speakerVoice: "cedar",
        },
      },
    },
  },
}
agent-proxy 模式中,機器人會加入已設定的語音頻道,但 OpenClaw 代理回合會使用目標頻道的一般已路由工作階段與代理。即時語音工作階段會把回傳結果說回語音頻道。監督代理仍可依照其工具政策使用一般訊息工具,包括在這是正確動作時傳送另一則 Discord 訊息。 委派的 OpenClaw 執行作用中時,新的 Discord 語音轉錄文字會在開始另一個代理回合前,被視為即時執行控制。像是「status」、「cancel that」、「use the smaller fix」或「when you’re done also check tests」這類片語,會被分類為作用中工作階段的狀態、取消、引導或後續輸入。狀態、取消、已接受的引導與後續結果會說回語音頻道,讓呼叫者知道 OpenClaw 是否已處理請求。 實用的目標形式:
  • target: "channel:123456789012345678" 透過 Discord 文字頻道工作階段路由。
  • target: "123456789012345678" 會被視為頻道目標。
  • target: "dm:123456789012345678"target: "user:123456789012345678" 透過該直接訊息工作階段路由。
回聲嚴重的 OpenAI Realtime 範例:
{
  channels: {
    discord: {
      voice: {
        enabled: true,
        mode: "bidi",
        model: "openai/gpt-5.5",
        realtime: {
          provider: "openai",
          model: "gpt-realtime-2",
          speakerVoice: "cedar",
          bargeIn: true,
          minBargeInAudioEndMs: 500,
          consultPolicy: "always",
          providers: {
            openai: {
              interruptResponseOnInputAudio: false,
            },
          },
        },
      },
    },
  },
}
當模型會透過開啟的麥克風聽到自己的 Discord 播放聲,但你仍想透過說話打斷它時,請使用此設定。OpenClaw 會阻止 OpenAI 因原始輸入音訊而自動中斷,同時 bargeIn: true 讓 Discord 說話者開始事件與已作用中的說話者音訊,在下一個擷取回合到達 OpenAI 前取消作用中的即時回應。audioEndMs 低於 minBargeInAudioEndMs 的非常早期插話訊號會被視為可能是回聲/雜訊並忽略,因此模型不會在第一個播放影格就中止。 預期的語音日誌:
  • 加入時:discord voice: joining ... voiceSession=... supervisorSession=... agentSessionMode=... voiceModel=... realtimeModel=...
  • 即時啟動時:discord voice: realtime bridge starting ... autoRespond=false interruptResponse=false bargeIn=false minBargeInAudioEndMs=...
  • 說話者音訊:discord voice: realtime speaker turn opened ...discord voice: realtime input audio started ... outputAudioMs=... outputActive=...discord voice: realtime speaker turn closed ... chunks=... discordBytes=... realtimeBytes=... interruptedPlayback=...
  • 略過過時語音時:discord voice: realtime forced agent consult skipped reason=incomplete-transcript ...reason=non-actionable-closing ...
  • 即時回應完成時:discord voice: realtime audio playback finishing reason=response.done ... audioMs=... chunks=...
  • 播放停止/重設時:discord voice: realtime audio playback stopped reason=... audioMs=... elapsedMs=... chunks=...
  • 即時諮詢時:discord voice: realtime consult requested ... voiceSession=... supervisorSession=... question=...
  • 代理回答時:discord voice: agent turn answer ...
  • 佇列精確語音時:discord voice: realtime exact speech queued ... queued=... outputAudioMs=... outputActive=...,接著是 discord voice: realtime exact speech dequeued reason=player-idle ...
  • 偵測到插話時:discord voice: realtime barge-in detected source=speaker-start ...discord voice: realtime barge-in detected source=active-speaker-audio ...,接著是 discord voice: realtime barge-in requested reason=... outputAudioMs=... outputActive=...
  • 即時中斷時:discord voice: realtime model interrupt requested client:response.cancel reason=barge-in,接著是 discord voice: realtime model audio truncated client:conversation.item.truncate reason=barge-in audioEndMs=...discord voice: realtime model interrupt confirmed server:response.done status=cancelled ...
  • 忽略回聲/雜訊時:discord voice: realtime model interrupt ignored client:conversation.item.truncate.skipped reason=barge-in audioEndMs=0 minAudioEndMs=250
  • 插話停用時:discord voice: realtime capture ignored during playback (barge-in disabled) ...
  • 閒置播放時:discord voice: realtime barge-in ignored reason=... outputActive=false ... playbackChunks=0
若要除錯音訊中斷,請把即時語音日誌當作時間軸閱讀:
  1. realtime audio playback started 表示 Discord 已開始播放助理音訊。橋接器會從此時開始計算助理輸出區塊、Discord PCM 位元組、提供者即時位元組,以及合成音訊時長。
  2. realtime speaker turn opened 標記 Discord 說話者變為作用中。如果播放已經作用中且 bargeIn 已啟用,後面可能接著 barge-in detected source=speaker-start
  3. realtime input audio started 標記該說話者回合收到第一個實際音訊影格。這裡的 outputActive=true 或非零 outputAudioMs 表示麥克風在助理播放仍作用中時送出輸入。
  4. barge-in detected source=active-speaker-audio 表示 OpenClaw 在助理播放作用中時看到即時說話者音訊。這有助於區分真正的中斷與沒有實用音訊的 Discord 說話者開始事件。
  5. barge-in requested reason=... 表示 OpenClaw 要求即時提供者取消或截斷作用中的回應。它包含 outputAudioMsoutputActiveplaybackChunks,因此你可以看到中斷前實際播放了多少助理音訊。
  6. realtime audio playback stopped reason=... 是本機 Discord 播放重設點。原因會說明是誰停止播放:barge-inplayer-idleprovider-clear-audioforced-agent-consultstream-closesession-close
  7. realtime speaker turn closed 摘要擷取到的輸入回合。chunks=0hasAudio=false 表示說話者回合已開啟,但沒有可用音訊到達即時橋接器。interruptedPlayback=true 表示該輸入回合與助理輸出重疊,並觸發插話邏輯。
實用欄位:
  • outputAudioMs:即時提供者在該日誌列之前產生的助理音訊時長。
  • audioMs:OpenClaw 在播放停止前計算到的助理音訊時長。
  • elapsedMs:開啟與關閉播放串流或說話者回合之間的實際經過時間。
  • discordBytes:傳送到或接收自 Discord 語音的 48 kHz 立體聲 PCM 位元組。
  • realtimeBytes:傳送到或接收自即時提供者的提供者格式 PCM 位元組。
  • playbackChunks:轉送到 Discord 以供作用中回應使用的助理音訊區塊。
  • sinceLastAudioMs:最後擷取到的說話者音訊影格與說話者回合關閉之間的間隔。
常見模式:
  • 伴隨 source=active-speaker-audio、很小的 outputAudioMs,且附近是同一位使用者的立即中斷,通常表示喇叭回聲進入麥克風。提高 voice.realtime.minBargeInAudioEndMs、降低喇叭音量、使用耳機,或設定 voice.realtime.providers.openai.interruptResponseOnInputAudio: false
  • source=speaker-start 後接 speaker turn closed ... hasAudio=false 表示 Discord 回報說話者開始,但沒有音訊到達 OpenClaw。這可能是暫時性的 Discord 語音事件、雜訊閘行為,或用戶端短暫觸發麥克風。
  • 沒有附近插話或 provider-clear-audioaudio playback stopped reason=stream-close,表示本機 Discord 播放串流非預期結束。請檢查前面的提供者與 Discord 播放器日誌。
  • capture ignored during playback (barge-in disabled) 表示 OpenClaw 在助理音訊作用中時刻意丟棄輸入。如果你希望語音中斷播放,請啟用 voice.realtime.bargeIn
  • barge-in ignored ... outputActive=false 表示 Discord 或提供者 VAD 回報語音,但 OpenClaw 沒有可中斷的作用中播放。這不應該中斷音訊。
憑證會依元件解析:voice.model 使用 LLM 路由驗證、tools.media.audio 使用 STT 驗證、messages.tts/voice.tts 使用 TTS 驗證,而 voice.realtime.providers 或提供者的一般驗證設定使用即時提供者驗證。

語音訊息

Discord 語音訊息會顯示波形預覽,並需要 OGG/Opus 音訊。OpenClaw 會自動產生波形,但需要閘道主機上的 ffmpegffprobe 來檢查與轉換。
  • 提供本機檔案路徑(URL 會被拒絕)。
  • 省略文字內容(Discord 會拒絕在同一個承載中同時包含文字 + 語音訊息)。
  • 可接受任何音訊格式;OpenClaw 會視需要轉換為 OGG/Opus。
message(action="send", channel="discord", target="channel:123", path="/path/to/audio.mp3", asVoice=true)

疑難排解

  • 啟用 Message Content Intent
  • 當你依賴使用者/成員解析時,啟用 Server Members Intent
  • 變更 intents 後重新啟動閘道
  • 驗證 groupPolicy
  • 驗證 channels.discord.guilds 下的 guild 允許清單
  • 如果存在 guild channels 對應表,則只允許列出的頻道
  • 驗證 requireMention 行為和提及模式
實用檢查:
openclaw doctor
openclaw channels status --probe
openclaw logs --follow
常見原因:
  • groupPolicy="allowlist",但沒有相符的 guild/頻道允許清單
  • requireMention 設定在錯誤位置(必須位於 channels.discord.guilds 下,或位於頻道項目中)
  • 傳送者被 guild/頻道 users 允許清單封鎖
典型記錄:
  • Slow listener detected ...
  • stuck session: sessionKey=agent:...:discord:... state=processing ...
Discord 閘道佇列調整項目:
  • 單帳號:channels.discord.eventQueue.listenerTimeout
  • 多帳號:channels.discord.accounts.<accountId>.eventQueue.listenerTimeout
  • 這只控制 Discord 閘道監聽器工作,而不是代理回合生命週期
Discord 不會對已排隊的代理回合套用頻道擁有的逾時。訊息監聽器會立即交接,已排隊的 Discord 執行會保留每個工作階段的順序,直到工作階段/工具/執行階段生命週期完成或中止工作。
{
  channels: {
    discord: {
      accounts: {
        default: {
          eventQueue: {
            listenerTimeout: 120000,
          },
        },
      },
    },
  },
}
OpenClaw 會在連線前擷取 Discord /gateway/bot 中繼資料。暫時性失敗會退回使用 Discord 的預設閘道 URL,並在記錄中受速率限制。中繼資料逾時調整項目:
  • 單帳號:channels.discord.gatewayInfoTimeoutMs
  • 多帳號:channels.discord.accounts.<accountId>.gatewayInfoTimeoutMs
  • 未設定 config 時的 env 後援:OPENCLAW_DISCORD_GATEWAY_INFO_TIMEOUT_MS
  • 預設值:30000(30 秒),最大值:120000
OpenClaw 會在啟動期間和執行階段重新連線後等待 Discord 閘道 READY 事件。具有啟動錯開設定的多帳號配置,可能需要比預設值更長的啟動 READY 視窗。READY 逾時調整項目:
  • 啟動單帳號:channels.discord.gatewayReadyTimeoutMs
  • 啟動多帳號:channels.discord.accounts.<accountId>.gatewayReadyTimeoutMs
  • 未設定 config 時的啟動 env 後援:OPENCLAW_DISCORD_READY_TIMEOUT_MS
  • 啟動預設值:15000(15 秒),最大值:120000
  • 執行階段單帳號:channels.discord.gatewayRuntimeReadyTimeoutMs
  • 執行階段多帳號:channels.discord.accounts.<accountId>.gatewayRuntimeReadyTimeoutMs
  • 未設定 config 時的執行階段 env 後援:OPENCLAW_DISCORD_RUNTIME_READY_TIMEOUT_MS
  • 執行階段預設值:30000(30 秒),最大值:120000
channels status --probe 權限檢查只適用於數字頻道 ID。如果你使用 slug 鍵,執行階段比對仍可運作,但 probe 無法完整驗證權限。
  • DM 已停用:channels.discord.dm.enabled=false
  • DM policy 已停用:channels.discord.dmPolicy="disabled"(舊版:channels.discord.dm.policy
  • pairing 模式中等待配對核准
預設會忽略機器人撰寫的訊息。如果你設定 channels.discord.allowBots=true,請使用嚴格的提及和允許清單規則,避免迴圈行為。 建議使用 channels.discord.allowBots="mentions",只接受提及機器人的機器人訊息。OpenClaw 也內建共用的機器人迴圈保護。每當 allowBots 允許機器人撰寫的訊息送達分派時,Discord 會將傳入事件對應到 (account, channel, bot pair) 事實,通用配對防護會在該配對超過設定的事件預算後抑制它。此防護可防止過去必須靠 Discord 速率限制停止的失控雙機器人迴圈;它不會影響單一機器人部署,或維持在預算內的一次性機器人回覆。預設設定(設定 allowBots 時啟用):
  • maxEventsPerWindow: 20 — 機器人配對可在滑動視窗內交換 20 則訊息
  • windowSeconds: 60 — 滑動視窗長度
  • cooldownSeconds: 60 — 一旦觸發預算,任一方向的每一則額外機器人對機器人訊息都會在一分鐘內遭丟棄
先在 channels.defaults.botLoopProtection 下設定共用預設值一次,然後在合法工作流程需要更多餘裕時覆寫 Discord。優先順序為:
  • channels.discord.accounts.<account>.botLoopProtection
  • channels.discord.botLoopProtection
  • channels.defaults.botLoopProtection
  • 內建預設值
Discord 使用通用的 maxEventsPerWindowwindowSecondscooldownSeconds 鍵。
{
  channels: {
    defaults: {
      botLoopProtection: {
        maxEventsPerWindow: 20,
        windowSeconds: 60,
        cooldownSeconds: 60,
      },
    },
    discord: {
      // Optional Discord-wide override. Account blocks override individual
      // fields and inherit omitted fields from here.
      botLoopProtection: {
        maxEventsPerWindow: 4,
      },
      accounts: {
        alpha: {
          // Alpha listens to other bots only when they mention it.
          allowBots: "mentions",
        },
        bravo: {
          // Bravo listens to all bot-authored Discord messages.
          allowBots: true,
          mentionAliases: {
            // Lets Bravo write an Alpha Discord mention with the configured user id.
            Alpha: "ALPHA_DISCORD_USER_ID",
          },
          botLoopProtection: {
            // Allow up to five messages per minute before suppressing the pair.
            maxEventsPerWindow: 5,
            windowSeconds: 60,
            cooldownSeconds: 90,
          },
        },
      },
    },
  },
}
  • 保持 OpenClaw 為最新版本(openclaw update),讓 Discord 語音接收復原邏輯可用
  • 確認 channels.discord.voice.daveEncryption=true(預設)
  • channels.discord.voice.decryptionFailureTolerance=24(上游預設值)開始,只有在需要時才調整
  • 觀察記錄中的:
    • discord voice: DAVE decrypt failures detected
    • discord voice: repeated decrypt failures; attempting rejoin
  • 如果自動重新加入後失敗仍持續,收集記錄並與 discord.js #11419discord.js #11449 中的上游 DAVE 接收歷史比較

設定參考

主要參考:設定參考 - Discord
  • 啟動/驗證:enabledtokenapplicationIdaccounts.*allowBots
  • policy:groupPolicydmPolicyallowFromdm.*guilds.*guilds.*.channels.*
  • command:commands.nativecommands.useAccessGroups(全域)、configWritesslashCommand.ephemeral
  • 事件佇列:eventQueue.listenerTimeout(監聽器預算,預設 120000)、eventQueue.maxQueueSize(預設 10000)、eventQueue.maxConcurrency(預設 50
  • 閘道:proxygatewayInfoTimeoutMsgatewayReadyTimeoutMsgatewayRuntimeReadyTimeoutMs
  • 回覆/歷史:replyToModehistoryLimitdmHistoryLimitdms.*.historyLimit
  • 傳遞:textChunkLimit(預設 2000)、maxLinesPerMessage(預設 17
  • 串流:streaming.modestreaming.chunkModestreaming.preview.*streaming.progress.*streaming.block.*(舊版扁平 streamModedraftChunkblockStreamingblockStreamingCoalescechunkMode 鍵會由 openclaw doctor --fix 遷移到 streaming.*
  • 媒體/重試:mediaMaxMb(限制對外 Discord 上傳,預設 100)、retry
  • actions:actions.*
  • presence:activitystatusactivityTypeactivityUrlautoPresence.*
  • UI:ui.components.accentColor
  • features:threadBindings、頂層 bindings[]type: "acp")、pluralkitexecApprovalsintentsagentComponents.enabledagentComponents.ttlMsheartbeatresponsePrefix

安全與操作

  • 將機器人權杖視為秘密(在受監督環境中建議使用 DISCORD_BOT_TOKEN)。
  • 授予最低權限 Discord 權限。
  • 如果 command 部署/狀態過期,請重新啟動閘道,並使用 openclaw channels status --probe 重新檢查。

相關

配對

將 Discord 使用者配對到閘道。

群組

群組聊天和允許清單行為。

頻道路由

將傳入訊息路由到代理。

安全性

威脅模型與強化。

多代理路由

將 guild 和頻道對應到代理。

斜線命令

原生命令行為。