準備好透過官方 Discord gateway 使用私訊與 guild 頻道。Documentation Index
Fetch the complete documentation index at: https://docs2.openclaw.ai/llms.txt
Use this file to discover all available pages before exploring further.
配對
Slash commands
頻道疑難排解
快速設定
你需要建立一個含有 bot 的新應用程式,將 bot 加入你的伺服器,並將它配對到 OpenClaw。我們建議將你的 bot 加入你自己的私人伺服器。如果你還沒有伺服器,請先建立一個(選擇 Create My Own > For me and my friends)。建立 Discord 應用程式與 bot
啟用特權 intents
- Message Content Intent(必要)
- Server Members Intent(建議;角色 allowlist 與名稱對 ID 比對需要)
- Presence Intent(選用;只有狀態更新需要)
複製你的 bot token
產生邀請 URL 並將 bot 加入你的伺服器
botapplications.commands
- View Channels Text Permissions
- Send Messages
- Read Message History
- Embed Links
- Attach Files
- Add Reactions(選用)
啟用 Developer Mode 並收集你的 ID
- 點擊 User Settings(你頭像旁的齒輪圖示)→ Advanced → 開啟 Developer Mode
- 在側邊欄的 伺服器圖示 上按右鍵 → Copy Server ID
- 在你自己的頭像上按右鍵 → Copy User ID
允許來自伺服器成員的私訊
安全地設定你的 bot token(不要在聊天中傳送)
openclaw gateway run 程序。
對於受管理的服務安裝,請從存在 DISCORD_BOT_TOKEN 的 shell 執行 openclaw gateway install,或將變數儲存在 ~/.openclaw/.env,如此服務才能在重新啟動後解析 env SecretRef。
如果你的主機被 Discord 的啟動應用程式查詢封鎖或受到速率限制,請從 Developer Portal 設定 Discord application/client ID,讓啟動可略過該 REST 呼叫。預設帳號使用 channels.discord.applicationId,如果執行多個 Discord bots,則使用 channels.discord.accounts.<accountId>.applicationId。設定 OpenClaw 並配對
- 詢問你的 agent
- CLI / config
“I already set my Discord bot token in config. Please finish Discord setup with User ID<user_id>and Server ID<server_id>.”
DISCORD_BOT_TOKEN 只用於預設帳號。
如果兩個已啟用的 Discord 帳號解析到相同的 bot token,OpenClaw 只會為該 token 啟動一個 gateway 監控器。來自設定的 token 優先於預設 env fallback;否則第一個已啟用的帳號勝出,重複帳號會回報為已停用。
對於進階 outbound 呼叫(message tool/channel actions),明確的每次呼叫 token 會用於該次呼叫。這適用於 send 與 read/probe 風格的動作(例如 read/search/fetch/thread/pins/permissions)。帳號 policy/retry 設定仍來自作用中 runtime snapshot 中選取的帳號。建議:設定 guild 工作區
私訊可正常使用後,你可以將 Discord 伺服器設定為完整工作區,讓每個頻道都有自己的 agent 工作階段與各自的情境。這建議用於只有你和你的 bot 的私人伺服器。將你的伺服器加入 guild allowlist
- 詢問你的 agent
- 設定
“Add my Discord Server ID <server_id> to the guild allowlist”
允許不需 @mention 即可回應
message tool 明確送出,因此 agent 可以預設潛伏,只在判斷頻道回覆有用時才發文。這表示選取的模型必須可靠地呼叫 tools。如果 Discord 顯示正在輸入且日誌顯示 token 使用量,但沒有發出的訊息,請檢查 session log 中是否有帶有 didSendViaMessagingTool: false 的 assistant text。這表示模型產生的是私密 final answer,而不是呼叫 message(action=send)。請切換到更強的 tool-calling 模型,或使用下方設定還原舊版自動 final replies。- 詢問你的 agent
- 設定
“Allow my agent to respond on this server without having to be @mentioned”
#coding、#home、#research,或任何適合你工作流程的頻道。
Runtime model
- Gateway 擁有 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 的純文字 cron/heartbeat 公告會使用最終的 助理可見答案一次。當代理發出多個可傳遞承載時,媒體和結構化元件承載仍會保持 多訊息形式。
論壇頻道
Discord 論壇和媒體頻道只接受討論串貼文。OpenClaw 支援兩種建立方式:- 傳送訊息到論壇父頻道(
channel:<forumId>)以自動建立討論串。討論串標題會使用訊息中的第一個非空行。 - 使用
openclaw message thread create直接建立討論串。不要對論壇頻道傳入--message-id。
channel:<threadId>)。
互動式元件
OpenClaw 支援代理訊息的 Discord components v2 容器。請搭配components 承載使用訊息工具。互動結果會像一般傳入訊息一樣路由回代理,並遵循現有 Discord replyToMode 設定。
支援的區塊:
text、section、separator、actions、media-gallery、file- 動作列最多允許 5 個按鈕或單一選取選單
- 選取類型:
string、user、role、mentionable、channel
components.reusable=true 可允許按鈕、選取和表單在過期前使用多次。
若要限制誰可以點擊按鈕,請在該按鈕上設定 allowedUsers(Discord 使用者 ID、標籤或 *)。設定後,不符合的使用者會收到臨時拒絕訊息。
/model 和 /models 斜線命令會開啟互動式模型選擇器,其中包含提供者、模型和相容執行階段下拉選單,並附有提交步驟。/models add 已棄用,現在會傳回棄用訊息,而不是從聊天註冊模型。選擇器回覆是臨時的,且只有呼叫的使用者可以使用。Discord 選取選單限制為 25 個選項,因此當你希望選擇器只顯示特定提供者(例如 openai-codex 或 vllm)的動態探索模型時,請將 provider/* 項目加入 agents.defaults.models。
檔案附件:
file區塊必須指向附件參照(attachment://<filename>)- 透過
media/path/filePath提供附件(單一檔案);多個檔案請使用media-gallery - 當上傳名稱應與附件參照相符時,使用
filename覆寫上傳名稱
- 加入最多 5 個欄位的
components.modal - 欄位類型:
text、checkbox、radio、select、role-select、user-select - OpenClaw 會自動加入觸發按鈕
存取控制與路由
- DM 政策
- 存取群組
- 伺服器政策
- 提及與群組私訊
channels.discord.dmPolicy 控制私訊存取。channels.discord.allowFrom 是標準私訊允許清單。pairing(預設)allowlistopen(需要channels.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.policy 和 channels.discord.dm.allowFrom 仍會為相容性而讀取。openclaw doctor --fix 會在不變更存取權的前提下,將它們遷移到 dmPolicy 和 allowFrom。傳遞用的私訊目標格式:user:<id><@id>提及
allowFrom 中的 ID 會為了相容性被視為使用者私訊目標。以角色為基礎的代理路由
使用bindings[].match.roles 依角色 ID 將 Discord 伺服器成員路由到不同代理。以角色為基礎的繫結只接受角色 ID,並在對等或父對等繫結之後、僅伺服器繫結之前評估。如果繫結也設定其他比對欄位(例如 peer + guildId + roles),所有已設定欄位都必須符合。
原生命令與命令驗證
commands.native預設為"auto",並且已為 Discord 啟用。- 每個頻道的覆寫:
channels.discord.commands.native。 commands.native=false會在啟動期間略過 Discord 斜線指令註冊與清理。先前註冊的指令可能仍會顯示在 Discord 中,直到你從 Discord 應用程式移除它們。- 原生指令授權使用與一般訊息處理相同的 Discord 允許清單/政策。
- 未獲授權的使用者可能仍會在 Discord UI 中看到指令;執行時仍會強制套用 OpenClaw 授權,並回傳「未授權」。
ephemeral: true
功能詳細資料
Reply tags and native replies
Reply tags and native replies
Live stream preview
Live stream preview
channels.discord.streaming 接受 off | partial | block | progress(預設)。progress 會保留一則可編輯的狀態草稿,並以工具進度更新它,直到最終送出;共用的起始標籤是一行滾動文字,因此一旦有足夠工作內容出現,就會像其他內容一樣捲走。streamMode 是舊版執行階段別名。執行 openclaw doctor --fix 可將持久化設定重寫為標準鍵。將 channels.discord.streaming.mode 設為 off 可停用 Discord 預覽編輯。如果明確啟用了 Discord 區塊串流,OpenClaw 會略過預覽串流,以避免重複串流。partial會在權杖抵達時編輯單一預覽訊息。block會送出草稿大小的區塊(使用draftChunk調整大小與斷點,並限制在textChunkLimit內)。- 媒體、錯誤,以及明確回覆的最終訊息會取消待處理的預覽編輯。
streaming.preview.toolProgress(預設true)控制工具/進度更新是否重用預覽訊息。- 工具/進度列會在可用時呈現為精簡的表情符號 + 標題 + 詳細資訊,例如
🛠️ Bash: run tests或🔎 Web Search: for "query"。 streaming.preview.commandText/streaming.progress.commandText控制精簡進度列中的指令/執行詳細資訊:raw(預設)或status(僅工具標籤)。
block 串流時,OpenClaw 會略過預覽串流,以避免重複串流。History, context, and thread behavior
History, context, and thread behavior
channels.discord.historyLimit預設20- 後援:
messages.groupChat.historyLimit 0會停用
channels.discord.dmHistoryLimitchannels.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會在回覆階段啟用後援期間保留。
Thread-bound sessions for subagents
Thread-bound sessions for subagents
/focus <target>將目前/新的討論串繫結到子代理/工作階段目標/unfocus移除目前討論串繫結/agents顯示作用中的執行與繫結狀態/session idle <duration|off>檢查/更新已聚焦繫結的不活動自動取消聚焦/session max-age <duration|off>檢查/更新已聚焦繫結的硬性最長期限
session.threadBindings.*設定全域預設值。channels.discord.threadBindings.*覆寫 Discord 行為。spawnSessions控制sessions_spawn({ thread: true })與 ACP 討論串衍生的自動建立/繫結討論串。預設:true。defaultSpawnContext控制討論串繫結衍生的原生子代理內容。預設:"fork"。- 已淘汰的
spawnSubagentSessions/spawnAcpSessions鍵會由openclaw doctor --fix遷移。 - 如果帳號停用了討論串繫結,
/focus與相關討論串繫結作業將無法使用。
Persistent ACP channel bindings
Persistent ACP channel bindings
bindings[]搭配type: "acp"和match.channel: "discord"
/acp spawn codex --bind here會就地繫結目前頻道或討論串,並讓未來訊息維持在相同 ACP 工作階段上。討論串訊息會繼承父頻道繫結。- 在已繫結的頻道或討論串中,
/new和/reset會就地重設相同 ACP 工作階段。暫時討論串繫結在作用中時可以覆寫目標解析。 spawnSessions會透過--thread auto|here管控子討論串建立/繫結。
Reaction notifications
Reaction notifications
offown(預設)allallowlist(使用guilds.<id>.users)
Ack reactions
Ack reactions
ackReaction 會在 OpenClaw 處理傳入訊息時送出確認表情符號。解析順序:channels.discord.accounts.<accountId>.ackReactionchannels.discord.ackReactionmessages.ackReaction- 代理身分表情符號後援(
agents.list[].identity.emoji,否則為 ”👀”)
- Discord 接受 unicode 表情符號或自訂表情符號名稱。
- 使用
""可停用頻道或帳號的反應。
Config writes
Config writes
/config set|unset 流程(啟用指令功能時)。停用:Gateway proxy
Gateway proxy
channels.discord.proxy 透過 HTTP(S) 代理路由 Discord Gateway WebSocket 流量與啟動 REST 查詢(應用程式 ID + 允許清單解析)。PluralKit support
PluralKit support
- 允許清單可以使用
pk:<memberId> - 只有在
channels.discord.dangerouslyAllowNameMatching: true時,才會依名稱/slug 比對成員顯示名稱 - 查詢會使用原始訊息 ID,且受時間範圍限制
- 如果查詢失敗,代理訊息會被視為 bot 訊息並丟棄,除非
allowBots=true
Outbound mention aliases
Outbound mention aliases
mentionAliases。鍵是不含前置 @ 的控制代碼;值是 Discord 使用者 ID。未知控制代碼、@everyone、@here,以及 Markdown 程式碼範圍內的提及會保持不變。Presence configuration
Presence configuration
- 0: 正在玩
- 1: 正在串流(需要
activityUrl) - 2: 正在聆聽
- 3: 正在觀看
- 4: 自訂(使用活動文字作為狀態內容;表情符號為選用)
- 5: 正在競賽
autoPresence.healthyTextautoPresence.degradedTextautoPresence.exhaustedText(支援{reason}預留位置)
Approvals in Discord
Approvals in Discord
channels.discord.execApprovals.enabledchannels.discord.execApprovals.approvers(選用;可行時會退回使用commands.ownerAllowFrom)channels.discord.execApprovals.target(dm|channel|both,預設值:dm)agentFilter、sessionFilter、cleanupAfterResolve
enabled 未設定或為 "auto",且至少可解析出一位核准者時,Discord 會自動啟用原生執行核准;核准者可來自 execApprovals.approvers 或 commands.ownerAllowFrom。Discord 不會從頻道 allowFrom、舊版 dm.allowFrom 或直接訊息 defaultTo 推斷執行核准者。設定 enabled: false 可明確停用 Discord 作為原生核准用戶端。對於 /diagnostics 和 /export-trajectory 等敏感的僅限擁有者群組命令,OpenClaw 會私下傳送核准提示與最終結果。當發起命令的擁有者有 Discord 擁有者路由時,它會先嘗試 Discord DM;若不可用,則退回使用 commands.ownerAllowFrom 中第一個可用的擁有者路由,例如 Telegram。當 target 為 channel 或 both 時,核准提示會在頻道中可見。只有已解析的核准者可以使用按鈕;其他使用者會收到短暫顯示的拒絕訊息。核准提示會包含命令文字,因此只有在受信任的頻道中才應啟用頻道傳送。如果無法從工作階段鍵衍生頻道 ID,OpenClaw 會退回使用 DM 傳送。Discord 也會呈現其他聊天頻道使用的共用核准按鈕。原生 Discord 轉接器主要新增核准者 DM 路由與頻道扇出。
當這些按鈕存在時,它們是主要的核准使用者體驗;OpenClaw
只有在工具結果指出聊天核准不可用,或手動核准是唯一途徑時,
才應包含手動 /approve 命令。
如果 Discord 原生核准執行階段未啟用,OpenClaw 會保留
本機決定性的 /approve <id> <decision> 提示可見。如果
執行階段已啟用,但原生卡片無法傳送至任何目標,
OpenClaw 會在同一聊天中傳送備援通知,其中包含待處理核准的確切 /approve
命令。Gateway 驗證與核准解析遵循共用 Gateway 用戶端合約(plugin: ID 透過 plugin.approval.resolve 解析;其他 ID 透過 exec.approval.resolve 解析)。核准預設會在 30 分鐘後過期。請參閱執行核准。工具與動作閘門
Discord 訊息動作包含傳訊、頻道管理、管理、presence 與中繼資料動作。 核心範例:- 傳訊:
sendMessage、readMessages、editMessage、deleteMessage、threadReply - 回應:
react、reactions、emojiList - 管理:
timeout、kick、ban - presence:
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 進行執行核准與跨情境標記。Discord 訊息動作也可以接受components 來提供自訂 UI(進階;需要透過 discord 工具建構 component 承載資料),而舊版 embeds 仍可使用,但不建議。
channels.discord.ui.components.accentColor設定 Discord component 容器使用的強調色(十六進位)。- 使用
channels.discord.accounts.<id>.ui.components.accentColor依帳戶設定。 - 當 components v2 存在時,
embeds會被忽略。
語音
Discord 有兩種不同的語音介面:即時語音頻道(連續對話)與語音訊息附件(波形預覽格式)。Gateway 支援兩者。語音頻道
設定檢查清單:- 在 Discord Developer Portal 啟用 Message Content Intent。
- 使用角色/使用者允許清單時,啟用 Server Members Intent。
- 使用
bot和applications.commands範圍邀請機器人。 - 在目標語音頻道授予 Connect、Speak、Send Messages 和 Read Message History。
- 啟用原生命令(
commands.native或channels.discord.commands.native)。 - 設定
channels.discord.voice。
/vc join|leave|status 控制工作階段。此命令會使用帳戶預設代理,並遵循與其他 Discord 命令相同的允許清單與群組政策規則。
voice.tts只會針對stt-tts語音播放覆寫messages.tts。即時模式會使用voice.realtime.voice。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是分開的。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.audio;voice.model不會影響轉錄。 - 在即時模式中,
voice.realtime.provider、voice.realtime.model與voice.realtime.voice會設定即時音訊工作階段。若要搭配 Codex 大腦使用 OpenAI Realtime 2,請使用voice.realtime.model: "gpt-realtime-2"與voice.model: "openai-codex/gpt-5.5"。 - OpenAI 即時提供者接受目前的 Realtime 2 事件名稱,以及舊版 Codex 相容的輸出音訊與轉錄事件別名,因此相容的提供者快照可以漂移,而不會遺失助理音訊。
voice.realtime.bargeIn控制 Discord 說話者開始事件是否會中斷作用中的即時播放。若未設定,它會跟隨即時提供者的輸入音訊中斷設定。voice.realtime.minBargeInAudioEndMs控制 OpenAI 即時插話截斷音訊前的最短助理播放時間。預設值:250。在低回音房間中可設為0以立即中斷,或在回音較重的喇叭設定中提高此值。- 若要在 Discord 播放中使用 OpenAI 語音,請設定
voice.tts.provider: "openai",並在voice.tts.openai.voice或voice.tts.providers.openai.voice下選擇文字轉語音語音。cedar在目前的 OpenAI TTS 模型上是很好的男性聲音選擇。 - 每個頻道的 Discord
systemPrompt覆寫會套用到該語音頻道的語音轉錄回合。 - 語音轉錄回合會從 Discord
allowFrom(或dm.allowFrom)衍生擁有者狀態;非擁有者說話者無法存取僅限擁有者的工具(例如gateway和cron)。 - Discord 語音對純文字設定是選用功能;設定
channels.discord.voice.enabled=true(或保留既有的channels.discord.voice區塊)即可啟用/vc指令、語音執行階段,以及GuildVoiceStatesGateway 意圖。 channels.discord.intents.voiceStates可以明確覆寫語音狀態意圖訂閱。保持未設定時,該意圖會跟隨有效的語音啟用狀態。- 如果
voice.autoJoin對同一個伺服器有多個項目,OpenClaw 會加入該伺服器最後設定的頻道。 voice.allowedChannels是選用的駐留允許清單。保持未設定可允許/vc join加入任何已授權的 Discord 語音頻道。設定後,/vc join、啟動時自動加入,以及機器人的語音狀態移動都會限制在列出的{ guildId, channelId }項目中。將它設定為空陣列可拒絕所有 Discord 語音加入。如果 Discord 將機器人移到允許清單之外,OpenClaw 會離開該頻道,並在有可用的已設定自動加入目標時重新加入。voice.daveEncryption與voice.decryptionFailureTolerance會傳遞至@discordjs/voice加入選項。- 如果未設定,
@discordjs/voice預設值為daveEncryption=true與decryptionFailureTolerance=24。 - OpenClaw 預設使用純 JS
opusscript解碼器接收 Discord 語音。選用的原生@discordjs/opus套件會被儲存庫的 pnpm 安裝政策忽略,因此一般安裝、Docker 跑道與無關測試不會編譯原生附加元件。專用的語音效能主機可以在安裝原生附加元件後,以OPENCLAW_DISCORD_OPUS_DECODER=native選用加入。 voice.connectTimeoutMs控制/vc join與自動加入嘗試的初始@discordjs/voiceReady 等待時間。預設值: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控制 OpenClaw 在 Discord 回報說話者已停止後,等待多久才將該音訊片段定稿給 STT。預設值:2500;如果 Discord 將正常停頓切成零碎的部分轉錄,請提高此值。- 當 ElevenLabs 是選取的 TTS 提供者時,Discord 語音播放會使用串流 TTS,並從提供者回應串流開始。不支援串流的提供者會退回合成暫存檔路徑。
- OpenClaw 也會監看接收解密失敗,並在短時間內重複失敗後,透過離開/重新加入語音頻道自動復原。
- 如果更新後接收日誌反覆顯示
DecryptionFailed(UnencryptedWhenPassthroughDisabled),請收集相依性報告與日誌。隨附的@discordjs/voice系列包含來自 discord.js PR #11449 的上游填補修正,該修正關閉了 discord.js issue #11419。 The operation was aborted接收事件是 OpenClaw 定稿已擷取說話者片段時的預期情況;它們是詳細診斷,不是警告。- 詳細 Discord 語音日誌會為每個已接受的說話者片段包含有界的一行 STT 轉錄預覽,因此偵錯時可同時看到使用者端與代理回覆端,而不會傾印無界的轉錄文字。
- 在
agent-proxy模式中,強制諮詢備援會略過可能不完整的轉錄片段,例如以...結尾的文字,或像and這類結尾連接詞,以及明顯不可操作的結語,例如「馬上回來」或「再見」。當這防止陳舊的佇列答案時,日誌會顯示forced agent consult skipped reason=...。
node-gyp 原始碼建置工具鏈。
安裝原生附加元件後,使用以下方式啟動 Gateway:
discord voice: opus decoder: @discordjs/opus。若沒有環境變數選用加入,或原生附加元件缺失或無法在主機上載入,OpenClaw 會記錄 discord voice: opus decoder: opusscript,並透過純 JS 備援持續接收語音。
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;支援串流的提供者會直接餵給播放器,否則會在已加入的頻道中播放產生的音訊檔案。
voice.agentSession 區塊時,每個語音頻道都會取得自己的路由後 OpenClaw 工作階段。例如,/vc join channel:234567890123456789 會與該 Discord 語音頻道的工作階段對話。即時模型只是語音前端;實質請求會交給已設定的 OpenClaw 代理。如果即時模型在未呼叫諮詢工具的情況下產生最終轉錄,OpenClaw 會強制執行諮詢作為備援,因此預設仍會像是在與代理對話。
舊版 STT 加 TTS 範例:
agent-proxy 模式中,機器人會加入已設定的語音頻道,但 OpenClaw 代理回合會使用目標頻道的一般路由工作階段與代理。即時語音工作階段會將回傳結果說回語音頻道。監督代理仍可根據其工具政策使用一般訊息工具,包括在那是正確動作時傳送另一則 Discord 訊息。
實用目標形式:
target: "channel:123456789012345678"透過 Discord 文字頻道工作階段路由。target: "123456789012345678"會被視為頻道目標。target: "dm:123456789012345678"或target: "user:123456789012345678"透過該直接訊息工作階段路由。
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=... - Agent 回答時:
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
realtime audio playback started表示 Discord 已開始播放助理音訊。從這一刻起,橋接會開始計算助理輸出區塊、Discord PCM 位元組、提供者即時位元組,以及合成音訊時長。realtime speaker turn opened標記 Discord 說話者變為啟用狀態。如果播放已啟用且bargeIn已啟用,後續可能出現barge-in detected source=speaker-start。realtime input audio started標記該說話者回合收到第一個實際音訊影格。此處的outputActive=true或非零outputAudioMs表示麥克風在助理播放仍啟用時傳送輸入。barge-in detected source=active-speaker-audio表示 OpenClaw 在助理播放啟用期間看到了即時說話者音訊。這有助於區分真正的中斷,以及沒有可用音訊的 Discord 說話者開始事件。barge-in requested reason=...表示 OpenClaw 要求即時提供者取消或截斷進行中的回應。它包含outputAudioMs、outputActive和playbackChunks,讓你可以看到中斷前實際已播放多少助理音訊。realtime audio playback stopped reason=...是本機 Discord 播放重設點。原因會指出是誰停止了播放:barge-in、player-idle、provider-clear-audio、forced-agent-consult、stream-close或session-close。realtime speaker turn closed會摘要擷取到的輸入回合。chunks=0或hasAudio=false表示說話者回合已開啟,但沒有可用音訊抵達即時橋接。interruptedPlayback=true表示該輸入回合與助理輸出重疊,並觸發插話邏輯。
outputAudioMs:即時提供者在該日誌行之前產生的助理音訊時長。audioMs:OpenClaw 在播放停止前計算到的助理音訊時長。elapsedMs:開啟與關閉播放串流或說話者回合之間的實際時間。discordBytes:傳送到 Discord 語音或從 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 語音事件、雜訊閘行為,或用戶端短暫按下麥克風。- 若
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 會自動產生波形,但需要 Gateway 主機上有ffmpeg 和 ffprobe 才能檢查並轉換。
- 提供本機檔案路徑(URL 會被拒絕)。
- 省略文字內容(Discord 會拒絕同一個酬載中的文字加語音訊息)。
- 接受任何音訊格式;OpenClaw 會視需要轉換為 OGG/Opus。
疑難排解
使用了不允許的 intents,或 Bot 看不到 guild 訊息
使用了不允許的 intents,或 Bot 看不到 guild 訊息
- 啟用 Message Content Intent
- 當你依賴使用者或成員解析時,啟用 Server Members Intent
- 變更 intents 後重新啟動 Gateway
Guild 訊息非預期遭封鎖
Guild 訊息非預期遭封鎖
- 驗證
groupPolicy - 驗證
channels.discord.guilds下的 guild 允許清單 - 如果存在 guild
channels對應表,則只允許列出的頻道 - 驗證
requireMention行為和提及模式
Require mention 為 false 但仍遭封鎖
Require mention 為 false 但仍遭封鎖
groupPolicy="allowlist"但沒有相符的 guild 或頻道允許清單requireMention設定在錯誤位置(必須位於channels.discord.guilds或頻道項目下)- 傳送者被 guild 或頻道
users允許清單封鎖
長時間執行的 Discord 回合或重複回覆
長時間執行的 Discord 回合或重複回覆
Slow listener detected ...stuck session: sessionKey=agent:...:discord:... state=processing ...
- 單帳戶:
channels.discord.eventQueue.listenerTimeout - 多帳戶:
channels.discord.accounts.<accountId>.eventQueue.listenerTimeout - 這只控制 Discord Gateway 監聽器工作,不控制 Agent 回合存續時間
Gateway 中繼資料查詢逾時警告
Gateway 中繼資料查詢逾時警告
/gateway/bot 中繼資料。暫時性失敗會退回使用 Discord 的預設 Gateway URL,並在日誌中進行速率限制。中繼資料逾時調整項:- 單帳戶:
channels.discord.gatewayInfoTimeoutMs - 多帳戶:
channels.discord.accounts.<accountId>.gatewayInfoTimeoutMs - 未設定組態時的環境變數後援:
OPENCLAW_DISCORD_GATEWAY_INFO_TIMEOUT_MS - 預設值:
30000(30 秒),最大值:120000
Gateway READY 逾時重新啟動
Gateway READY 逾時重新啟動
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 鍵,執行階段比對仍可運作,但 probe 無法完整驗證權限。DM 和配對問題
DM 和配對問題
- DM 已停用:
channels.discord.dm.enabled=false - DM 原則已停用:
channels.discord.dmPolicy="disabled"(舊版:channels.discord.dm.policy) - 在
pairing模式中等待配對核准
Bot 對 Bot 迴圈
Bot 對 Bot 迴圈
channels.discord.allowBots=true,請使用嚴格的提及與允許清單規則,以避免迴圈行為。
建議使用 channels.discord.allowBots="mentions",只接受提及該機器人的機器人訊息。Voice STT 因 DecryptionFailed(...) 而中斷
Voice STT 因 DecryptionFailed(...) 而中斷
- 讓 OpenClaw 保持最新(
openclaw update),確保 Discord 語音接收復原邏輯已存在 - 確認
channels.discord.voice.daveEncryption=true(預設值) - 從
channels.discord.voice.decryptionFailureTolerance=24(上游預設值)開始,僅在需要時調整 - 觀察日誌中的:
discord voice: DAVE decrypt failures detecteddiscord voice: repeated decrypt failures; attempting rejoin
- 如果自動重新加入後仍持續失敗,請收集日誌,並與 discord.js #11419 和 discord.js #11449 中的上游 DAVE 接收歷史比對
設定參考
主要參考:設定參考 - Discord。高訊號 Discord 欄位
高訊號 Discord 欄位
- 啟動/驗證:
enabled,token,accounts.*,allowBots - 政策:
groupPolicy,dm.*,guilds.*,guilds.*.channels.* - 命令:
commands.native,commands.useAccessGroups,configWrites,slashCommand.* - 事件佇列:
eventQueue.listenerTimeout(監聽器預算)、eventQueue.maxQueueSize,eventQueue.maxConcurrency - Gateway:
gatewayInfoTimeoutMs,gatewayReadyTimeoutMs,gatewayRuntimeReadyTimeoutMs - 回覆/歷史:
replyToMode,historyLimit,dmHistoryLimit,dms.*.historyLimit - 傳送:
textChunkLimit,chunkMode,maxLinesPerMessage - 串流:
streaming(舊版別名:streamMode)、streaming.preview.toolProgress,draftChunk,blockStreaming,blockStreamingCoalesce - 媒體/重試:
mediaMaxMb(限制對外 Discord 上傳,預設100MB)、retry - 動作:
actions.* - 狀態顯示:
activity,status,activityType,activityUrl - UI:
ui.components.accentColor - 功能:
threadBindings、頂層bindings[](type: "acp")、pluralkit,execApprovals,intents,agentComponents,heartbeat,responsePrefix
安全性與操作
- 將機器人 token 視為機密(受監督環境建議使用
DISCORD_BOT_TOKEN)。 - 授予最低權限的 Discord 權限。
- 如果命令部署/狀態過期,請重新啟動 gateway,並使用
openclaw channels status --probe重新檢查。