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 中啟用下列範圍:
botapplications.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:
- User Settings(齒輪圖示)→ Developer → 開啟 Developer Mode (行動裝置:App Settings → Advanced)
- 以滑鼠右鍵按一下你的伺服器圖示 → Copy Server ID
- 以滑鼠右鍵按一下你自己的頭像 → Copy User ID
將 Server ID、User ID 與機器人權杖保留在一起;下一步需要這三項資料。
允許來自伺服器成員的私訊
若要讓配對正常運作,Discord 必須允許機器人傳送私訊給你。以滑鼠右鍵按一下你的伺服器圖示 → Privacy Settings → 開啟 Direct Messages。
如果你透過 Discord 私訊使用 OpenClaw,請保持此設定開啟。如果你只使用伺服器頻道,可以在配對完成後停用。
安全地設定機器人權杖(請勿在聊天中傳送)
機器人權杖是機密資訊。在傳訊息給代理程式之前,請先在執行 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" },},},}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 設定。”
命令列介面/設定
檔案型設定:
{channels: {discord: {enabled: true,token: {source: "env",provider: "default",id: "DISCORD_BOT_TOKEN",},},},}預設帳號的環境變數備援:
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 時,才應在該處設定。
{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 配對碼:
<CODE>”
命令列介面
openclaw pairing list discordopenclaw pairing approve discord <CODE>配對碼會在 1 小時後到期。核准後,即可透過 Discord 私訊與你的代理程式聊天。
建議:設定伺服器工作區
私訊正常運作後,你可以將伺服器變成完整的工作區,讓每個頻道都有具備自身內容脈絡的獨立代理程式工作階段。建議用於只有你和機器人的私人伺服器。
將你的伺服器加入伺服器允許清單
如此一來,代理程式就能在伺服器上的任何頻道回應,而不僅限於私訊。
詢問你的代理程式
“將我的 Discord Server ID
<server_id>加入伺服器允許清單”
設定
{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:
{channels: {discord: {guilds: {YOUR_SERVER_ID: { requireMention: false,},},},},}若要要求可見的群組/頻道回覆必須透過訊息工具傳送,請設定 messages.groupChat.visibleReplies: "message_tool"。
規劃伺服器頻道中的記憶
長期記憶(MEMORY.md)只會在私訊工作階段中自動載入;伺服器頻道不會載入。
詢問你的代理程式
“當我在 Discord 頻道中提問時,如果需要 MEMORY.md 中的長期內容脈絡,請使用 memory_search 或 memory_get。”
手動
若要在每個頻道中共用內容脈絡,請將穩定的指示放在 AGENTS.md 或 USER.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。
傳送至論壇父頻道以建立討論串:
openclaw message send --channel discord --target channel:<forumId> \ --message "主題標題\n貼文內文"明確建立論壇討論串:
openclaw message thread create --channel discord --target channel:<forumId> \ --thread-name "主題標題" --message "貼文內文"論壇父頻道不接受 Discord 元件。如果需要元件,請傳送至討論串本身(channel:<threadId>)。
互動式元件
OpenClaw 支援在代理程式訊息中使用 Discord 元件 v2 容器。請搭配 components 承載資料使用訊息工具。互動結果會以一般傳入訊息的形式路由回代理程式,並遵循現有的 Discord replyToMode 設定。
支援的區塊:
text、section、separator、actions、media-gallery、file- 動作列最多可包含 5 個按鈕或單一選取選單
- 選取類型:
string、user、role、mentionable、channel
元件預設只能使用一次。設定 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 個選項,因此若只想讓選擇器顯示特定供應商(例如 openai 或 vllm)動態探索到的模型,請將 provider/* 項目新增至 agents.defaults.models。
檔案附件:
file區塊必須指向附件參照(attachment://<filename>)- 透過
media/path/filePath提供附件(單一檔案);多個檔案請使用media-gallery - 若上傳名稱應與附件參照相符,請使用
filename覆寫上傳名稱
互動視窗表單:
- 新增
components.modal,最多可包含 5 個欄位 - 欄位類型:
text、checkbox、radio、select、role-select、user-select - OpenClaw 會自動新增觸發按鈕
範例:
{ 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傳送者)open(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>提及
啟用頻道預設值時,純數字 ID 通常會解析為頻道 ID;但為了相容性,列於帳號有效私訊 allowFrom 中的 ID 會視為使用者私訊目標。
存取群組
Discord 私訊和文字命令授權可在 channels.discord.allowFrom 中使用動態 accessGroup:<name> 項目。
存取群組名稱由各訊息頻道共用。若是靜態群組,且成員使用各頻道一般的 allowFrom 語法表示,請使用 type: "message.senders";若要由 Discord 頻道目前具備 ViewChannel 權限的受眾動態定義成員資格,請使用 type: "discord.channelAudience"。共用存取群組行為:存取群組。
{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 的人私訊機器人,同時拒絕其他所有人的私訊。
{accessGroups: {maintainers: { type: "discord.channelAudience", guildId: "1456350064065904867", channelId: "1456744319972282449", membership: "canViewChannel",},},channels: {discord: { dmPolicy: "allowlist", allowFrom: ["accessGroup:maintainers"],},},}你可以混用動態與靜態項目:
{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 控制:
openallowlistdisabled
當 channels.discord 存在時,安全基準為 allowlist。
allowlist 行為:
- 伺服器必須符合
channels.discord.guilds(建議使用id,也接受 slug) - 選用的傳送者允許清單:
users(建議使用穩定 ID)和roles(僅限身分組 ID);若設定任一項,傳送者符合users或roles即可獲准 - 預設停用直接名稱/標籤比對;只有在需要緊急相容模式時,才啟用
channels.discord.dangerouslyAllowNameMatching: true users支援名稱/標籤,但使用 ID 更安全;使用名稱/標籤項目時,openclaw security audit會發出警告- 若伺服器已設定
channels,則未列出的頻道會遭拒絕 - 若伺服器沒有
channels區塊,則該允許清單伺服器中的所有頻道都會獲准
範例:
{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.groupPolicy 是 open 也一樣。
提及與群組私訊
伺服器訊息預設需要提及才會處理。
提及偵測包括:
- 明確提及機器人
- 已設定的提及模式(
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),所有已設定欄位都必須相符。
{ 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: true(channels.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會在權杖抵達時編輯單一預覽訊息。block會輸出草稿大小的區塊;可使用streaming.preview.chunk(minChars、maxChars、breakPreference)調整大小與分段點,並以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(僅顯示工具標籤)。
隱藏原始 command/exec 文字,同時保留精簡的進度行:
{ "channels": { "discord": { "streaming": { "mode": "progress", "progress": { "toolProgress": true, "commandText": "status" } } } }}預覽串流僅支援文字;媒體回覆會改用一般傳送方式。
歷史記錄、上下文與討論串行為
伺服器歷史記錄上下文:
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>私訊目標。 - 在回覆階段啟用備援期間,會保留
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 頻道綁定
若要使用穩定且「永遠在線」的 ACP 工作區,請設定以 Discord 對話為目標的頂層具型別 ACP 綁定。
設定路徑: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):
offown(預設)allallowlist(使用guilds.<id>.users)
回應事件會轉換為系統事件,並附加至路由指定的 Discord 工作階段。
確認回應
OpenClaw 處理傳入訊息時,ackReaction 會傳送確認表情符號。
解析順序:
channels.discord.accounts.<accountId>.ackReactionchannels.discord.ackReactionmessages.ackReaction- 備援使用代理程式身分表情符號(
agents.list[].identity.emoji,否則使用 "👀")
注意事項:
- Discord 接受 Unicode 表情符號或自訂表情符號名稱。
- 使用
""可停用某個頻道或帳號的回應。
範圍(messages.ackReactionScope):
值:"all"(私訊 + 群組,包括環境房間事件)、"direct"(僅限私訊)、"group-all"(每則群組訊息,但不包括環境房間事件,且不包含私訊)、"group-mentions"(在群組中提及機器人時;不包含私訊,預設)、"off"/"none"(停用)。
寫入設定
預設啟用由頻道發起的設定寫入。這會影響 /config set|unset 流程(啟用命令功能時)。
停用方式:
{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。
{channels: {discord: { proxy: "http://proxy.example:8080",},},}各帳號覆寫:
{channels: {discord: { accounts: { primary: { proxy: "http://proxy.example:8080", }, },},},}PluralKit 支援
啟用 PluralKit 解析,以將代理傳送的訊息對應至系統成員身分:
{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 行內程式碼中的提及都會保持不變。
{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:正在直播(需要
activityUrl;而activityUrl需要activityType: 1) - 2:正在聆聽
- 3:正在觀看
- 4:自訂(將活動文字用作狀態內容;表情符號為選填)
- 5:正在競賽
自動上線狀態(執行階段健康狀態訊號):
{channels: {discord: { autoPresence: { enabled: true, intervalMs: 30000, minUpdateIntervalMs: 15000, exhaustedText: "權杖已耗盡", },},},}自動上線狀態會將執行階段可用性對應至 Discord 狀態:健康 => 上線、效能降低或未知 => 閒置、已耗盡或無法使用 => 請勿打擾。預設值:intervalMs 為 30000,minUpdateIntervalMs 為 15000(必須小於或等於 intervalMs)。選用的文字覆寫項目:
autoPresence.healthyTextautoPresence.degradedTextautoPresence.exhaustedText(支援{reason}預留位置)
Discord 中的核准
Discord 支援在私訊中使用按鈕處理核准,也可選擇在原始頻道中發布核准提示。
設定路徑:
channels.discord.execApprovals.enabledchannels.discord.execApprovals.approvers(選填;可行時會回退至commands.ownerAllowFrom)channels.discord.execApprovals.target(dm|channel|both,預設:dm)agentFilter、sessionFilter、cleanupAfterResolve
當 enabled 未設定或為 "auto",且能從 execApprovals.approvers 或 commands.ownerAllowFrom 解析出至少一位核准者時,Discord 會自動啟用原生執行核准。Discord 不會從頻道的 allowFrom、舊版 dm.allowFrom 或私訊的 defaultTo 推斷執行核准者。若要明確停用 Discord 的原生核准用戶端,請設定 enabled: false。
對於 /diagnostics 和 /export-trajectory 等僅限擁有者使用的敏感群組命令,OpenClaw 會私下傳送核准提示和最終結果。若發出命令的擁有者具有 Discord 擁有者路由,系統會先嘗試傳送 Discord 私訊;否則會回退至 commands.ownerAllowFrom 中第一個可用的擁有者路由,例如 Telegram。
當 target 為 channel 或 both 時,頻道中的所有人都能看見核准提示。只有解析出的核准者可以使用按鈕;其他使用者會收到僅自己可見的拒絕訊息。核准提示包含命令文字,因此請只在受信任的頻道中啟用頻道傳送。若無法從工作階段鍵取得頻道 ID,OpenClaw 會回退至私訊傳送。
Discord 會呈現其他聊天頻道共用的核准按鈕;原生 Discord 轉接器主要新增核准者私訊路由和頻道分送功能。出現這些按鈕時,它們是主要的核准使用者體驗;只有當工具結果表示聊天核准無法使用,或手動核准是唯一途徑時,OpenClaw 才應包含手動 /approve 命令。若 Discord 原生核准執行階段未啟用,OpenClaw 會繼續顯示本機確定性的 /approve <id> <decision> 提示。若執行階段已啟用,但無法將原生卡片傳送至任何目標,OpenClaw 會在同一聊天中傳送回退通知,其中包含待處理核准提供的確切 /approve 命令。
閘道驗證和核准解析遵循共用的閘道用戶端契約(plugin: ID 透過 plugin.approval.resolve 解析;其他 ID 透過 exec.approval.resolve 解析)。核准預設於 30 分鐘後到期。
請參閱執行核准。
工具與動作閘門
Discord 訊息動作涵蓋傳訊、頻道管理、管理操作、上線狀態及中繼資料。
核心範例:
- 傳訊:
sendMessage、readMessages、editMessage、deleteMessage、threadReply - 回應:
react、reactions、emojiList - 管理操作:
timeout、kick、ban - 上線狀態:
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。
範例:
{ channels: { discord: { ui: { components: { accentColor: "#5865F2", }, }, }, },}語音
Discord 有兩種不同的語音介面:即時語音頻道(持續對話)和語音訊息附件(波形預覽格式)。閘道同時支援兩者。
語音頻道
設定檢查清單:
- 在 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 命令相同的允許清單和群組原則規則。
/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.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.audio;voice.model不影響轉錄。 - 在即時模式下,
voice.realtime.provider、voice.realtime.model及voice.realtime.speakerVoice用於設定即時音訊工作階段。若搭配 OpenAI Realtime 2.1 與 Codex 大腦,請使用voice.realtime.model: "gpt-realtime-2.1"及voice.model: "openai/gpt-5.6-sol"。 - 即時語音模式預設會將精簡的
IDENTITY.md、USER.md及SOUL.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.daveEncryption及voice.decryptionFailureTolerance會直接傳遞給@discordjs/voice的加入選項;上游預設值為daveEncryption=true及decryptionFailureTolerance=24。- OpenClaw 使用隨附的
libopus-wasm編解碼器來接收 Discord 語音及播放即時原始 PCM。它隨附固定版本的 libopus WebAssembly 組建,不需要原生 opus 附加元件。 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控制 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。
{ 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;支援串流的提供者會直接將內容送入播放器,否則會在已加入的頻道中播放產生的音訊檔案。
預設代理程式代理語音頻道工作階段範例:
{ 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 範例:
{ 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.6-sol", realtime: { provider: "openai", model: "gpt-realtime-2.1", speakerVoice: "cedar", toolPolicy: "safe-read-only", consultPolicy: "always", }, }, }, },}將語音作為現有 Discord 頻道工作階段的延伸:
{ 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 範例:
{ 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
若要偵錯音訊遭截斷的問題,請將即時語音日誌視為時間軸來閱讀:
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 語音或從中接收的 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 會自動產生波形,但需要閘道主機上安裝 ffmpeg 與 ffprobe,才能檢查並轉換音訊。
- 提供本機檔案路徑(不接受 URL)。
- 省略文字內容(Discord 不接受在同一個承載資料中同時包含文字與語音訊息)。
- 接受任何音訊格式;OpenClaw 會視需要轉換為 OGG/Opus。
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行為與提及模式
實用的檢查:
openclaw doctoropenclaw channels status --probeopenclaw logs --followRequire 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 執行會維持各工作階段的順序,直到工作階段/工具/執行階段生命週期完成或中止工作。
{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>.botLoopProtectionchannels.discord.botLoopProtectionchannels.defaults.botLoopProtection- 內建預設值
Discord 使用通用的 maxEventsPerWindow、windowSeconds 與 cooldownSeconds 鍵。
{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 detecteddiscord voice: repeated decrypt failures; attempting rejoin
- 如果自動重新加入後仍持續失敗,請收集記錄,並與 discord.js #11419 和 discord.js #11449 中的上游 DAVE 接收歷程比較
組態參考
主要參考:組態參考 - Discord。
高重要性 Discord 欄位
- 啟動/驗證:
enabled、token、applicationId、accounts.*、allowBots - 政策:
groupPolicy、dmPolicy、allowFrom、dm.*、guilds.*、guilds.*.channels.* - 命令:
commands.native、commands.useAccessGroups(全域)、configWrites、slashCommand.ephemeral - 事件佇列:
eventQueue.listenerTimeout(監聽器預算,預設值120000)、eventQueue.maxQueueSize(預設值10000)、eventQueue.maxConcurrency(預設值50) - 閘道:
proxy、gatewayInfoTimeoutMs、gatewayReadyTimeoutMs、gatewayRuntimeReadyTimeoutMs - 回覆/歷程:
replyToMode、historyLimit、dmHistoryLimit、dms.*.historyLimit - 傳遞:
textChunkLimit(預設值2000)、maxLinesPerMessage(預設值17) - 串流:
streaming.mode、streaming.chunkMode、streaming.preview.*、streaming.progress.*、streaming.block.*(舊版扁平streamMode、draftChunk、blockStreaming、blockStreamingCoalesce、chunkMode鍵會由openclaw doctor --fix遷移至streaming.*) - 媒體/重試:
mediaMaxMb(限制 Discord 對外上傳,預設值100)、retry - 動作:
actions.* - 狀態:
activity、status、activityType、activityUrl、autoPresence.* - 使用者介面:
ui.components.accentColor - 功能:
threadBindings、頂層bindings[](type: "acp")、pluralkit、execApprovals、intents、agentComponents.enabled、agentComponents.ttlMs、heartbeat、responsePrefix
安全與操作
- 將機器人權杖視為秘密資訊(在受監管環境中建議使用
DISCORD_BOT_TOKEN)。 - 授予最低權限的 Discord 權限。
- 如果命令部署/狀態已過時,請重新啟動閘道,並使用
openclaw channels status --probe重新檢查。