WhatsApp 通道
状态:通过 Baileys 使用 WhatsApp Web。网关拥有会话。
快速设置(入门)
- 如果可能,使用单独的手机号码(推荐)。
- 在
~/.openclaw/openclaw.json中配置 WhatsApp。 - 运行
openclaw channels login扫描二维码(关联设备)。 - 启动网关。
最小配置:
{
channels: {
whatsapp: {
dmPolicy: "allowlist",
allowFrom: ["+15551234567"]
}
}
}设计目标
- 在一个网关进程中支持多个 WhatsApp 账户(多账户)。
- 确定性路由:回复返回 WhatsApp,无模型路由。
- 模型看到足够的上下文来理解引用的回复。
配置写入
默认情况下,WhatsApp 允许通过 /config set|unset 触发的配置更新(需要 commands.config: true)。
禁用:
{
channels: { whatsapp: { configWrites: false } }
}架构(职责划分)
- 网关拥有 Baileys 套接字和收件箱循环。
- CLI / macOS 应用与网关通信;不使用直接的 Baileys。
- 活动监听器是出站发送所必需的;否则发送会快速失败。
获取手机号码(两种模式)
WhatsApp 需要真实的手机号码进行验证。VoIP 和虚拟号码通常被屏蔽。支持两种运行 OpenClaw 的方式:
专用号码(推荐)
为 OpenClaw 使用单独的手机号码。最佳体验,清晰的路由,无自聊怪癖。理想设置:备用/旧安卓手机 + eSIM。保持 Wi-Fi 和电源连接,通过 QR 关联。
WhatsApp Business: 可以在同一设备上使用 WhatsApp Business 与不同号码。非常适合保持个人 WhatsApp 分离 —— 安装 WhatsApp Business 并在其中注册 OpenClaw 号码。
示例配置(专用号码,单用户允许列表):
{
channels: {
whatsapp: {
dmPolicy: "allowlist",
allowFrom: ["+15551234567"]
}
}
}配对模式(可选): 如果想要配对而非允许列表,将 channels.whatsapp.dmPolicy 设置为 pairing。未知发送者会收到配对代码;通过以下方式批准: openclaw pairing approve whatsapp <code>
个人号码(备用方案)
快速备用方案:在你自己的号码上运行 OpenClaw。向自己发送消息(WhatsApp"给自己发消息")进行测试,以免骚扰联系人。预计在设置和实验期间需要在主手机上读取验证码。必须启用自聊模式。 当向导询问你的个人 WhatsApp 号码时,输入你将从中发送消息的电话(所有者/发送者),而不是助手号码。
示例配置(个人号码,自聊):
{
"whatsapp": {
"selfChatMode": true,
"dmPolicy": "allowlist",
"allowFrom": ["+15551234567"]
}
}当设置时,自聊回复默认为 [{identity.name}](否则为 [openclaw]),如果 messages.responsePrefix 未设置。显式设置它以自定义或禁用前缀(使用 "" 移除)。
号码来源建议
避免: TextNow、Google Voice、大多数"免费短信"服务 —— WhatsApp 严厉阻止这些。
提示: 号码只需接收一条验证短信。之后,WhatsApp Web 会话通过 creds.json 持久化。
为什么不用 Twilio?
- 早期 OpenClaw 版本支持 Twilio 的 WhatsApp Business 集成。
- WhatsApp Business 号码不适合个人助手。
- Meta 强制执行 24 小时回复窗口;如果您在过去 24 小时内没有回复,企业号码无法发起新消息。
- 高音量或"聊天"使用会触发积极阻止,因为企业账户不适合发送数十条个人助手消息。
- 结果:不可靠的投递和频繁的阻止,因此移除了支持。
登录 + 凭证
- 登录命令:
openclaw channels login(通过关联设备显示二维码)。 - 多账户登录:
openclaw channels login --account <id>(<id>=accountId)。 - 默认账户(省略
--account时):如果存在则为default,否则为第一个配置的账户 ID(排序后)。 - 凭证存储在
~/.openclaw/credentials/whatsapp/<accountId>/creds.json。 - 备份副本位于
creds.json.bak(损坏时恢复)。 - 旧版兼容性:旧安装将 Baileys 文件直接存储在
~/.openclaw/credentials/中。 - 注销:
openclaw channels logout(或--account <id>)删除 WhatsApp 认证状态(但保留共享的oauth.json)。 - 注销的套接字 => 错误指示重新关联。
入站流程(DM + 群组)
- WhatsApp 事件来自
messages.upsert(Baileys)。 - 关闭时会分离收件箱监听器,以避免在测试/重启中累积事件处理程序。
- 状态/广播聊天被忽略。
- 直接聊天使用 E.164;群组使用群组 JID。
- DM 策略:
channels.whatsapp.dmPolicy控制直接聊天访问(默认:pairing)。- 配对:未知发送者收到配对代码(通过
openclaw pairing approve whatsapp <code>批准;代码 1 小时后过期)。 - 开放:需要
channels.whatsapp.allowFrom包含"*"。 - 你关联的 WhatsApp 号码被隐式信任,因此自消息跳过
channels.whatsapp.dmPolicy和channels.whatsapp.allowFrom检查。
- 配对:未知发送者收到配对代码(通过
个人号码模式(备用)
如果您在个人 WhatsApp 号码上运行 OpenClaw,启用 channels.whatsapp.selfChatMode(见上文示例)。
行为:
- 出站 DM 永远不会触发配对回复(防止骚扰联系人)。
- 未知入站发送者仍遵循
channels.whatsapp.dmPolicy。 - 自聊模式(allowFrom 包含您的号码)避免自动已读回执并忽略提及 JID。
- 非自聊 DM 发送已读回执。
已读回执
默认情况下,网关在收到 WhatsApp 入站消息后将其标记为已读(蓝勾)。
全局禁用:
{
channels: { whatsapp: { sendReadReceipts: false } }
}按账户禁用:
{
channels: {
whatsapp: {
accounts: {
personal: { sendReadReceipts: false }
}
}
}
}注意:
- 自聊模式始终跳过已读回执。
WhatsApp 常见问题:发送消息 + 配对
当我关联 WhatsApp 时,OpenClaw 会向随机联系人发送消息吗?
不会。默认 DM 策略是配对,因此未知发送者只会收到配对代码,并且他们的消息不会被处理。OpenClaw 只回复它收到的聊天,或您明确触发的发送(智能体/CLI)。
配对如何在 WhatsApp 上工作?
配对是未知发送者的 DM 门控:
- 新发送者的第一条 DM 返回一个短代码(消息不会被处理)。
- 批准:
openclaw pairing approve whatsapp <code>(通过openclaw pairing list whatsapp列出)。 - 代码 1 小时后过期;每个通道的待处理请求上限为 3 个。
多个人可以在一个 WhatsApp 号码上使用不同的 OpenClaw 吗?
可以,通过 bindings 将每个发送者路由到不同的智能体(对等方 kind: "dm",发送者 E.164 如 +15551234567)。回复仍来自同一个 WhatsApp 账户,并且直接聊天折叠到每个智能体的主会话,因此使用每人一个智能体。DM 访问控制(dmPolicy/allowFrom)是每个 WhatsApp 账户全局的。见多智能体路由。
为什么向导询问我的手机号码?
向导使用它来设置您的允许列表/所有者,以便您的 DM 被允许。它不用于自动发送。如果您运行在个人 WhatsApp 号码上,使用相同的号码并启用 channels.whatsapp.selfChatMode。
消息规范化(模型看到的内容)
Body是带有信封的当前消息正文。- 引用的回复上下文始终附加:
[Replying to +1555 id:ABC123] <quoted text or <media:...>> [/Replying] - 回复元数据也设置:
ReplyToId= stanzaIdReplyToBody= 引用正文或媒体占位符ReplyToSender= 已知时的 E.164
- 纯媒体入站消息使用占位符:
<media:image|video|audio|document|sticker>
群组
- 群组映射到
agent:<agentId>:whatsapp:group:<jid>会话。 - 群组策略:
channels.whatsapp.groupPolicy = open|disabled|allowlist(默认allowlist)。 - 激活模式:
mention(默认):需要 @提及或正则表达式匹配。always:始终触发。
/activation mention|always是所有者专用的,必须作为独立消息发送。- 所有者 =
channels.whatsapp.allowFrom(或未设置时的自 E.164)。 - 历史注入(仅待处理):
- 最近未处理的消息(默认 50 条)插入在:
[自上次回复以来的聊天消息 - 上下文](已在会话中的消息不会被重新注入) - 当前消息在:
[当前消息 - 回复此消息] - 发送者后缀附加:
[来自: 姓名 (+E164)]
- 最近未处理的消息(默认 50 条)插入在:
- 群组元数据缓存 5 分钟(主题 + 参与者)。
回复传递(线程)
- WhatsApp Web 发送标准消息(当前网关中没有引用的回复线程)。
- 此通道上忽略回复标签。
确认反应(自动反应)
WhatsApp 可以在收到消息后立即自动发送表情符号反应,然后再生成回复。这为用户提供消息已收到的即时反馈。
配置:
{
"whatsapp": {
"ackReaction": {
"emoji": "👀",
"direct": true,
"group": "mentions"
}
}
}选项:
emoji(字符串):用于确认的表情符号(例如,"👀"、"✅"、"📨")。空或省略 = 功能禁用。direct(布尔值,默认:true):在直接/DM 聊天中发送反应。group(字符串,默认:"mentions"):群聊行为:"always":对所有群组消息做出反应(即使没有 @提及)"mentions":仅在机器人被 @提及时做出反应"never":在群组中从不做出反应
按账户覆盖:
{
"whatsapp": {
"accounts": {
"work": {
"ackReaction": {
"emoji": "✅",
"direct": false,
"group": "always"
}
}
}
}
}行为说明:
- 反应在收到消息后立即发送,在输入指示或机器人回复之前。
- 在
requireMention: false的群组中(激活:always),group: "mentions"会对所有消息做出反应(不仅仅是 @提及)。 - 即发即忘:反应失败会被记录,但不会阻止机器人回复。
- 群组反应自动包含参与者 JID。
- WhatsApp 忽略
messages.ackReaction;使用channels.whatsapp.ackReaction代替。
智能体工具(反应)
- 工具:
whatsapp带react操作(chatJid、messageId、emoji,可选remove)。 - 可选:
participant(群组发送者)、fromMe(对自己的消息做出反应)、accountId(多账户)。 - 反应移除语义:见/tools/reactions。
- 工具门控:
channels.whatsapp.actions.reactions(默认:启用)。
限制
- 出站文本被分块为
channels.whatsapp.textChunkLimit(默认 4000)。 - 可选换行分块:设置
channels.whatsapp.chunkMode="newline"在长度分块之前按空行(段落边界)拆分。 - 入站媒体保存由
channels.whatsapp.mediaMaxMb限制(默认 50 MB)。 - 出站媒体项由
agents.defaults.mediaMaxMb限制(默认 5 MB)。
出站发送(文本 + 媒体)
- 使用活动的 Web 监听器;如果网关未运行则出错。
- 文本分块:每条消息最大 4k(可通过
channels.whatsapp.textChunkLimit配置,可选channels.whatsapp.chunkMode)。 - 媒体:
- 支持图片/视频/音频/文档。
- 音频作为 PTT 发送;
audio/ogg=>audio/ogg; codecs=opus。 - 标题仅在第一个媒体项上。
- 媒体获取支持 HTTP(S) 和本地路径。
- 动态 GIF:WhatsApp 期望 MP4 且
gifPlayback: true用于内联循环。- CLI:
openclaw message send --media <mp4> --gif-playback - 网关:
send参数包含gifPlayback: true
- CLI:
语音便签(PTT 音频)
WhatsApp 将音频作为语音便签发送(PTT 气泡)。
- 最佳效果:OGG/Opus。OpenClaw 将
audio/ogg重写为audio/ogg; codecs=opus。 [[audio_as_voice]]对 WhatsApp 被忽略(音频已经作为语音便签发送)。
媒体限制 + 优化
- 默认出站限制:5 MB(每媒体项)。
- 覆盖:
agents.defaults.mediaMaxMb。 - 图片自动优化为 JPEG(在限制下,调整大小 + 质量扫描)。
- 超大媒体 => 错误;媒体回复回退到文本警告。
心跳
- 网关心跳记录连接健康状况(
web.heartbeatSeconds,默认 60s)。 - 智能体心跳可按智能体配置(
agents.list[].heartbeat)或全局通过agents.defaults.heartbeat(当没有每智能体条目时回退)。- 使用配置的心跳提示(默认:
如果存在 HEARTBEAT.md 则读取它(工作区上下文)。严格遵循。不要从之前的聊天中推断或重复旧任务。如果不需要注意,回复 HEARTBEAT_OK.)+HEARTBEAT_OK跳过行为。 - 传递默认为最后使用的通道(或配置的目标)。
- 使用配置的心跳提示(默认:
重连行为
- 退避策略:
web.reconnect:initialMs、maxMs、factor、jitter、maxAttempts。
- 如果达到最大尝试次数,Web 监控停止(降级)。
- 注销 => 停止并要求重新关联。
配置快速映射
channels.whatsapp.dmPolicy(DM 策略:pairing/allowlist/open/disabled)。channels.whatsapp.selfChatMode(同一手机设置;机器人使用您的个人 WhatsApp 号码)。channels.whatsapp.allowFrom(DM 允许列表)。WhatsApp 使用 E.164 电话号码(无用户名)。channels.whatsapp.mediaMaxMb(入站媒体保存限制)。channels.whatsapp.ackReaction(消息收到时的自动反应:{emoji, direct, group})。channels.whatsapp.accounts.<accountId>.*(每账户设置 + 可选authDir)。channels.whatsapp.accounts.<accountId>.mediaMaxMb(每账户入站媒体限制)。channels.whatsapp.accounts.<accountId>.ackReaction(每账户确认反应覆盖)。channels.whatsapp.groupAllowFrom(群组发送者允许列表)。channels.whatsapp.groupPolicy(群组策略)。channels.whatsapp.historyLimit/channels.whatsapp.accounts.<accountId>.historyLimit(群组历史上下文;0禁用)。channels.whatsapp.dmHistoryLimit(DM 历史限制,以用户轮为单位)。每用户覆盖:channels.whatsapp.dms["<phone>"].historyLimit。channels.whatsapp.groups(群组允许列表 + 提及门控默认;使用"*"允许所有)。channels.whatsapp.actions.reactions(门控 WhatsApp 工具反应)。agents.list[].groupChat.mentionPatterns(或messages.groupChat.mentionPatterns)。messages.groupChat.historyLimit。channels.whatsapp.messagePrefix(入站前缀;每账户:channels.whatsapp.accounts.<accountId>.messagePrefix;已弃用:messages.messagePrefix)。messages.responsePrefix(出站前缀)。agents.defaults.mediaMaxMb。agents.defaults.heartbeat.every。agents.defaults.heartbeat.model(可选覆盖)。agents.defaults.heartbeat.target。agents.defaults.heartbeat.to。agents.defaults.heartbeat.session。agents.list[].heartbeat.*(每智能体覆盖)。session.*(范围、空闲、存储、mainKey)。web.enabled(为 false 时禁用通道启动)。web.heartbeatSeconds。web.reconnect.*。
日志 + 故障排除
- 子系统:
whatsapp/inbound、whatsapp/outbound、web-heartbeat、web-reconnect。 - 日志文件:
/tmp/openclaw/openclaw-YYYY-MM-DD.log(可配置)。 - 故障排除指南:网关故障排除。
故障排除(快速)
未关联 / 需要 QR 登录
- 症状:
channels status显示linked: false或警告"Not linked"。 - 修复:在网关主机上运行
openclaw channels login并扫描 QR(WhatsApp → 设置 → 关联设备)。
已关联但断开连接 / 重连循环
- 症状:
channels status显示running, disconnected或警告"Linked but disconnected"。 - 修复:
openclaw doctor(或重启网关)。如果持续存在,通过channels login重新关联并检查openclaw logs --follow。
Bun 运行时
- Bun 不推荐。WhatsApp(Baileys)和 Telegram 在 Bun 上不可靠。 使用 Node 运行网关。(见运行时说明)。
相关命令
openclaw channels- 通道管理openclaw pairing- 配对管理- 群组概念 - 群组配置说明