WhatsApp (Web channel)
Status: production-ready via WhatsApp Web (Baileys). Gateway owns linked session(s).Pairing
Channel troubleshooting
Gateway configuration
Quick setup
Configure WhatsApp access policy
Link WhatsApp (QR)
Start the gateway
Approve first pairing request (if using pairing mode)
Deployment patterns
Dedicated number (recommended)
Dedicated number (recommended)
- separate WhatsApp identity for OpenClaw
- clearer DM allowlists and routing boundaries
- lower chance of self-chat confusion
Personal-number fallback
Personal-number fallback
dmPolicy: "allowlist"allowFromincludes your personal numberselfChatMode: true
allowFrom.WhatsApp Web-only channel scope
WhatsApp Web-only channel scope
Baileys) in current OpenClaw channel architecture.There is no separate Twilio WhatsApp messaging channel in the built-in chat-channel registry.Runtime model
- Gateway owns the WhatsApp socket and reconnect loop.
- Outbound sends require an active WhatsApp listener for the target account.
- Status and broadcast chats are ignored (
@status,@broadcast). - Direct chats use DM session rules (
session.dmScope; defaultmaincollapses DMs to the agent main session). - Group sessions are isolated (
agent:<agentId>:whatsapp:group:<jid>).
Access control and activation
- DM policy
- Group policy + allowlists
- Mentions + /activation
channels.whatsapp.dmPolicy controls direct chat access:pairing(default)allowlistopen(requiresallowFromto include"*")disabled
allowFrom accepts E.164-style numbers (normalized internally).Multi-account override: channels.whatsapp.accounts.<id>.dmPolicy (and allowFrom) take precedence over channel-level defaults for that account.Runtime behavior details:- pairings are persisted in channel allow-store and merged with configured
allowFrom - if no allowlist is configured, the linked self number is allowed by default
- outbound
fromMeDMs are never auto-paired
Personal-number and self-chat behavior
When the linked self number is also present inallowFrom, WhatsApp self-chat safeguards activate:
- skip read receipts for self-chat turns
- ignore mention-JID auto-trigger behavior that would otherwise ping yourself
- if
messages.responsePrefixis unset, self-chat replies default to[{identity.name}]or[openclaw]
Message normalization and context
Inbound envelope + reply context
Inbound envelope + reply context
ReplyToId, ReplyToBody, ReplyToSender, sender JID/E.164).Media placeholders and location/contact extraction
Media placeholders and location/contact extraction
<media:image><media:video><media:audio><media:document><media:sticker>
Pending group history injection
Pending group history injection
- default limit:
50 - config:
channels.whatsapp.historyLimit - fallback:
messages.groupChat.historyLimit 0disables
[Chat messages since your last reply - for context][Current message - respond to this]
Read receipts
Read receipts
Delivery, chunking, and media
Text chunking
Text chunking
- default chunk limit:
channels.whatsapp.textChunkLimit = 4000 channels.whatsapp.chunkMode = "length" | "newline"newlinemode prefers paragraph boundaries (blank lines), then falls back to length-safe chunking
Outbound media behavior
Outbound media behavior
- supports image, video, audio (PTT voice-note), and document payloads
audio/oggis rewritten toaudio/ogg; codecs=opusfor voice-note compatibility- animated GIF playback is supported via
gifPlayback: trueon video sends - captions are applied to the first media item when sending multi-media reply payloads
- media source can be HTTP(S),
file://, or local paths
Media size limits and fallback behavior
Media size limits and fallback behavior
- inbound media save cap:
channels.whatsapp.mediaMaxMb(default50) - outbound media send cap:
channels.whatsapp.mediaMaxMb(default50) - per-account overrides use
channels.whatsapp.accounts.<accountId>.mediaMaxMb - images are auto-optimized (resize/quality sweep) to fit limits
- on media send failure, first-item fallback sends text warning instead of dropping the response silently
Acknowledgment reactions
WhatsApp supports immediate ack reactions on inbound receipt viachannels.whatsapp.ackReaction.
- sent immediately after inbound is accepted (pre-reply)
- failures are logged but do not block normal reply delivery
- group mode
mentionsreacts on mention-triggered turns; group activationalwaysacts as bypass for this check - WhatsApp uses
channels.whatsapp.ackReaction(legacymessages.ackReactionis not used here)
Multi-account and credentials
Account selection and defaults
Account selection and defaults
- account ids come from
channels.whatsapp.accounts - default account selection:
defaultif present, otherwise first configured account id (sorted) - account ids are normalized internally for lookup
Credential paths and legacy compatibility
Credential paths and legacy compatibility
- current auth path:
~/.openclaw/credentials/whatsapp/<accountId>/creds.json - backup file:
creds.json.bak - legacy default auth in
~/.openclaw/credentials/is still recognized/migrated for default-account flows
Logout behavior
Logout behavior
openclaw channels logout --channel whatsapp [--account <id>] clears WhatsApp auth state for that account.In legacy auth directories, oauth.json is preserved while Baileys auth files are removed.Tools, actions, and config writes
- Agent tool support includes WhatsApp reaction action (
react). - Action gates:
channels.whatsapp.actions.reactionschannels.whatsapp.actions.polls
- Channel-initiated config writes are enabled by default (disable via
channels.whatsapp.configWrites=false).
Troubleshooting
Not linked (QR required)
Not linked (QR required)
Linked but disconnected / reconnect loop
Linked but disconnected / reconnect loop
channels login.No active listener when sending
No active listener when sending
Group messages unexpectedly ignored
Group messages unexpectedly ignored
groupPolicygroupAllowFrom/allowFromgroupsallowlist entries- mention gating (
requireMention+ mention patterns) - duplicate keys in
openclaw.json(JSON5): later entries override earlier ones, so keep a singlegroupPolicyper scope
Bun runtime warning
Bun runtime warning
Configuration reference pointers
Primary reference: High-signal WhatsApp fields:- access:
dmPolicy,allowFrom,groupPolicy,groupAllowFrom,groups - delivery:
textChunkLimit,chunkMode,mediaMaxMb,sendReadReceipts,ackReaction - multi-account:
accounts.<id>.enabled,accounts.<id>.authDir, account-level overrides - operations:
configWrites,debounceMs,web.enabled,web.heartbeatSeconds,web.reconnect.* - session behavior:
session.dmScope,historyLimit,dmHistoryLimit,dms.<id>.historyLimit