Complete Guide to OpenClaw WhatsApp Integration
Step-by-step guide to connect OpenClaw with WhatsApp. Chat with your AI assistant through WhatsApp using the WhatsApp Web protocol via Baileys.
OpenClaw Manuals
Tutorial Authors
Overview
WhatsApp integration allows you to chat with your OpenClaw AI assistant directly through WhatsApp. OpenClaw uses WhatsApp Web via Baileys — the gateway owns the session(s) and manages all communication. You'll link your WhatsApp account similar to how you'd link WhatsApp Web on a browser.
Prerequisites
Before starting, ensure you have:
- OpenClaw installed and the gateway running
- A WhatsApp account with a real mobile number (VoIP and virtual numbers are usually blocked by WhatsApp)
- Node.js runtime (Bun is not recommended — WhatsApp/Baileys is unreliable on Bun)
Getting a Phone Number
WhatsApp requires a real mobile number for verification. There are two supported modes:
Dedicated Number (Recommended)
Use a separate phone number for OpenClaw. This gives the best UX with clean routing and no self-chat quirks. The ideal setup is a spare/old Android phone + eSIM — leave it on Wi-Fi and power, then link via QR.
Number sourcing tips:
- Local eSIM from your country's mobile carrier (most reliable)
- Prepaid SIM — cheap, just needs to receive one verification SMS
- Avoid: TextNow, Google Voice, most "free SMS" services — WhatsApp blocks these aggressively
The number only needs to receive one verification SMS. After that, WhatsApp Web sessions persist via
creds.json
.
Tip: You can use WhatsApp Business on the same device with a different number. Great for keeping your personal WhatsApp separate — install WhatsApp Business and register the OpenClaw number there.
Personal Number (Fallback)
Quick fallback: run OpenClaw on your own number . Message yourself (WhatsApp "Message yourself") for testing so you don't spam contacts. You must enable self-chat mode in this case.
Step 1: Configure WhatsApp
Edit your
~/.openclaw/openclaw.json
.
Dedicated Number Config
{
channels: {
whatsapp: {
dmPolicy: "allowlist",
allowFrom: ["+15551234567"],
},
},
}
Replace
+15551234567
with the phone number(s) you want to allow to chat with the assistant (E.164 format).
Personal Number Config (Self-Chat Mode)
{
"whatsapp": {
"selfChatMode": true,
"dmPolicy": "allowlist",
"allowFrom": ["+15551234567"]
}
}
When using self-chat mode, enter the phone number you message from (the owner/sender), not the assistant number. Self-chat replies default to
[{identity.name}]
as a prefix (or
[openclaw]
if unset). You can customize this via
messages.responsePrefix
or set it to
""
to remove it.
Step 2: Link Your WhatsApp Account
Run the login command:
openclaw channels login
This will display a QR code in your terminal. On your phone:
- Open WhatsApp
- Go to Settings > Linked Devices
- Tap Link a Device
- Scan the QR code displayed in your terminal
For multi-account setups, specify the account:
openclaw channels login --account
The default account (when
--account
is omitted) is
default
if present, otherwise the first configured account ID (sorted).
Step 3: Start the Gateway
Start the OpenClaw gateway to begin receiving messages. The gateway owns the Baileys socket and inbox loop — CLI and macOS app talk to the gateway, with no direct Baileys usage.
Important: An active listener is required for outbound sends; otherwise, sends will fail fast.
DM Access Control
OpenClaw provides three DM policy modes via
channels.whatsapp.dmPolicy
:
Pairing Mode (Default)
Unknown senders receive a time-limited pairing code. Their message is not processed until approved.
# Approve a pairing request
openclaw pairing approve whatsapp
# List pending pairing requests
openclaw pairing list whatsapp
Pairing codes expire after 1 hour , and pending requests are capped at 3 per channel.
Allowlist Mode
Only phone numbers listed in
channels.whatsapp.allowFrom
can initiate chats.
{
channels: {
whatsapp: {
dmPolicy: "allowlist",
allowFrom: ["+15551234567", "+15559876543"],
},
},
}
Open Mode
Requires
channels.whatsapp.allowFrom
to include
"*"
.
Note:
Your linked WhatsApp number is implicitly trusted — self messages skip
dmPolicy
and
allowFrom
checks.
Read Receipts
By default, the gateway marks inbound WhatsApp messages as read (blue ticks) once accepted.
Disable globally:
{
channels: { whatsapp: { sendReadReceipts: false } },
}
Disable per account:
{
channels: {
whatsapp: {
accounts: {
personal: { sendReadReceipts: false },
},
},
},
}
Self-chat mode always skips read receipts.
Group Chat Support
Groups map to dedicated sessions. Configure group behavior with:
-
Group policy:
channels.whatsapp.groupPolicy—open,disabled, orallowlist(default:allowlist) -
Activation modes:
-
mention(default): requires @mention or regex match -
always: always triggers a response
-
Toggle activation with an owner-only command (must be a standalone message):
/activation mention /activation always
Owner is determined by
channels.whatsapp.allowFrom
(or your self E.164 if unset).
Group History Context
Recent unprocessed messages (default 50) are automatically injected as context:
[Chat messages since your last reply - for context] ... [Current message - respond to this]
Each message includes a sender suffix:
[from: Name (+E164)]
.
Group metadata (subject + participants) is cached for 5 minutes.
Acknowledgment Reactions
WhatsApp can automatically send emoji reactions to incoming messages upon receipt, providing instant feedback before the bot generates a reply.
{
"whatsapp": {
"ackReaction": {
"emoji": "👀",
"direct": true,
"group": "mentions"
}
}
}
Options:
-
emoji: Emoji to react with (e.g., "👀", "✅"). Empty or omitted disables the feature. -
direct(default:true): Send reactions in DM chats. -
group(default:"mentions"):-
"always": React to all group messages -
"mentions": React only when bot is @mentioned -
"never": Never react in groups
-
Per-account override:
{
"whatsapp": {
"accounts": {
"work": {
"ackReaction": {
"emoji": "✅",
"direct": false,
"group": "always"
}
}
}
}
}
Reactions are sent immediately upon receipt, before typing indicators or bot replies. Failures are logged but don't prevent the bot from replying.
Message Handling
Inbound Messages
-
Messages arrive via Baileys
messages.upsertevents - Status/broadcast chats are ignored
- Direct chats use E.164 format; groups use group JID
- Quoted reply context is always appended to provide conversation context
-
Media-only messages use placeholders:
<media:image|video|audio|document|sticker>
Outbound Messages
-
Text is chunked to
4,000 characters
by default (configurable via
channels.whatsapp.textChunkLimit) -
Optional newline chunking: set
channels.whatsapp.chunkMode="newline"to split on paragraph boundaries before length chunking - Supported media types: image, video, audio, document
- Audio is sent as voice notes (PTT). Best results with OGG/Opus format
- Caption only on first media item
-
Animated GIFs: WhatsApp expects MP4 with
gifPlayback: truefor inline looping
Media Limits
-
Inbound
media save cap: 50 MB (configurable via
channels.whatsapp.mediaMaxMb) -
Outbound
media cap: 5 MB per item (configurable via
agents.defaults.mediaMaxMb) - Images are auto-optimized to JPEG when under cap (resize + quality sweep)
- Oversize media results in an error; media reply falls back to text warning
Credentials & Storage
-
Credentials stored at:
~/.openclaw/credentials/whatsapp/<accountId>/creds.json -
Automatic backup at
creds.json.bak(restored on corruption) -
Logout:
openclaw channels logout(or--account <id>) deletes WhatsApp auth state but keeps sharedoauth.json
Multi-Account Support
Multiple WhatsApp accounts can run in a single Gateway process. Use account identifiers in the configuration:
{
channels: {
whatsapp: {
accounts: {
personal: { /* per-account settings */ },
work: { /* per-account settings */ },
},
},
},
}
Per-account settings support overrides for
sendReadReceipts
,
ackReaction
,
mediaMaxMb
,
historyLimit
, and more.
Why Not Twilio / WhatsApp Business API?
Early OpenClaw builds supported Twilio's WhatsApp Business integration, but it was removed because:
- WhatsApp Business numbers are a poor fit for a personal assistant
- Meta enforces a 24-hour reply window — if you haven't responded in the last 24 hours, the business number can't initiate new messages
- High-volume or "chatty" usage triggers aggressive blocking, because business accounts aren't designed for personal assistant-style messaging
- Result: unreliable delivery and frequent blocks
Config Quick Reference
| Config Key | Description |
|---|---|
|
channels.whatsapp.dmPolicy
| DM policy:
pairing
/
allowlist
/
open
/
disabled
|
|
channels.whatsapp.selfChatMode
| Enable for personal number setup |
|
channels.whatsapp.allowFrom
| DM allowlist (E.164 phone numbers) |
|
channels.whatsapp.sendReadReceipts
| Auto read receipts (default: true) |
|
channels.whatsapp.ackReaction
| Auto-reaction on message receipt |
|
channels.whatsapp.groupPolicy
| Group policy:
open
/
disabled
/
allowlist
|
|
channels.whatsapp.textChunkLimit
| Outbound text chunk size (default: 4000) |
|
channels.whatsapp.mediaMaxMb
| Inbound media cap (default: 50 MB) |
|
channels.whatsapp.configWrites
| Allow config writes via
/config
command |
|
agents.defaults.mediaMaxMb
| Outbound media cap (default: 5 MB) |
Troubleshooting
Not Linked / QR Login Required
Symptom:
channels status
shows
linked: false
or warns "Not linked".
Fix:
Run
openclaw channels login
on the gateway host and scan the QR code (WhatsApp > Settings > Linked Devices).
Linked but Disconnected / Reconnect Loop
Symptom:
channels status
shows
running, disconnected
or warns "Linked but disconnected".
Fix:
Run
openclaw doctor
or restart the gateway. If it persists, relink via
openclaw channels login
and inspect
openclaw logs --follow
.
Bun Runtime Issues
Bun is not recommended . WhatsApp (Baileys) and Telegram are unreliable on Bun. Run the gateway with Node.js .
Reconnect Behavior
The gateway uses a backoff policy (
web.reconnect
) with configurable
initialMs
,
maxMs
,
factor
,
jitter
, and
maxAttempts
. If max attempts are reached, web monitoring stops (degraded mode). A logged-out socket stops and requires re-linking.