Mainstream messaging

Discord

OpenClaw 透過官方 Discord 閘道以機器人身分連線至 Discord。支援私訊與伺服器頻道。

快速設定

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

  • 建立 Discord 應用程式與機器人

    Discord Developer Portal 中,按一下 New Application 並為其命名(例如 “OpenClaw”)。

    在側邊欄開啟 Bot,並將 Username 設為你的代理程式名稱。

  • 啟用特權意圖

    仍在 Bot 頁面中,於 Privileged Gateway Intents 下啟用:

    • Message Content Intent(必要)
    • Server Members Intent(建議;角色允許清單、名稱對應 ID,以及頻道受眾存取群組需要此設定)
    • Presence Intent(選用;僅用於在線狀態更新)
  • 複製機器人權杖

    Bot 頁面中,按一下 Reset Token 並複製權杖。

  • 產生邀請網址並將機器人加入伺服器

    在側邊欄開啟 OAuth2。在 OAuth2 URL Generator 中啟用下列範圍:

    • 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

    複製產生的網址、在瀏覽器中開啟、選取你的伺服器,然後按一下 Continue。機器人現在應會出現在你的伺服器中。

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

    在 Discord 應用程式中啟用 Developer Mode,以便複製 ID:

    1. User Settings(齒輪圖示)→ Developer → 開啟 Developer Mode (行動裝置:App SettingsAdvanced
    2. 以滑鼠右鍵按一下你的伺服器圖示Copy Server ID
    3. 以滑鼠右鍵按一下你自己的頭像Copy User ID

    將 Server ID、User ID 與機器人權杖保留在一起;下一步需要這三項資料。

  • 允許來自伺服器成員的私訊

    若要讓配對正常運作,Discord 必須允許機器人傳送私訊給你。以滑鼠右鍵按一下你的伺服器圖示Privacy Settings → 開啟 Direct Messages

    如果你透過 Discord 私訊使用 OpenClaw,請保持此設定開啟。如果你只使用伺服器頻道,可以在配對完成後停用。

  • 安全地設定機器人權杖(請勿在聊天中傳送)

    機器人權杖是機密資訊。在傳訊息給代理程式之前,請先在執行 OpenClaw 的電腦上設定權杖:

    bash
    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" },},},}JSON5openclaw config patch --file ./discord.patch.json5 --dry-runopenclaw config patch --file ./discord.patch.json5openclaw gateway

    如果 OpenClaw 已經以背景服務執行,請透過 OpenClaw Mac 應用程式重新啟動,或停止後重新啟動 openclaw gateway run 程序。 若為受管理的服務安裝,請在已設定 DISCORD_BOT_TOKEN 的 shell 中執行 openclaw gateway install,或將變數儲存在 ~/.openclaw/.env,讓服務能在重新啟動後解析環境變數 SecretRef。 如果你的主機受到 Discord 啟動時應用程式查詢的封鎖或速率限制,請從 Developer Portal 設定應用程式/用戶端 ID,讓啟動程序可以略過該 REST 呼叫:預設帳號使用 channels.discord.applicationId,或每個機器人使用 channels.discord.accounts.<accountId>.applicationId

  • 設定 OpenClaw 並配對

    詢問你的代理程式

    在現有頻道(例如 Telegram)上與你的 OpenClaw 代理程式聊天並告知它。如果 Discord 是你的第一個頻道,請改用命令列介面/設定分頁。

    “我已經在設定中設好 Discord 機器人權杖。請使用 User ID <user_id> 和 Server ID <server_id> 完成 Discord 設定。”

    命令列介面/設定

    檔案型設定:

    json5
    {channels: {discord: {enabled: true,token: {source: "env",provider: "default",id: "DISCORD_BOT_TOKEN",},},},}

    預設帳號的環境變數備援:

    bash
    DISCORD_BOT_TOKEN=...

    若要進行指令碼化或遠端設定,請使用 openclaw config patch --file ./discord.patch.json5 --dry-run 寫入相同的 JSON5 區塊,然後移除 --dry-run 再次執行。純文字 token 字串也可使用,而 channels.discord.token 支援 env/file/exec 提供者的 SecretRef 值。請參閱機密資訊管理

    若使用多個 Discord 機器人,請將每個機器人的權杖與應用程式 ID 保留在各自的帳號下。頂層的 channels.discord.applicationId 會由帳號繼承,因此只有在每個帳號都使用相同的應用程式 ID 時,才應在該處設定。

    json5
    {channels: {discord: {enabled: true,accounts: {personal: {  token: { source: "env", provider: "default", id: "DISCORD_PERSONAL_TOKEN" },  applicationId: "111111111111111111",},work: {  token: { source: "env", provider: "default", id: "DISCORD_WORK_TOKEN" },  applicationId: "222222222222222222",},},},},}
  • 核准首次私訊配對

    閘道開始執行後,請在 Discord 中私訊你的機器人。它會回覆配對碼。

    詢問你的代理程式

    在現有頻道上將配對碼傳送給你的代理程式:

    “核准此 Discord 配對碼:&lt;CODE&gt;

    命令列介面

    bash
    openclaw pairing list discordopenclaw pairing approve discord &lt;CODE&gt;

    配對碼會在 1 小時後到期。核准後,即可透過 Discord 私訊與你的代理程式聊天。

  • 建議:設定伺服器工作區

    私訊正常運作後,你可以將伺服器變成完整的工作區,讓每個頻道都有具備自身內容脈絡的獨立代理程式工作階段。建議用於只有你和機器人的私人伺服器。

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

    如此一來,代理程式就能在伺服器上的任何頻道回應,而不僅限於私訊。

    詢問你的代理程式

    “將我的 Discord Server ID <server_id> 加入伺服器允許清單”

    設定

    json5
    {channels: {discord: {groupPolicy: "allowlist",guilds: {YOUR_SERVER_ID: {  requireMention: true,  users: ["YOUR_USER_ID"],},},},},}
  • 允許不使用 @提及的回應

    根據預設,代理程式只有在伺服器頻道中被 @提及時才會回應。在私人伺服器上,你可能會希望它回應每一則訊息。

    在伺服器頻道中,一般回覆預設會自動發佈。對於共用且持續開啟的聊天室,請選擇啟用 messages.groupChat.visibleReplies: "message_tool",讓代理程式可以靜默觀察,並只在判斷頻道回覆有用時發文。搭配 GPT-5.6 Sol 等最新世代且工具可靠的模型時效果最佳。除非工具傳送訊息,否則環境聊天室事件會保持靜默。完整的靜默觀察模式設定請參閱環境聊天室事件

    如果 Discord 顯示正在輸入,記錄也顯示權杖用量,但沒有發佈訊息,請檢查該輪是否設定為環境聊天室事件,或是否選擇使用訊息工具的可見回覆。

    詢問你的代理程式

    “允許我的代理程式在此伺服器上回應,不必被 @提及”

    設定

    在伺服器設定中設定 requireMention: false

    json5
    {channels: {discord: {guilds: {YOUR_SERVER_ID: {  requireMention: false,},},},},}

    若要要求可見的群組/頻道回覆必須透過訊息工具傳送,請設定 messages.groupChat.visibleReplies: "message_tool"

  • 規劃伺服器頻道中的記憶

    長期記憶(MEMORY.md)只會在私訊工作階段中自動載入;伺服器頻道不會載入。

    詢問你的代理程式

    “當我在 Discord 頻道中提問時,如果需要 MEMORY.md 中的長期內容脈絡,請使用 memory_search 或 memory_get。”

    手動

    若要在每個頻道中共用內容脈絡,請將穩定的指示放在 AGENTS.mdUSER.md 中(每個工作階段都會注入)。將長期筆記保留在 MEMORY.md 中,並視需要透過記憶工具存取。

  • 現在請建立頻道並開始聊天。代理程式可以看到頻道名稱,而每個頻道都是隔離的工作階段——請依照你的工作流程設定 #coding#home#research 或其他適合的頻道。

    執行階段模型

    • 閘道負責管理 Discord 連線。
    • 回覆路由是確定性的:來自 Discord 的輸入會回覆至 Discord。
    • Discord 伺服器/頻道中繼資料會以不受信任的內容脈絡加入模型提示,而不會作為使用者可見的回覆前綴。如果模型將該封裝複製回來,OpenClaw 會從對外回覆和未來的重播內容脈絡中移除複製的中繼資料。
    • 根據預設(session.dmScope=main),直接聊天會共用代理程式的主要工作階段(agent:main:main)。
    • 伺服器頻道使用隔離的工作階段金鑰(agent:<agentId>:discord:channel:<channelId>)。
    • 群組私訊預設會被忽略(channels.discord.dm.groupEnabled=false)。
    • 原生斜線命令會在隔離的命令工作階段(agent:<agentId>:discord:slash:<userId>)中執行,同時仍會將 CommandTargetSessionKey 帶到路由後的對話工作階段。
    • 僅含文字的排程/心跳偵測公告傳送到 Discord 時,會合併成最終可供助理看見的答案,並只傳送一次。當代理程式發出多個可傳送的承載內容時,媒體與結構化元件承載內容仍會維持多則訊息。

    論壇頻道

    Discord 論壇與媒體頻道只接受線程貼文。OpenClaw 支援兩種建立方式:

    • 傳送訊息至論壇父頻道(channel:<forumId>),即可自動建立討論串。討論串標題會採用訊息中第一個非空白行(截斷至 Discord 的 100 字元討論串名稱上限)。
    • 使用 openclaw message thread create 直接建立討論串。對論壇頻道請勿傳入 --message-id

    傳送至論壇父頻道以建立討論串:

    bash
    openclaw message send --channel discord --target channel:<forumId> \  --message "主題標題\n貼文內文"

    明確建立論壇討論串:

    bash
    openclaw message thread create --channel discord --target channel:<forumId> \  --thread-name "主題標題" --message "貼文內文"

    論壇父頻道不接受 Discord 元件。如果需要元件,請傳送至討論串本身(channel:<threadId>)。

    互動式元件

    OpenClaw 支援在代理程式訊息中使用 Discord 元件 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>
    • 透過 mediapathfilePath 提供附件(單一檔案);多個檔案請使用 media-gallery
    • 若上傳名稱應與附件參照相符,請使用 filename 覆寫上傳名稱

    互動視窗表單:

    • 新增 components.modal,最多可包含 5 個欄位
    • 欄位類型:textcheckboxradioselectrole-selectuser-select
    • OpenClaw 會自動新增觸發按鈕

    範例:

    json5
    {  channel: "discord",  action: "send",  to: "channel:123456789012345678",  message: "選用的備援文字",  components: {    reusable: true,    text: "選擇一個路徑",    blocks: [      {        type: "actions",        buttons: [          {            label: "核准",            style: "success",            allowedUsers: ["123456789012345678"],          },          { label: "拒絕", style: "danger" },        ],      },      {        type: "actions",        select: {          type: "string",          placeholder: "選擇一個選項",          options: [            { label: "選項 A", value: "a" },            { label: "選項 B", value: "b" },          ],        },      },    ],    modal: {      title: "詳細資料",      triggerLabel: "開啟表單",      fields: [        { type: "text", label: "申請者" },        {          type: "select",          label: "優先順序",          options: [            { label: "低", value: "low" },            { label: "高", value: "high" },          ],        },      ],    },  },}

    存取控制與路由

    私訊政策

    channels.discord.dmPolicy 控制私訊存取。channels.discord.allowFrom 是標準的私訊允許清單。

    • pairing(預設)
    • allowlist(至少需要一位 allowFrom 傳送者)
    • openchannels.discord.allowFrom 必須包含 "*"
    • disabled

    如果私訊政策不是開放,未知使用者會遭到封鎖(或在 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.allowFrom。若能在不變更存取權限的情況下進行遷移,openclaw doctor --fix 會將它們遷移至 dmPolicyallowFrom

    用於傳遞的私訊目標格式:

    • user:<id>
    • <@id> 提及

    啟用頻道預設值時,純數字 ID 通常會解析為頻道 ID;但為了相容性,列於帳號有效私訊 allowFrom 中的 ID 會視為使用者私訊目標。

    存取群組

    Discord 私訊和文字命令授權可在 channels.discord.allowFrom 中使用動態 accessGroup:<name> 項目。

    存取群組名稱由各訊息頻道共用。若是靜態群組,且成員使用各頻道一般的 allowFrom 語法表示,請使用 type: "message.senders";若要由 Discord 頻道目前具備 ViewChannel 權限的受眾動態定義成員資格,請使用 type: "discord.channelAudience"。共用存取群組行為:存取群組

    json5
    {accessGroups: {operators: {  type: "message.senders",  members: {    "*": ["global-owner-id"],    discord: ["discord:123456789012345678"],    telegram: ["987654321"],  },},},channels: {discord: {  dmPolicy: "allowlist",  allowFrom: ["accessGroup:operators"],},},}

    Discord 文字頻道沒有獨立的成員清單。type: "discord.channelAudience" 對成員資格的定義如下:私訊傳送者是所設定伺服器的成員,且套用身分組與頻道覆寫後,目前對所設定的頻道具有有效的 ViewChannel 權限。

    範例:允許任何能看見 #maintainers 的人私訊機器人,同時拒絕其他所有人的私訊。

    json5
    {accessGroups: {maintainers: {  type: "discord.channelAudience",  guildId: "1456350064065904867",  channelId: "1456744319972282449",  membership: "canViewChannel",},},channels: {discord: {  dmPolicy: "allowlist",  allowFrom: ["accessGroup:maintainers"],},},}

    你可以混用動態與靜態項目:

    json5
    {accessGroups: {maintainers: {  type: "discord.channelAudience",  guildId: "1456350064065904867",  channelId: "1456744319972282449",},},channels: {discord: {  dmPolicy: "allowlist",  allowFrom: ["accessGroup:maintainers", "discord:123456789012345678"],},},}

    查詢失敗時會採取封閉式拒絕。如果 Discord 回傳 Missing Access、成員查詢失敗,或頻道屬於其他伺服器,該私訊傳送者會視為未獲授權。

    使用頻道受眾存取群組時,請在 Discord Developer Portal 啟用 Server Members Intent。私訊不包含伺服器成員狀態,因此 OpenClaw 會在授權時透過 Discord REST 解析該成員。

    伺服器政策

    伺服器處理由 channels.discord.groupPolicy 控制:

    • open
    • allowlist
    • disabled

    channels.discord 存在時,安全基準為 allowlist

    allowlist 行為:

    • 伺服器必須符合 channels.discord.guilds(建議使用 id,也接受 slug)
    • 選用的傳送者允許清單:users(建議使用穩定 ID)和 roles(僅限身分組 ID);若設定任一項,傳送者符合 usersroles 即可獲准
    • 預設停用直接名稱/標籤比對;只有在需要緊急相容模式時,才啟用 channels.discord.dangerouslyAllowNameMatching: true
    • users 支援名稱/標籤,但使用 ID 更安全;使用名稱/標籤項目時,openclaw security audit 會發出警告
    • 若伺服器已設定 channels,則未列出的頻道會遭拒絕
    • 若伺服器沒有 channels 區塊,則該允許清單伺服器中的所有頻道都會獲准

    範例:

    json5
    {channels: {discord: {  groupPolicy: "allowlist",  guilds: {    "123456789012345678": {      requireMention: true,      ignoreOtherMentions: true,      users: ["987654321098765432"],      roles: ["123456789012345678"],      channels: {        general: { enabled: true },        help: { enabled: true, requireMention: true },      },    },  },},},}

    openclaw doctor --fix 會將舊版的每頻道 allow 鍵遷移至 enabled

    如果你只設定 DISCORD_BOT_TOKEN,而未建立 channels.discord 區塊,執行階段的備援值會是 groupPolicy="allowlist"(日誌中會顯示警告),即使 channels.defaults.groupPolicyopen 也一樣。

    提及與群組私訊

    伺服器訊息預設需要提及才會處理。

    提及偵測包括:

    • 明確提及機器人
    • 已設定的提及模式(agents.list[].groupChat.mentionPatterns,備援為 messages.groupChat.mentionPatterns
    • 在支援情況下,隱含的回覆機器人行為

    撰寫傳出 Discord 訊息時,請使用標準提及語法:使用者為 <@USER_ID>、頻道為 <#CHANNEL_ID>、身分組為 <@&ROLE_ID>。請勿使用舊版 <@!USER_ID> 暱稱提及格式。

    requireMention 會依伺服器/頻道設定(channels.discord.guilds...)。 ignoreOtherMentions 可選擇性丟棄提及其他使用者/身分組但未提及機器人的訊息(不含 @everyone/@here)。

    群組私訊:

    • 預設:忽略(dm.groupEnabled=false
    • 可選擇透過 dm.groupChannels 設定允許清單(頻道 ID 或 slug)

    依身分組路由代理程式

    使用 bindings[].match.roles,依身分組 ID 將 Discord 伺服器成員路由至不同的代理程式。以身分組為基礎的繫結僅接受身分組 ID,評估順序位於對等端或父對等端繫結之後、僅限伺服器的繫結之前。如果繫結也設定了其他比對欄位(例如 peer + guildId + roles),所有已設定欄位都必須相符。

    json5
    {  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 使用者介面中看到命令;執行時會強制套用 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 會維持為純連結:

    json5
    {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 結構。

    json5
    {channels: {discord: {  streaming: {    mode: "progress",    progress: {      label: "auto",      maxLines: 8,      maxLineChars: 120,      toolProgress: true,      commentary: false,    },  },},},}
    • off 會停用 Discord 預覽編輯。
    • partial 會在權杖抵達時編輯單一預覽訊息。
    • 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.commandTextstreaming.progress.commandText 控制精簡進度列中的命令/執行詳細資訊:raw(預設)或 status(僅顯示工具標籤)。

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

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

    預覽串流僅支援文字;媒體回覆會改用一般傳送方式。

    歷史記錄、上下文與討論串行為

    伺服器歷史記錄上下文:

    • channels.discord.historyLimit 預設為 20
    • 備援值:messages.groupChat.historyLimit
    • 0 表示停用

    私訊歷史記錄控制:

    • 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> 私訊目標。
    • 在回覆階段啟用備援期間,會保留 guilds.<guild>.channels.<channel>.requireMention: false

    頻道主題會以不受信任的上下文注入。允許清單限制誰能觸發代理程式,但不構成完整的補充上下文遮蔽邊界。

    子代理程式的討論串綁定工作階段

    Discord 可將討論串綁定至工作階段目標,使該討論串中的後續訊息持續路由至同一個工作階段(包括子代理程式工作階段)。

    命令:

    • /focus <target> 將目前或新的討論串綁定至子代理程式/工作階段目標
    • /unfocus 移除目前的討論串綁定
    • /agents 顯示執行中的工作與綁定狀態
    • /session idle <duration|off> 檢視/更新已聚焦綁定因閒置而自動取消聚焦的設定
    • /session max-age <duration|off> 檢視/更新已聚焦綁定的硬性最長存續時間

    設定:

    json5
    {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"
    • 已淘汰的 spawnSubagentSessionsspawnAcpSessions 設定鍵會由 openclaw doctor --fix 遷移。
    • 如果某個帳號已停用討論串綁定,則無法使用 /focus 及相關的討論串綁定操作。

    請參閱子代理程式ACP 代理程式設定參考

    持久 ACP 頻道綁定

    若要使用穩定且「永遠在線」的 ACP 工作區,請設定以 Discord 對話為目標的頂層具型別 ACP 綁定。

    設定路徑:bindings[],並使用 type: "acp"match.channel: "discord"

    json5
    {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 工作階段。

    確認回應

    OpenClaw 處理傳入訊息時,ackReaction 會傳送確認表情符號。

    解析順序:

    • channels.discord.accounts.<accountId>.ackReaction
    • channels.discord.ackReaction
    • messages.ackReaction
    • 備援使用代理程式身分表情符號(agents.list[].identity.emoji,否則使用 "👀")

    注意事項:

    • Discord 接受 Unicode 表情符號或自訂表情符號名稱。
    • 使用 "" 可停用某個頻道或帳號的回應。

    範圍(messages.ackReactionScope):

    值:"all"(私訊 + 群組,包括環境房間事件)、"direct"(僅限私訊)、"group-all"(每則群組訊息,但不包括環境房間事件,且不包含私訊)、"group-mentions"(在群組中提及機器人時;不包含私訊,預設)、"off""none"(停用)。

    寫入設定

    預設啟用由頻道發起的設定寫入。這會影響 /config set|unset 流程(啟用命令功能時)。

    停用方式:

    json5
    {channels: {discord: {  configWrites: false,},},}
    閘道 Proxy

    使用 channels.discord.proxy,透過 HTTP(S) Proxy 路由 Discord 閘道 WebSocket 流量與啟動時的 REST 查詢(應用程式 ID + 允許清單解析)。 Discord 閘道 WebSocket 的 Proxy 必須明確設定;WebSocket 連線不會繼承閘道程序中的環境 Proxy 環境變數。設定 channels.discord.proxy 時,啟動 REST 查詢會使用此 Proxy。

    json5
    {channels: {discord: {  proxy: "http://proxy.example:8080",},},}

    各帳號覆寫:

    json5
    {channels: {discord: {  accounts: {    primary: {      proxy: "http://proxy.example:8080",    },  },},},}
    PluralKit 支援

    啟用 PluralKit 解析,以將代理傳送的訊息對應至系統成員身分:

    json5
    {channels: {discord: {  pluralkit: {    enabled: true,    token: "pk_live_...", // 選填;私人系統需要  },},},}

    注意事項:

    • 允許清單可使用 pk:<memberId>
    • 僅當 channels.discord.dangerouslyAllowNameMatching: true 時,才會依名稱/slug 比對成員顯示名稱
    • 查詢會使用原始訊息 ID 呼叫 PluralKit API
    • 若查詢失敗,代理訊息會被視為機器人訊息並遭捨棄,除非 allowBots 允許其通過
    傳出提及別名

    當代理程式需要確定地提及已知的 Discord 使用者時,請使用 mentionAliases。鍵是不含開頭 @ 的代稱;值是 Discord 使用者 ID。未知代稱、@everyone@here,以及 Markdown 行內程式碼中的提及都會保持不變。

    json5
    {channels: {discord: {  mentionAliases: {    SupportLead: "123456789012345678",  },  accounts: {    ops: {      mentionAliases: {        OpsLead: "234567890123456789",      },    },  },},},}
    上線狀態設定

    當你設定狀態或活動欄位,或啟用自動上線狀態時,系統會套用上線狀態更新。

    僅設定狀態:

    json5
    {channels: {discord: {  status: "idle",},},}

    活動(設定 activity 時,預設活動類型為自訂狀態):

    json5
    {channels: {discord: {  activity: "專注時間",  activityType: 4,},},}

    直播:

    json5
    {channels: {discord: {  activity: "即時程式設計",  activityType: 1,  activityUrl: "https://twitch.tv/openclaw",},},}

    活動類型對照:

    • 0:正在玩
    • 1:正在直播(需要 activityUrl;而 activityUrl 需要 activityType: 1
    • 2:正在聆聽
    • 3:正在觀看
    • 4:自訂(將活動文字用作狀態內容;表情符號為選填)
    • 5:正在競賽

    自動上線狀態(執行階段健康狀態訊號):

    json5
    {channels: {discord: {  autoPresence: {    enabled: true,    intervalMs: 30000,    minUpdateIntervalMs: 15000,    exhaustedText: "權杖已耗盡",  },},},}

    自動上線狀態會將執行階段可用性對應至 Discord 狀態:健康 => 上線、效能降低或未知 => 閒置、已耗盡或無法使用 => 請勿打擾。預設值:intervalMs 為 30000,minUpdateIntervalMs 為 15000(必須小於或等於 intervalMs)。選用的文字覆寫項目:

    • autoPresence.healthyText
    • autoPresence.degradedText
    • autoPresence.exhaustedText(支援 {reason} 預留位置)
    Discord 中的核准

    Discord 支援在私訊中使用按鈕處理核准,也可選擇在原始頻道中發布核准提示。

    設定路徑:

    • channels.discord.execApprovals.enabled
    • channels.discord.execApprovals.approvers(選填;可行時會回退至 commands.ownerAllowFrom
    • channels.discord.execApprovals.targetdm | channel | both,預設:dm
    • agentFiltersessionFiltercleanupAfterResolve

    enabled 未設定或為 "auto",且能從 execApprovals.approverscommands.ownerAllowFrom 解析出至少一位核准者時,Discord 會自動啟用原生執行核准。Discord 不會從頻道的 allowFrom、舊版 dm.allowFrom 或私訊的 defaultTo 推斷執行核准者。若要明確停用 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 分鐘後到期。

    請參閱執行核准

    工具與動作閘門

    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 使用者介面

    OpenClaw 使用 Discord components v2 提供執行核准與跨內容脈絡標記。Discord 訊息動作也可接受 components 以建立自訂使用者介面(進階功能;需要透過 discord 工具建構元件承載內容),而舊版 embeds 仍可使用,但不建議採用。

    • channels.discord.ui.components.accentColor 設定 Discord 元件容器使用的強調色(十六進位)。各帳號設定:channels.discord.accounts.<id>.ui.components.accentColor
    • channels.discord.agentComponents.ttlMs 控制已傳送的 Discord 元件回呼維持註冊的時間長度(預設 1800000,上限 86400000)。各帳號設定:channels.discord.accounts.<id>.agentComponents.ttlMs
    • 當存在 components v2 時,embeds 會被忽略。
    • 預設會抑制純 URL 預覽。當單一傳出連結應展開時,請在訊息動作上設定 suppressEmbeds: false

    範例:

    json5
    {  channels: {    discord: {      ui: {        components: {          accentColor: "#5865F2",        },      },    },  },}

    語音

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

    語音頻道

    設定檢查清單:

    1. 在 Discord Developer Portal 中啟用 Message Content Intent。
    2. 使用角色/使用者允許清單時,啟用 Server Members Intent。
    3. 使用 botapplications.commands 範圍邀請機器人。
    4. 在目標語音頻道中授予 Connect、Speak、Send Messages 和 Read Message History 權限。
    5. 啟用原生命令(commands.nativechannels.discord.commands.native)。
    6. 設定 channels.discord.voice

    使用 /vc join|leave|status 控制工作階段。此命令使用帳號的預設代理程式,並遵循與其他 Discord 命令相同的允許清單和群組原則規則。

    bash
    /vc join channel:<voice-channel-id>/vc status/vc leave

    若要在加入前檢查機器人的有效權限:

    bash
    openclaw channels capabilities --channel discord --target channel:<voice-channel-id>

    自動加入範例:

    json5
    {  channels: {    discord: {      voice: {        enabled: true,        model: "openai/gpt-5.6-sol",        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.1",          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 用於設定即時音訊工作階段。若搭配 OpenAI Realtime 2.1 與 Codex 大腦,請使用 voice.realtime.model: "gpt-realtime-2.1"voice.model: "openai/gpt-5.6-sol"
    • 即時語音模式預設會將精簡的 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 下選擇文字轉語音的聲音。對目前的 OpenAI TTS 模型而言,cedar 是不錯的陽剛聲線選擇。
    • 各 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 的上游填補修正,該 PR 已結束 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

    json5
    {  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 會套用語音輸出原則來執行;由於 Discord 語音負責最終的 TTS 播放,因此該原則會隱藏代理程式的 tts 工具,並要求回傳文字。
    • 設定 voice.model 時,只會覆寫這次語音頻道回合所使用的回應 LLM。
    • voice.tts 會合併並覆寫 messages.tts;支援串流的提供者會直接將內容送入播放器,否則會在已加入的頻道中播放產生的音訊檔案。

    預設代理程式代理語音頻道工作階段範例:

    json5
    {  channels: {    discord: {      voice: {        enabled: true,        model: "openai/gpt-5.6-sol",        followUsersEnabled: true,        followUsers: ["123456789012345678"],        realtime: {          provider: "openai",          model: "gpt-realtime-2.1",          speakerVoice: "cedar",        },      },    },  },}

    若沒有 voice.agentSession 區塊,每個語音頻道都會取得各自路由的 OpenClaw 工作階段。例如,/vc join channel:234567890123456789 會與該 Discord 語音頻道的工作階段對話。即時模型只是語音前端;實質要求會交給已設定的 OpenClaw 代理程式。如果即時模型未呼叫諮詢工具便產生最終轉錄文字,OpenClaw 會強制執行諮詢作為後援,使預設行為仍如同與代理程式對話。

    舊版 STT 加 TTS 範例:

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

    即時雙向通訊範例:

    json5
    {  channels: {    discord: {      voice: {        enabled: true,        mode: "bidi",        model: "openai/gpt-5.6-sol",        realtime: {          provider: "openai",          model: "gpt-realtime-2.1",          speakerVoice: "cedar",          toolPolicy: "safe-read-only",          consultPolicy: "always",        },      },    },  },}

    將語音作為現有 Discord 頻道工作階段的延伸:

    json5
    {  channels: {    discord: {      voice: {        enabled: true,        mode: "agent-proxy",        model: "openai/gpt-5.6-sol",        agentSession: {          mode: "target",          target: "channel:123456789012345678",        },        realtime: {          provider: "openai",          model: "gpt-realtime-2.1",          speakerVoice: "cedar",        },      },    },  },}

    agent-proxy 模式下,機器人會加入已設定的語音頻道,但 OpenClaw 代理程式回合會使用目標頻道正常路由的工作階段與代理程式。即時語音工作階段會將回傳結果朗讀至語音頻道。監督代理程式仍可依其工具原則使用一般訊息工具,包括在適當情況下另外傳送 Discord 訊息。

    委派的 OpenClaw 執行處於作用中時,新的 Discord 語音轉錄文字會先視為即時執行控制,再決定是否啟動另一個代理程式回合。像是「狀態」、「取消那個」、「使用較小的修正」,或「完成後也檢查測試」等語句,會分類為作用中工作階段的狀態、取消、引導或後續輸入。狀態、取消、已接受的引導及後續結果都會在語音頻道中朗讀,讓呼叫者知道 OpenClaw 是否已處理要求。

    實用的目標格式:

    • target: "channel:123456789012345678" 透過 Discord 文字頻道工作階段路由。
    • target: "123456789012345678" 會視為頻道目標。
    • target: "dm:123456789012345678"target: "user:123456789012345678" 透過該私人訊息工作階段路由。

    回音嚴重時的 OpenAI Realtime 範例:

    json5
    {  channels: {    discord: {      voice: {        enabled: true,        mode: "bidi",        model: "openai/gpt-5.6-sol",        realtime: {          provider: "openai",          model: "gpt-realtime-2.1",          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=trueoutputAudioMs 非零,表示助理仍在播放時,麥克風正傳送輸入。
    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-audiooutputAudioMs 很小,且同一位使用者就在附近,通常表示喇叭回音進入了麥克風。提高 voice.realtime.minBargeInAudioEndMs、降低喇叭音量、使用耳機,或設定 voice.realtime.providers.openai.interruptResponseOnInputAudio: false
    • source=speaker-start 後接 speaker turn closed ... hasAudio=false,表示 Discord 回報說話者開始,但沒有音訊抵達 OpenClaw。這可能是暫時性的 Discord 語音事件、雜訊閘行為,或用戶端短暫啟用麥克風。
    • 若出現 audio playback stopped reason=stream-close,且附近沒有插話或 provider-clear-audio,表示本機 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。
    bash
    message(action="send", channel="discord", target="channel:123", path="/path/to/audio.mp3", asVoice=true)

    疑難排解

    使用了不允許的 intents,或機器人看不到伺服器訊息
    • 啟用 Message Content Intent
    • 當你需要解析使用者/成員時,啟用 Server Members Intent
    • 變更 intents 後重新啟動閘道
    伺服器訊息意外遭到封鎖
    • 驗證 groupPolicy
    • 驗證 channels.discord.guilds 下的伺服器允許清單
    • 如果伺服器存在 channels 對應表,則只允許列出的頻道
    • 驗證 requireMention 行為與提及模式

    實用的檢查:

    bash
    openclaw doctoropenclaw channels status --probeopenclaw logs --follow
    Require mention 為 false,但仍遭到封鎖

    常見原因:

    • groupPolicy="allowlist",但沒有相符的伺服器/頻道允許清單
    • requireMention 設定在錯誤的位置(必須位於 channels.discord.guilds 或頻道項目下)
    • 傳送者遭到伺服器/頻道的 users 允許清單封鎖
    長時間執行的 Discord 回合或重複回覆

    典型記錄:

    • Slow listener detected ...
    • stuck session: sessionKey=agent:...:discord:... state=processing ...

    Discord 閘道佇列調整項目:

    • 單一帳號:channels.discord.eventQueue.listenerTimeout
    • 多帳號:channels.discord.accounts.<accountId>.eventQueue.listenerTimeout
    • 這只控制 Discord 閘道監聽器工作,不控制代理程式回合的存續時間

    Discord 不會對排入佇列的代理程式回合套用頻道所擁有的逾時。訊息監聽器會立即移交工作,而排入佇列的 Discord 執行會維持各工作階段的順序,直到工作階段/工具/執行階段生命週期完成或中止工作。

    json5
    {channels: {discord: {  accounts: {    default: {      eventQueue: {        listenerTimeout: 120000,      },    },  },},},}
    閘道中繼資料查詢逾時警告

    OpenClaw 會在連線前擷取 Discord /gateway/bot 中繼資料。暫時性失敗會退回使用 Discord 的預設閘道 URL,且記錄會受到速率限制。

    中繼資料逾時調整項目:

    • 單一帳號:channels.discord.gatewayInfoTimeoutMs
    • 多帳號:channels.discord.accounts.<accountId>.gatewayInfoTimeoutMs
    • 未設定組態時的環境變數備援:OPENCLAW_DISCORD_GATEWAY_INFO_TIMEOUT_MS
    • 預設值:30000(30 秒),最大值:120000
    閘道 READY 逾時重新啟動

    OpenClaw 會在啟動期間及執行階段重新連線後,等待 Discord 閘道的 READY 事件。採用交錯啟動的多帳號設定,可能需要比預設值更長的啟動 READY 時限。

    READY 逾時調整項目:

    • 啟動時單一帳號:channels.discord.gatewayReadyTimeoutMs
    • 啟動時多帳號:channels.discord.accounts.<accountId>.gatewayReadyTimeoutMs
    • 未設定組態時的啟動環境變數備援:OPENCLAW_DISCORD_READY_TIMEOUT_MS
    • 啟動預設值:15000(15 秒),最大值:120000
    • 執行階段單一帳號:channels.discord.gatewayRuntimeReadyTimeoutMs
    • 執行階段多帳號:channels.discord.accounts.<accountId>.gatewayRuntimeReadyTimeoutMs
    • 未設定組態時的執行階段環境變數備援:OPENCLAW_DISCORD_RUNTIME_READY_TIMEOUT_MS
    • 執行階段預設值:30000(30 秒),最大值:120000
    權限稽核不一致

    channels status --probe 權限檢查僅適用於數字頻道 ID。

    如果你使用 slug 鍵,執行階段比對仍可運作,但探查無法完整驗證權限。

    私訊與配對問題
    • 私訊已停用:channels.discord.dm.enabled=false
    • 私訊政策已停用: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 鍵。

    json5
    {channels: {defaults: {  botLoopProtection: {    maxEventsPerWindow: 20,    windowSeconds: 60,    cooldownSeconds: 60,  },},discord: {  // 選用的 Discord 全域覆寫。帳號區塊會覆寫個別  // 欄位,並從此處繼承省略的欄位。  botLoopProtection: {    maxEventsPerWindow: 4,  },  accounts: {    alpha: {      // Alpha 僅在其他機器人提及它時才監聽。      allowBots: "mentions",    },    bravo: {      // Bravo 監聽所有由機器人撰寫的 Discord 訊息。      allowBots: true,      mentionAliases: {        // 讓 Bravo 使用設定的使用者 ID 寫入 Alpha 的 Discord 提及。        Alpha: "ALPHA_DISCORD_USER_ID",      },      botLoopProtection: {        // 每分鐘最多允許五則訊息,之後才抑制該配對。        maxEventsPerWindow: 5,        windowSeconds: 60,        cooldownSeconds: 90,      },    },  },},},}
    語音 STT 因 DecryptionFailed(...) 而中斷
    • 保持 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

    高重要性 Discord 欄位
    • 啟動/驗證:enabledtokenapplicationIdaccounts.*allowBots
    • 政策:groupPolicydmPolicyallowFromdm.*guilds.*guilds.*.channels.*
    • 命令: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.*
    • 狀態:activitystatusactivityTypeactivityUrlautoPresence.*
    • 使用者介面:ui.components.accentColor
    • 功能:threadBindings、頂層 bindings[]type: "acp")、pluralkitexecApprovalsintentsagentComponents.enabledagentComponents.ttlMsheartbeatresponsePrefix

    安全與操作

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

    相關內容

    Was this useful?
    On this page

    On this page