OpenClawSkills
GitHub
通道 • 5 分钟阅读

WhatsApp

WhatsApp(Web 通道)集成:登录、收件箱、回复、媒体与运维

状态:仅支持通过 Baileys 接入 WhatsApp Web。会话由 Gateway 统一管理。

Tutorial.step

新手快速配置

1. 尽量使用 单独的手机号(推荐)。

2. 在 ~/.openclaw/openclaw.json 中配置 WhatsApp。

3. 运行 openclaw channels login 扫码登录(WhatsApp → 设置 → 已链接设备)。

4. 启动 Gateway。

最小配置示例:

Json5
{
  channels: {
    whatsapp: {
      dmPolicy: "allowlist",
      allowFrom: ["+15551234567"],
    },
  },
}
Tutorial.step

目标

- 在同一个 Gateway 进程里支持多个 WhatsApp 账号(multi-account)。

- 确定性路由:消息从 WhatsApp 来,就回到 WhatsApp(不让模型选择通道)。

- 模型能看到足够的引用/回复上下文,理解"我在回哪条消息"。

Tutorial.step

配置写回(Config writes)

默认情况下,WhatsApp 允许把由 /config set|unset 触发的配置更新写回配置文件(需要 commands.config: true)。

禁用:

Json5
{
  channels: { whatsapp: { configWrites: false } },
}
Tutorial.step

架构(谁负责什么)

- Gateway 负责 Baileys socket 与收件箱循环(inbox loop)。

- CLI / macOS 应用 只与 Gateway 通信,不会直接使用 Baileys。

- 出站发送需要 活跃监听器;否则会快速失败(因为没有 Web 会话)。

Tutorial.step

获取手机号(两种模式)

WhatsApp 需要真实的手机号码进行验证。VoIP/虚拟号通常会被拦截。OpenClaw 在 WhatsApp 上有两种推荐运行方式:

#

Tutorial.step

独立号码(推荐)

给 OpenClaw 使用一个 单独号码。体验最好:路由清晰、没有"给自己发消息"的怪异边界情况。理想配置:备用/旧 Android 手机 + eSIM,连上 Wi‑Fi 和电源,通过扫码完成链接。

WhatsApp Business: 同一设备上可以用不同号码同时装 WhatsApp 与 WhatsApp Business。把 OpenClaw 放到 Business 里是很好的隔离方式。

示例配置(独立号码、单用户 allowlist):

Json5
{
  channels: {
    whatsapp: {
      dmPolicy: "allowlist",
      allowFrom: ["+15551234567"],
    },
  },
}

可选:配对模式(pairing)

如果你想用配对而不是 allowlist,把 channels.whatsapp.dmPolicy 设为 pairing。未知发送者会收到配对码;批准方式:

openclaw pairing approve whatsapp <code>

#

Tutorial.step

个人号码(兜底)

兜底方案:让 OpenClaw 跑在 你自己的号码 上。测试时可以在 WhatsApp 的 "Message yourself" 里给自己发消息,避免骚扰联系人。配置与实验时你需要在主手机上读取验证码。必须启用 self-chat 模式。

当向导询问你的个人 WhatsApp 号码时,填写"你将从哪个号码给助手发消息"的号码(owner/sender),而不是"助手号码"(因为这里就是同一个号)。

示例配置(个人号 + self-chat):

Json
{
  "whatsapp": {
    "selfChatMode": true,
    "dmPolicy": "allowlist",
    "allowFrom": ["+15551234567"]
  }
}

在 self-chat 模式下,如果没有设置 messages.responsePrefix,回复前缀默认使用 [{identity.name}](否则是 [openclaw])。如需自定义或禁用前缀,请显式设置(用 "" 表示移除)。

#

Tutorial.step

号码来源建议

- 来自你所在国家运营商的 本地 eSIM(最稳定)

- 奥地利:''hot.at''

- 英国:''giffgaff''(免费 SIM,无合约)

- 预付费 SIM — 只要能接收一次验证短信即可

避免: TextNow、Google Voice、多数"免费短信接收"服务(WhatsApp 封得很狠)。

提示: 号码只需要接收一次验证短信。之后 WhatsApp Web 会话会通过 creds.json 持续存在。

Tutorial.step

为什么不使用 Twilio?

- 早期 OpenClaw 曾支持 Twilio 的 WhatsApp Business 集成。

- WhatsApp Business 号码并不适合个人助手。

- Meta 强制 24 小时回复窗口;超过 24 小时未互动时,Business 号码无法主动发起新消息。

- 高频/"碎碎念"式使用会触发更激进的封锁,因为 Business 账号并不是用来发送大量个人助手消息的。

- 结果是投递不稳定、封锁频繁,因此已移除支持。

Tutorial.step

登录与凭据

- 登录命令:openclaw channels login(扫码:Linked Devices)。

- Multi-account login: openclaw channels login --account <id> (<id> = accountId).

- 默认账号:省略 --account 时,若存在 default 则用它,否则按排序取第一个配置的账号 id。

- Credentials storage: ~/.openclaw/credentials/whatsapp/<accountId>/creds.json.

- 备份副本:creds.json.bak(损坏时会用于恢复)。

- 兼容旧版:更早的安装会直接把 Baileys 文件放在 ~/.openclaw/credentials/ 下。

- Logout: openclaw channels logout (or --account <id>) deletes WhatsApp auth state (but keeps shared oauth.json).

- 未登录的 socket 会报错并提示重新链接。

Tutorial.step

入站流程(私聊 + 群聊)

- WhatsApp 事件来自 Baileys 的 messages.upsert。

- 为避免测试/重启累计事件处理器,关闭时会卸载 inbox listeners。

- 会忽略 status/broadcast chats。

- 私聊使用 E.164;群聊使用 group JID。

- 私聊策略(DM policy):channels.whatsapp.dmPolicy 控制私聊访问(默认 pairing)。

- pairing: unknown senders receive pairing code (openclaw pairing approve whatsapp <code>; expires in 1 hour).

- open:需要 channels.whatsapp.allowFrom 包含 "*"。

- 你自己绑定的 WhatsApp 号码会被隐式信任:自发消息会跳过 dmPolicy 与 allowFrom 校验。

#

Tutorial.step

个人号模式(兜底)

如果你用 个人 WhatsApp 号码 跑 OpenClaw,启用 channels.whatsapp.selfChatMode(见上面的示例)。

行为:

- 出站私聊不会触发 pairing 回复(避免刷屏联系人)。

- 入站未知发送者仍遵循 channels.whatsapp.dmPolicy。

- self-chat 模式(allowFrom 包含你自己的号)会避免自动已读回执,并忽略 mention JIDs。

- 非 self-chat 私聊会发送已读回执。

Tutorial.step

已读回执

默认情况下,Gateway 会在消息被接受后把 WhatsApp 入站消息标记为已读(蓝勾)。

全局禁用:

Json5
{
  channels: { whatsapp: { sendReadReceipts: false } },
}

按账号禁用:

Json5
{
  channels: {
    whatsapp: {
      accounts: {
        personal: { sendReadReceipts: false },
      },
    },
  },
}

说明:

- self-chat 模式始终跳过已读回执。

Tutorial.step

WhatsApp FAQ:发消息与配对

链接 WhatsApp 后,OpenClaw 会给随机联系人发消息吗?

不会。默认私聊策略是 pairing:未知发送者只会收到一个配对码,其消息 不会被处理。OpenClaw 只会回复它收到的聊天,或你显式触发的发送(agent/CLI)。

WhatsApp 的 pairing 是怎么工作的?

pairing 是对未知发送者的私聊门禁:

- 新发送者第一次私聊会收到一个短码(消息不会被处理)。

- Approve: openclaw pairing approve whatsapp <code> (list: openclaw pairing list whatsapp).

- 配对码 1 小时过期;每个通道的待处理请求默认上限是 3 个。

一个 WhatsApp 号能让多人分别使用不同 OpenClaw 实例吗?

可以:通过 ''bindings'' 把不同 sender 路由到不同 agent(peer ''kind: "dm"'',sender 用 ''+1555...'' 这种 E.164)。但回复仍来自 ''同一个 WhatsApp 账号'',且私聊会折叠到各自 agent 的主会话,所以建议 ''一人一个 agent''。私聊访问控制(''dmPolicy''/''allowFrom'')是按 WhatsApp 账号全局生效的。见 ''Multi-Agent Routing''。

向导为什么会问我的手机号?

向导用它来设置你的 owner/allowlist,确保你自己的私聊能被允许。它不会用于自动发送。若你跑在个人号上,就填同一个号码并启用 channels.whatsapp.selfChatMode。

Tutorial.step

消息归一化(模型看到什么)

- Body 是当前消息正文(带 envelope)。

- 引用/回复上下文会 始终追加:

[Replying to +1555 id:ABC123]
&lt;quoted text or &lt;media:...&gt;&gt;
[/Replying]

- 同时会设置 reply 元数据:

- ReplyToId = stanzaId

- ReplyToBody = 引用正文或 media placeholder

- ReplyToSender = 可用时为 E.164

- 纯媒体入站消息会使用占位符:

- <media:image|video|audio|document|sticker>

Tutorial.step

群聊

- Group session key: agent:<agentId>:whatsapp:group:<jid>.

- 群策略:channels.whatsapp.groupPolicy = open|disabled|allowlist(默认 allowlist)。

- 触发模式:

- mention(默认):需要 @mention 或正则命中。

- always:总是触发。

- /activation mention|always 仅 owner 可用,并且必须作为单独一条消息发送。

- owner = channels.whatsapp.allowFrom(或未设置时用 self E.164)。

- 历史注入(仅 pending):

- 最近未处理消息(默认 50 条)会插入到:

[Chat messages since your last reply - for context]

- 当前消息插入到:

[Current message - respond to this]

- 末尾会追加发送者信息:[from: Name (+E164)]

- 群元数据缓存 5 分钟(主题 + 成员)。

Tutorial.step

回复投递(线程)

- 当前 gateway 的 WhatsApp Web 出站只发送普通消息(不做 quoted reply 线程化)。

- reply tags 在该通道会被忽略。

Tutorial.step

确认反应(收到即自动 react)

WhatsApp 可以在收到消息后立刻自动发送一个 emoji 反应(在机器人生成回复之前),让用户马上知道"消息已收到"。

配置:

Json
{
  "whatsapp": {
    "ackReaction": {
      "emoji": "👀",
      "direct": true,
      "group": "mentions"
    }
  }
}

选项:

- emoji(string):用于确认的 Emoji(如 "👀"、"✅"、"📨")。为空或省略表示禁用。

- direct(boolean):对私聊启用(默认:true)。

- group(string|boolean):对群聊启用。"mentions" = 仅被 @ 时;true = 总是;false = 禁用(默认:"mentions")。