安裝
openclaw onboard 和 openclaw channels add --channel whatsapp 會在你首次選取外掛時提示安裝;如果缺少外掛,openclaw channels login --channel whatsapp 也會提供相同的安裝流程。開發版簽出會使用本機外掛路徑;穩定版/測試版安裝會先從 ClawHub 安裝 @openclaw/whatsapp,失敗時再改用 npm。WhatsApp 執行階段不隨 OpenClaw 核心 npm 套件提供,因此其執行階段相依套件會保留在外部外掛中。手動安裝:
@openclaw/whatsapp)用於登錄檔備援;只有需要可重現安裝時,才固定使用確切版本。
配對
未知傳送者的預設私訊原則為配對。
頻道疑難排解
跨頻道診斷與修復操作手冊。
閘道設定
完整的頻道設定模式與範例。
快速設定
1
設定存取原則
2
連結 WhatsApp(QR 碼)
3
啟動閘道
4
核准第一個私訊存取要求(配對模式)
開啟 設定 → 頻道 → 私訊存取要求,找到 WhatsApp 帳號,
然後核准傳送者。如果偏好使用命令列介面:私訊存取要求會在 1 小時後過期;每個
帳號最多可有 3 個待處理要求。此核准與用於連結
帳號本身的 WhatsApp 登入 QR 碼分開處理。
建議使用獨立的 WhatsApp 號碼(設定與中繼資料已針對此方式最佳化),但也完整支援個人號碼/自我聊天設定。
部署模式
專用號碼(建議)
專用號碼(建議)
- 為 OpenClaw 使用獨立的 WhatsApp 身分
- 更清楚的私訊允許清單與路由界線
- 降低自我聊天混淆的機率
個人號碼備援
個人號碼備援
新手引導支援個人號碼模式,並寫入適合自我聊天的基準設定:
dmPolicy: "allowlist"、allowFrom(包含你自己的號碼)、selfChatMode: true。執行階段的自我聊天防護會依據已連結的自身號碼加上 allowFrom 判定。執行階段模型
- 閘道負責管理 WhatsApp 通訊端與重新連線迴圈。
- 看門狗會分別追蹤兩個訊號:原始 WhatsApp Web 傳輸活動與應用程式訊息活動。安靜但仍保持連線的工作階段,不會只因最近沒有收到訊息就重新啟動;只有在固定的內部時間範圍內(使用者無法設定)未收到傳輸框架,或應用程式訊息靜默時間超過一般訊息逾時的 4 倍時,才會強制重新連線。最近仍有活動的工作階段剛完成重新連線時,第一個時間範圍會使用較短的一般訊息逾時,而不是 4 倍時間範圍。在該次重新連線初期,OpenClaw 可以自動回覆 Baileys 提前傳遞的離線訊息,範圍受限於傳入訊息 ID 的去重生命週期;初始啟動仍會保留較短的過時記錄防護。
- 傳出訊息時,目標帳號必須有作用中的 WhatsApp 接聽器;否則傳送會立即失敗。
- 傳送群組訊息時,如果
@+<digits>和@<digits>權杖(位於文字與媒體說明文字中)符合目前的參與者中繼資料,則會附加原生提及中繼資料,包括以 LID 為基礎的群組。 - 狀態與廣播聊天(
@status、@broadcast)會被忽略。 - 直接聊天使用私訊工作階段規則(
session.dmScope;預設的main會將私訊合併至代理程式的主要工作階段)。群組工作階段會依每個 JID 隔離(agent:<agentId>:whatsapp:group:<jid>)。 - WhatsApp 頻道/電子報可透過其原生
@newsletterJID 指定為明確的傳出目標,並使用頻道工作階段中繼資料(agent:<agentId>:whatsapp:channel:<jid>),而非私訊語意。 - WhatsApp Web 傳輸會採用閘道主機上的標準 Proxy 環境變數(
HTTPS_PROXY、HTTP_PROXY、NO_PROXY及其小寫變體)。請優先使用主機層級的 Proxy 設定,而非各頻道設定。
使用 MeowCaller 致電目前的要求者(實驗性)
外掛可在源自 WhatsApp 的代理程式回合中公開whatsapp_call。它使用 MeowCaller 向目前已授權的要求者撥打 WhatsApp 語音通話,並在對方接聽後播放 OpenClaw TTS 訊息。此工具沒有目的地號碼參數,因此提示詞無法將通話重新導向。預設停用。
1
啟用實驗性通話
將 若未設定或為
actions.calls: true 新增至 WhatsApp 頻道設定,然後重新啟動閘道:false,OpenClaw 不會公開 whatsapp_call 工具。2
安裝已審查的 MeowCaller 命令列介面
轉接器預期閘道主機的 確保閘道服務的
PATH 中有一個 meowcaller 可執行檔。在 MeowCaller PR #7 合併前,請建置已審查的分支:PATH 中包含 $HOME/.local/bin。此修訂版具有明確的 pair 與僅傳送的 notify 命令;notify 不會開啟麥克風、喇叭、視訊裝置或診斷擷取。請勿改用上游範例命令列介面的 play 命令。3
配對 MeowCaller 已連結裝置
要求 WhatsApp 代理程式檢查通話設定(以互動方式執行此命令,從 WhatsApp > Linked devices 掃描 QR 碼,並等待
whatsapp_call 狀態動作會回報帳號特定的狀態目錄與配對命令)。針對預設帳號:MeowCaller linked device ready。請將 wa-voip.db 保密,這是 MeowCaller 工作階段。非預設帳號會從狀態動作取得各自的儲存區路徑;在 Windows 上,請執行其 PowerShell 命令。4
設定 TTS 並從 WhatsApp 撥打電話
設定支援電話語音的 TTS 供應商,重新啟動閘道,然後傳送類似
Call me and say the build finished. 的要求。此工具會從受信任的傳入內容解析傳送者、合成暫時的私人 WAV 檔案、在有限的通話時間範圍內執行 MeowCaller,並在之後刪除音訊檔案。OpenClaw 會明確傳遞帳號的儲存區、等待接聽/播放/掛斷後的零退出狀態,並將逾時或非零退出視為工具呼叫失敗。核准提示
WhatsApp 可將執行與外掛核准提示呈現為👍/👎 回應,並由頂層核准轉送設定控制:
approvals.exec 與 approvals.plugin 彼此獨立;啟用 WhatsApp 頻道只會連結傳輸層,除非啟用相符的核准類別並將其路由至該處,否則不會傳送任何內容。工作階段模式只會對源自 WhatsApp 的核准傳送原生表情符號核准。目標模式會對明確目標使用共用轉送流水線,不會建立個別的核准者私訊扇出。
WhatsApp 核准回應需要在 allowFrom(或 "*")中明確指定核准者。defaultTo 設定一般預設訊息目標,而不是核准者清單。手動 /approve 命令在解析核准前,仍會經過一般的 WhatsApp 傳送者授權路徑。
問題回應
若ask_user 提示包含一個非機密的單選問題,且有一至四個選項,WhatsApp 會在選項標籤旁顯示 1️⃣ 到 4️⃣。使用相符數字回應已送達的提示即可作答。OpenClaw 會透過閘道將數字對應至標準選項;過期或重複的點選會被忽略。多問題、多選及自由文字提示仍只能以文字回覆。一般 WhatsApp 私訊/群組准入規則會授權做出回應的傳送者。
外掛掛鉤與隱私權
傳入的 WhatsApp 訊息可能含有個人內容、電話號碼、群組識別碼、傳送者名稱及工作階段關聯欄位。除非你選擇加入,否則 WhatsApp 不會將傳入的message_received 掛鉤承載資料廣播給外掛:
channels.whatsapp.accounts.<id>.pluginHooks.messageReceived 下將選擇加入的範圍限制為單一帳號。只有當你信任外掛能存取傳入的 WhatsApp 內容與識別碼時,才啟用此功能。
存取控制與啟用
- 私訊原則
- 群組政策與允許清單
- 提及與 /activation
channels.whatsapp.dmPolicy:allowFrom 接受 E.164 格式的號碼(內部會正規化)。它僅是私訊傳送者存取控制清單,不會限制明確傳送至群組 JID 或 @newsletter 頻道 JID 的外寄訊息。多帳號覆寫:channels.whatsapp.accounts.<id>.dmPolicy(以及 .allowFrom)的優先順序高於該帳號的頻道層級預設值。執行階段注意事項:- 配對會持續儲存在頻道允許清單儲存區,並與已設定的
allowFrom合併 - 排程自動化與心跳偵測收件者的備援會使用明確的傳遞目標或已設定的
allowFrom;私訊配對核准不會隱含成為排程/心跳偵測收件者 - 若未設定允許清單,預設允許已連結的自身號碼
- OpenClaw 絕不會自動配對外寄的
fromMe私訊(你從已連結裝置傳送給自己的訊息)
已設定的 ACP 繫結
WhatsApp 透過頂層bindings[] 支援持久化 ACP 繫結:
個人號碼與自我聊天行為
當已連結的自身號碼也存在於allowFrom 中時,系統會啟用自我聊天防護措施:略過自我聊天回合的已讀回條、忽略會提示你自己的提及 JID 自動觸發行為,並在頻道/帳號的 responsePrefix 未設定時,預設將回覆傳送至 [{identity.name}](或 [openclaw])。
訊息正規化與上下文
傳入封裝與回覆上下文
傳入封裝與回覆上下文
傳入訊息會封裝於共用的傳入封裝中。引用回覆會以下列形式附加上下文:系統會在可取得時填入回覆中繼資料(
ReplyToId、ReplyToBody、ReplyToSender、傳送者 JID/E.164)。若引用的目標是可下載的媒體,OpenClaw 會透過一般傳入媒體儲存區儲存該媒體,並公開 MediaPath/MediaType,讓代理程式可直接檢查,而非只看到 <media:image>。媒體預留位置與位置/聯絡人擷取
媒體預留位置與位置/聯絡人擷取
僅含媒體的訊息會正規化為預留位置:
<media:image>、<media:video>、<media:audio>、<media:document>、<media:sticker>。當訊息本文僅為 <media:audio> 時,已授權群組的語音留言會在提及閘控前進行轉錄,因此在語音留言中說出機器人提及內容即可觸發回覆。若轉錄文字仍未提及機器人,該文字會保留於待處理群組歷程記錄中,而不是保留原始預留位置。位置訊息本文會呈現為簡短的座標文字。位置標籤/註解以及聯絡人/vCard 詳細資料會呈現為圍欄式不受信任中繼資料,而非行內提示文字。待處理群組歷程記錄注入
待處理群組歷程記錄注入
未處理的群組訊息會先緩衝,並在機器人最終被觸發時注入為上下文。
- 預設限制:
50 - 設定:
channels.whatsapp.historyLimit,後備messages.groupChat.historyLimit 0會停用
[Chat messages since your last reply - for context] 和 [Current message - respond to this]。讀取回條
讀取回條
對已接受的傳入訊息預設啟用。若要全域停用:每個帳號的覆寫設定:
channels.whatsapp.accounts.<id>.sendReadReceipts。即使已全域啟用,與自己的聊天仍會略過讀取回條。傳送、分塊與媒體
文字分塊
文字分塊
- 預設分塊限制:
channels.whatsapp.textChunkLimit = 4000 channels.whatsapp.streaming.chunkMode = "length" | "newline";newline優先使用段落邊界(空白行),然後退回至符合長度安全限制的分塊方式
傳出媒體行為
傳出媒體行為
- 支援圖片、影片、音訊(PTT 語音留言)和文件酬載
- 音訊會以 Baileys
audio酬載搭配ptt: true傳送,呈現為即按即說語音留言;回覆酬載會保留audioAsVoice,讓 TTS 語音留言輸出無論提供者的來源格式為何,皆維持使用此路徑 - 原生 Ogg/Opus 音訊會以
audio/ogg; codecs=opus傳送;其他所有格式(包括 Microsoft Edge TTS 的 MP3/WebM 輸出)都會在 PTT 傳送前,使用ffmpeg轉碼為 48 kHz 單聲道 Ogg/Opus /tts latest會將最新的助理回覆作為一則語音留言傳送,並避免重複傳送同一則回覆;/tts chat on|off|default控制目前聊天的自動 TTS- 傳送影片時使用
gifPlayback: true,可啟用 GIF 動畫播放 forceDocument/asDocument會透過 Baileys 文件酬載傳送圖片、GIF 和影片,以避免 WhatsApp 的媒體壓縮,並保留解析後的檔名與 MIME 類型- 在多媒體回覆中,說明文字會套用至第一個媒體項目,但 PTT 語音留言除外:音訊會先傳送且不含說明文字,接著再以獨立文字訊息傳送說明文字(WhatsApp 用戶端無法一致地顯示語音留言說明文字)
- 媒體來源可以是 HTTP(S)、
file://或本機路徑
媒體大小限制與後備行為
媒體大小限制與後備行為
- 傳入儲存上限與傳出傳送上限:
channels.whatsapp.mediaMaxMb(預設為50) - 每個帳號的覆寫設定:
channels.whatsapp.accounts.<id>.mediaMaxMb - 除非
forceDocument/asDocument要求以文件形式傳送,否則圖片會自動最佳化(調整大小/逐步調整品質)以符合限制 - 媒體傳送失敗時,第一個項目的後備機制會傳送文字警告,而不會無聲地捨棄回覆
回覆引用
channels.whatsapp.replyToMode 控制原生回覆引用(傳出回覆會明顯引用傳入訊息):
每個帳號的覆寫設定:
channels.whatsapp.accounts.<id>.replyToMode。
表情回應層級
channels.whatsapp.reactionLevel 控制代理程式使用表情符號回應的廣泛程度:
每個帳號的覆寫設定:
channels.whatsapp.accounts.<id>.reactionLevel。
確認表情回應
channels.whatsapp.ackReaction 會在收到傳入訊息時立即傳送表情回應,並受 reactionLevel 限制(若為 "off" 則不傳送):
ackReaction 但沒有 emoji,WhatsApp 會使用路由所指代理程式身分的表情符號,並以 ”👀” 作為後備(若不需要確認表情回應,請省略 ackReaction 或設定 emoji: "");失敗會記錄於日誌,但不會阻擋回覆傳送;群組模式 mentions 僅會在由提及觸發的回合中做出表情回應,而群組啟用方式 always 會略過這項檢查;WhatsApp 僅使用 channels.whatsapp.ackReaction(舊版 messages.ackReaction 不適用於此處)。
生命週期狀態表情回應
設定messages.statusReactions.enabled: true,讓 WhatsApp 在回合期間取代確認表情回應,而非保留靜態的收件表情符號,並依序切換已排入佇列、思考中、工具活動、壓縮、完成和錯誤等狀態:
channels.whatsapp.ackReaction 仍會控制私人訊息與群組的適用資格;已排入佇列狀態使用與一般確認表情回應相同的有效表情符號;WhatsApp 每則訊息只有一個機器人表情回應欄位,因此生命週期更新會直接取代目前的表情回應,並在最終完成/錯誤狀態後還原確認表情回應。
多帳號與認證資訊
帳號選擇與預設值
帳號選擇與預設值
帳號 ID 來自
channels.whatsapp.accounts。若有 default,預設會選擇該帳號,否則選擇第一個已設定的帳號 ID(依字母順序排序)。帳號 ID 會在內部正規化,以供查詢。認證資訊路徑與舊版相容性
認證資訊路徑與舊版相容性
- 目前的驗證路徑:
~/.openclaw/credentials/whatsapp/<accountId>/creds.json(備份:creds.json.bak) - 仍會辨識/遷移
~/.openclaw/credentials/中的舊版預設驗證,以供預設帳號流程使用
登出行為
登出行為
openclaw channels logout --channel whatsapp [--account <id>] 會清除該帳號的 WhatsApp 驗證狀態。若可連線至閘道,登出時會先停止該帳號的即時監聽器,讓已連結的工作階段在下次重新啟動前停止接收訊息。openclaw channels remove --channel whatsapp 也會在停用或刪除帳號設定前停止即時監聽器。在舊版驗證目錄中,移除 Baileys 驗證檔案時會保留 oauth.json。工具、動作與設定寫入
- 代理程式工具支援包含 WhatsApp 表情回應動作(
react)。 - 動作閘門:
channels.whatsapp.actions.reactions、channels.whatsapp.actions.polls(現有動作預設為true)、channels.whatsapp.actions.calls(預設為false,請參閱上方的 MeowCaller)。 - 預設允許由頻道發起設定寫入;可透過
channels.whatsapp.configWrites: false停用。
疑難排解
尚未連結(需要 QR 碼)
尚未連結(需要 QR 碼)
症狀:頻道狀態顯示尚未連結。
已連結但中斷連線/重連迴圈
已連結但中斷連線/重連迴圈
症狀:已連結的帳號反覆中斷連線或嘗試重新連線。活動較少的帳號即使超過一般訊息逾時仍可保持連線;只有在 WhatsApp Web 傳輸活動停止、通訊端關閉,或應用程式層級活動的靜默時間超過較長的安全時限時,監視程式才會重新啟動(請參閱上方的執行階段模型)。修正方式:若修正主機連線能力與時間設定後仍持續出現迴圈,請備份帳號驗證目錄並重新連結:若
~/.openclaw/logs/whatsapp-health.log 顯示 Gateway inactive,但 openclaw gateway status 與 openclaw channels status --probe 均顯示運作正常,請執行 openclaw doctor。在 Linux 上,doctor 會針對叫用已淘汰之 ~/.openclaw/bin/ensure-whatsapp.sh 指令碼的舊版 crontab 項目發出警告;請使用 crontab -e 移除這些項目——排程可能缺少 systemd 使用者匯流排環境,導致該舊指令碼錯誤回報閘道健康狀態。透過 Proxy 登入時 QR 碼逾時
透過 Proxy 登入時 QR 碼逾時
症狀:
openclaw channels login --channel whatsapp 在顯示可用的 QR 碼前,因 status=408 Request Time-out 或 TLS 通訊端中斷連線而失敗。WhatsApp Web 登入會使用閘道主機的標準 Proxy 環境(HTTPS_PROXY、HTTP_PROXY、小寫變體、NO_PROXY)。確認閘道處理程序有繼承 Proxy 環境,且 NO_PROXY 不符合 mmg.whatsapp.net。傳送時沒有使用中的監聽器
傳送時沒有使用中的監聽器
若目標帳號沒有使用中的閘道監聽器,傳出訊息會立即失敗。請確認閘道正在執行,且帳號已連結。
回覆出現在逐字稿中,但未出現在 WhatsApp
回覆出現在逐字稿中,但未出現在 WhatsApp
逐字稿資料列會記錄代理程式產生的內容;WhatsApp 傳遞則會另外檢查。只有在 Baileys 針對至少一次可見的文字或媒體傳送回傳傳出訊息 ID 後,OpenClaw 才會將自動回覆視為已傳送。確認表情回應是獨立於回覆前的收件確認——表情回應成功不代表後續的文字/媒體回覆已獲接受。請檢查閘道日誌中是否有
auto-reply delivery failed 或 auto-reply was not accepted by WhatsApp provider。群組訊息意外遭到忽略
群組訊息意外遭到忽略
請依此順序檢查:
groupPolicy、groupAllowFrom/allowFrom、groups 允許清單項目、提及閘門(requireMention + 提及模式),以及 openclaw.json 中的重複鍵(JSON5 中較後面的項目會覆寫較前面的項目——每個範圍僅保留一個 groupPolicy)。若有 channels.whatsapp.groups,WhatsApp 仍可觀察其他群組的訊息,但 OpenClaw 會在工作階段路由前捨棄這些訊息。請將群組 JID 新增至 channels.whatsapp.groups,或新增 groups["*"] 以允許所有群組,同時繼續由 groupPolicy/groupAllowFrom 控制傳送者授權。Bun 執行階段警告
Bun 執行階段警告
OpenClaw 閘道需要 Node。Bun 不提供標準狀態儲存區所使用的
node:sqlite API,而 doctor 會將舊版 Bun 服務遷移至 Node。系統提示詞
WhatsApp 可透過groups 與 direct 對應,為群組和直接聊天提供 Telegram 風格的系統提示詞。
群組訊息的解析方式:首先決定實際使用的 groups 對應——只要帳號有定義自己的 groups 鍵,就會完全取代根層級的 groups 對應(不進行深層合併)。接著只會在這個最終產生的單一對應中查詢提示詞:
- 群組專屬提示詞(
groups["<groupId>"].systemPrompt):當群組項目存在,且其systemPrompt鍵已有定義時使用。空字串("")會抑制萬用字元,且不套用任何提示詞。 - 群組萬用字元提示詞(
groups["*"].systemPrompt):當特定群組項目不存在,或該項目存在但沒有systemPrompt鍵時使用。
direct 對應與 direct["*"] 進行解析。
dms 仍是輕量的個別私訊歷程覆寫儲存區(dms.<id>.historyLimit)。提示詞覆寫位於 direct 下。這種在提示詞解析中以帳號取代根層級的行為,是一般的淺層覆寫:任何帳號的
groups/direct 鍵(包括明確指定的空物件)都會取代根層級對應。這與上述群組成員資格允許清單檢查不同;後者針對意外為空的 groups: {} 提供單一帳號安全網。groups(即使帳號本身沒有 groups),以防止機器人接收其未加入之群組的訊息。WhatsApp 不會套用此防護——任何沒有自身覆寫的帳號都會繼承根層級的 groups/direct,不受帳號數量影響。在多帳號 WhatsApp 設定中,若要使用個別帳號提示詞,請在每個帳號下明確定義完整對應。
重要行為:
channels.whatsapp.groups同時是個別群組設定對應,以及聊天層級的群組允許清單。在根層級或帳號範圍中,groups["*"]都表示該範圍“允許所有群組”。- 只有在確定要讓該範圍允許所有群組時,才新增萬用字元
systemPrompt。若只要讓固定的一組群組 ID 符合資格,請在每個明確列入允許清單的項目中重複提示詞,而不要使用groups["*"]。 - 群組准入與傳送者授權是分開的檢查。
groups["*"]會擴大可進入群組處理程序的群組範圍,但不會授權這些群組中的所有傳送者——傳送者授權仍由groupPolicy/groupAllowFrom控制。 channels.whatsapp.direct對私訊沒有相同的附帶作用:direct["*"]只會在私訊已由dmPolicy加上allowFrom或配對儲存區規則允許後,提供預設設定。