WhatsApp(Web 頻道)
狀態:透過 WhatsApp Web(Baileys)已準備好上線使用。閘道擁有已連結的工作階段。
快速設定
步驟 1:設定 WhatsApp 存取政策
{
channels: {
whatsapp: {
dmPolicy: "pairing",
allowFrom: ["+15551234567"],
groupPolicy: "allowlist",
groupAllowFrom: ["+15551234567"],
},
},
}
步驟 2:連結 WhatsApp(QR)
openclaw channels login --channel whatsapp
特定帳號:
openclaw channels login --channel whatsapp --account work
步驟 3:啟動閘道
openclaw gateway
步驟 4:核准首次配對請求(使用配對模式時)
openclaw pairing list whatsapp
openclaw pairing approve whatsapp <CODE>
配對請求在 1 小時後過期。每個頻道的待處理請求上限為 3 個。
注意: OpenClaw 建議盡可能使用獨立號碼執行 WhatsApp。(頻道中繼資料和啟用流程針對此設定最佳化,但也支援個人號碼設定。)
部署模式
專用號碼(建議)
這是最乾淨的營運模式:
- 為 OpenClaw 提供獨立的 WhatsApp 身分
- 更清晰的 DM 許可清單和路由邊界
- 較低的自聊混淆機率
最小政策模式:
```json5
{
channels: {
whatsapp: {
dmPolicy: "allowlist",
allowFrom: ["+15551234567"],
},
},
}
```
個人號碼備援
初始設定支援個人號碼模式並寫入適合自聊的基準設定:
- `dmPolicy: "allowlist"`
- `allowFrom` 包含你的個人號碼
- `selfChatMode: true`
在執行時,自聊保護會依據已連結的自身號碼和 `allowFrom` 進行判斷。
WhatsApp Web 限定的頻道範圍
在目前的 OpenClaw 頻道架構中,訊息平台頻道是基於 WhatsApp Web(`Baileys`)。
內建的聊天頻道登錄中沒有獨立的 Twilio WhatsApp 訊息頻道。
執行時模型
- 閘道擁有 WhatsApp socket 和重連迴圈。
- 對外傳送需要目標帳號有活躍的 WhatsApp 監聽器。
- 狀態和廣播聊天會被忽略(
@status、@broadcast)。 - 私訊使用 DM 工作階段規則(
session.dmScope;預設main會將 DM 合併到代理主工作階段)。 - 群組工作階段是隔離的(
agent:<agentId>:whatsapp:group:<jid>)。
存取控制與啟用
DM 政策
`channels.whatsapp.dmPolicy` 控制私訊存取:
- `pairing`(預設)
- `allowlist`
- `open`(需要 `allowFrom` 包含 `"*"`)
- `disabled`
`allowFrom` 接受 E.164 格式號碼(內部自動標準化)。
多帳號覆寫:`channels.whatsapp.accounts.<id>.dmPolicy`(和 `allowFrom`)對該帳號優先於頻道層級的預設值。
執行時行為細節:
- 配對會持久化在頻道許可儲存中,並與已設定的 `allowFrom` 合併
- 如果未設定許可清單,已連結的自身號碼預設為允許
- 對外的 `fromMe` DM 永遠不會自動配對
群組政策 + 許可清單
群組存取有兩個層次:
1. **群組成員許可清單**(`channels.whatsapp.groups`)
- 如果省略 `groups`,所有群組都有資格
- 如果 `groups` 存在,作為群組許可清單(允許 `"*"`)
2. **群組發送者政策**(`channels.whatsapp.groupPolicy` + `groupAllowFrom`)
- `open`:跳過發送者許可清單
- `allowlist`:發送者必須符合 `groupAllowFrom`(或 `*`)
- `disabled`:阻擋所有群組收件
發送者許可清單備援:
- 如果 `groupAllowFrom` 未設定,執行時會在可用時回退到 `allowFrom`
- 發送者許可清單在提及/回覆啟用之前評估
注意:如果完全沒有 `channels.whatsapp` 區塊,執行時群組政策備援為 `allowlist`(帶警告日誌),即使已設定 `channels.defaults.groupPolicy`。
提及 + /activation
群組回覆預設需要提及。
提及偵測包括:
- 對機器人身分的明確 WhatsApp 提及
- 已設定的提及正規表示式模式(`agents.list[].groupChat.mentionPatterns`,備用 `messages.groupChat.mentionPatterns`)
- 隱式回覆機器人偵測(回覆發送者符合機器人身分)
安全提示:
- 引用/回覆只滿足提及閘門;**不**授予發送者授權
- 使用 `groupPolicy: "allowlist"` 時,非許可清單的發送者即使回覆許可清單使用者的訊息仍會被阻擋
工作階段層級啟用指令:
- `/activation mention`
- `/activation always`
`activation` 更新工作階段狀態(非全域設定)。此指令受擁有者閘門限制。
個人號碼與自聊行為
當已連結的自身號碼同時出現在 allowFrom 中時,WhatsApp 自聊保護會啟用:
- 跳過自聊輪次的已讀回執
- 忽略會 ping 自己的提及 JID 自動觸發行為
- 如果
messages.responsePrefix未設定,自聊回覆預設使用[{identity.name}]或[openclaw]
訊息標準化與上下文
收件信封 + 回覆上下文
收到的 WhatsApp 訊息會包裝在共用的收件信封中。
如果存在引用回覆,上下文會以此形式附加:
```text
[Replying to <sender> id:<stanzaId>]
<quoted body or media placeholder>
[/Replying]
```
回覆中繼資料欄位在可用時也會填充(`ReplyToId`、`ReplyToBody`、`ReplyToSender`、發送者 JID/E.164)。
媒體佔位符與位置/聯絡人擷取
僅含媒體的收件訊息會以佔位符標準化,例如:
- `<media:image>`
- `<media:video>`
- `<media:audio>`
- `<media:document>`
- `<media:sticker>`
位置和聯絡人內容會在路由前標準化為文字上下文。
待處理群組歷史注入
群組中未處理的訊息可以被緩衝並在機器人最終被觸發時作為上下文注入。
- 預設限制:`50`
- 設定:`channels.whatsapp.historyLimit`
- 備援:`messages.groupChat.historyLimit`
- `0` 為停用
注入標記:
- `[Chat messages since your last reply - for context]`
- `[Current message - respond to this]`
已讀回執
對已接受的 WhatsApp 收件訊息,已讀回執預設為啟用。
全域停用:
```json5
{
channels: {
whatsapp: {
sendReadReceipts: false,
},
},
}
```
按帳號覆寫:
```json5
{
channels: {
whatsapp: {
accounts: {
work: {
sendReadReceipts: false,
},
},
},
},
}
```
即使全域啟用,自聊輪次也會跳過已讀回執。
送達、分段與媒體
文字分段
- 預設分段限制:`channels.whatsapp.textChunkLimit = 4000`
- `channels.whatsapp.chunkMode = "length" | "newline"`
- `newline` 模式優先依段落邊界(空白行)分割,再退回到長度安全分段
傳出媒體行為
- 支援圖片、視訊、音訊(PTT 語音備忘錄)和文件類型
- `audio/ogg` 會改寫為 `audio/ogg; codecs=opus` 以相容語音備忘錄
- 動態 GIF 播放透過視訊傳送時的 `gifPlayback: true` 支援
- 說明文字套用到多媒體回覆中的第一個媒體項目
- 媒體來源可以是 HTTP(S)、`file://` 或本機路徑
媒體大小限制與備援行為
- 收件媒體儲存上限:`channels.whatsapp.mediaMaxMb`(預設 `50`)
- 傳出媒體傳送上限:`channels.whatsapp.mediaMaxMb`(預設 `50`)
- 按帳號覆寫使用 `channels.whatsapp.accounts.<accountId>.mediaMaxMb`
- 圖片會自動最佳化(調整大小/品質掃描)以符合限制
- 媒體傳送失敗時,第一項目備援會傳送文字警告而非靜默丟棄回應
確認反應
WhatsApp 支援透過 channels.whatsapp.ackReaction 在收到訊息時立即傳送確認反應。
{
channels: {
whatsapp: {
ackReaction: {
emoji: "👀",
direct: true,
group: "mentions", // always | mentions | never
},
},
},
}
行為說明:
- 在收件被接受後立即傳送(回覆之前)
- 失敗會記錄但不會阻擋正常的回覆送達
- 群組模式
mentions在提及觸發的輪次時反應;群組啟用always作為此檢查的繞過 - WhatsApp 使用
channels.whatsapp.ackReaction(此處不使用舊版messages.ackReaction)
多帳號與憑證
帳號選擇與預設值
- 帳號 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 認證狀態。
在舊版認證目錄中,`oauth.json` 會保留,而 Baileys 認證檔案會被移除。
工具、動作與設定寫入
- 代理工具支援包括 WhatsApp 反應動作(
react)。 - 動作閘門:
channels.whatsapp.actions.reactionschannels.whatsapp.actions.polls
- 頻道觸發的設定寫入預設為啟用(停用方式:
channels.whatsapp.configWrites=false)。
疑難排解
未連結(需要 QR)
症狀:頻道狀態回報未連結。
修復:
```bash
openclaw channels login --channel whatsapp
openclaw channels status
```
已連結但斷線 / 重連迴圈
症狀:已連結的帳號持續斷線或重連。
修復:
```bash
openclaw doctor
openclaw logs --follow
```
如有需要,使用 `channels login` 重新連結。
傳送時無活躍監聽器
當目標帳號沒有活躍的閘道監聽器時,對外傳送會立即失敗。
確認閘道正在執行且帳號已連結。
群組訊息意外被忽略
依此順序檢查:
- `groupPolicy`
- `groupAllowFrom` / `allowFrom`
- `groups` 許可清單項目
- 提及閘門(`requireMention` + 提及模式)
- `openclaw.json`(JSON5)中的重複鍵:後面的項目會覆寫前面的,因此每個範圍保持單一 `groupPolicy`
Bun 執行時警告
WhatsApp 閘道執行時應使用 Node。Bun 被標記為不相容於穩定的 WhatsApp/Telegram 閘道運作。
設定參考指引
主要參考:
WhatsApp 高信號欄位:
- 存取:
dmPolicy、allowFrom、groupPolicy、groupAllowFrom、groups - 送達:
textChunkLimit、chunkMode、mediaMaxMb、sendReadReceipts、ackReaction - 多帳號:
accounts.<id>.enabled、accounts.<id>.authDir、帳號層級覆寫 - 營運:
configWrites、debounceMs、web.enabled、web.heartbeatSeconds、web.reconnect.* - 工作階段行為:
session.dmScope、historyLimit、dmHistoryLimit、dms.<id>.historyLimit