openclaw-whatsapp
WhatsApp bridge that connects OpenClaw agents to WhatsApp. Send messages, auto-reply to DMs with AI, search message history, and sync contacts — all from a single Go binary.
Quick Reference
# Check status
openclaw-whatsapp status
# Send a message
openclaw-whatsapp send "NUMBER@s.whatsapp.net" "Your message"
# View logs (if running as service)
journalctl --user -u openclaw-whatsapp.service -f
# View worker logs
tail -f /tmp/openclaw-wa-agent/worker.log
Full Setup (Self-Service)
Follow these steps to set up WhatsApp auto-reply from scratch.
Step 1: Install the binary
curl -fsSL https://raw.githubusercontent.com/0xs4m1337/openclaw-whatsapp/main/install.sh | bash
Verify installation:
openclaw-whatsapp version
Step 2: Find your openclaw binary path
which openclaw
# Example output: /home/USER/.nvm/versions/node/v22.22.0/bin/openclaw
Save this path — you'll need it in Step 4.
Step 3: Install relay scripts
Copy scripts from this skill directory:
SKILL_DIR="$(dirname "$(realpath "$0")")" # or use absolute path to skill
# Copy scripts
sudo cp "$SKILL_DIR/scripts/wa-notify.sh" /usr/local/bin/wa-notify.sh
sudo cp "$SKILL_DIR/scripts/wa-notify-worker.sh" /usr/local/bin/wa-notify-worker.sh
sudo chmod +x /usr/local/bin/wa-notify.sh /usr/local/bin/wa-notify-worker.sh
Or if running as agent, use the skill directory path directly:
cp ~/clawd/skills/openclaw-whatsapp/scripts/wa-notify.sh /usr/local/bin/
cp ~/clawd/skills/openclaw-whatsapp/scripts/wa-notify-worker.sh /usr/local/bin/
chmod +x /usr/local/bin/wa-notify.sh /usr/local/bin/wa-notify-worker.sh
Step 4: Configure the worker script
Edit /usr/local/bin/wa-notify-worker.sh and update the PATH line with your openclaw binary path from Step 2:
# Find this line near the top:
export PATH="/home/oussama/.nvm/versions/node/v22.22.0/bin:$PATH"
# Change it to your actual path:
export PATH="/home/YOUR_USER/.nvm/versions/node/vXX.XX.X/bin:$PATH"
Also update the worker script path in /usr/local/bin/wa-notify.sh:
# Find this line near the bottom:
nohup /home/oussama/dev/openclaw-whatsapp/scripts/wa-notify-worker.sh
# Change to:
nohup /usr/local/bin/wa-notify-worker.sh
Step 5: Create config file
mkdir -p ~/.openclaw-whatsapp
cat > ~/.openclaw-whatsapp/config.yaml << 'EOF'
port: 8555
data_dir: ~/.openclaw-whatsapp
auto_reconnect: true
reconnect_interval: 30s
log_level: info
agent:
enabled: true
mode: "command"
command: "/usr/local/bin/wa-notify.sh '{name}' '{message}' '{chat_jid}' '{message_id}'"
ignore_from_me: true
dm_only: true
timeout: 30s
system_prompt: |
You are a helpful WhatsApp assistant. Be concise and natural.
EOF
Step 6: Create systemd service (recommended)
mkdir -p ~/.config/systemd/user
cat > ~/.config/systemd/user/openclaw-whatsapp.service << 'EOF'
[Unit]
Description=OpenClaw WhatsApp Bridge
After=network.target
[Service]
Type=simple
ExecStart=/usr/local/bin/openclaw-whatsapp start -c %h/.openclaw-whatsapp/config.yaml
Restart=always
RestartSec=5
[Install]
WantedBy=default.target
EOF
systemctl --user daemon-reload
systemctl --user enable openclaw-whatsapp.service
systemctl --user start openclaw-whatsapp.service
Step 7: Link WhatsApp
- Check bridge is running:
openclaw-whatsapp status - Open QR page:
http://localhost:8555/qr - On your phone: WhatsApp → Settings → Linked Devices → Link a Device
- Scan the QR code
Step 8: Test
Send a WhatsApp message to the linked number from another phone. Check:
# Bridge logs
journalctl --user -u openclaw-whatsapp.service -n 20
# Worker logs
cat /tmp/openclaw-wa-agent/worker.log
Architecture
WhatsApp DM → Bridge → wa-notify.sh (enqueue)
→ wa-notify-worker.sh (background, file-locked)
→ Fetches last 10 messages for context
→ openclaw agent (processes message)
→ openclaw-whatsapp send <JID> <reply>
→ WhatsApp reply sent
Key features:
- Fast enqueue — bridge doesn't wait for agent processing
- Deduplication — message IDs tracked to prevent double-replies
- Single worker — file-locked, sequential processing, no race conditions
- Crash resilience — queue persists across restarts
Customizing System Prompt
Edit ~/.openclaw-whatsapp/config.yaml and update the system_prompt field:
agent:
system_prompt: |
You are a sales assistant for Acme Corp.
Be friendly and professional.
When someone wants to book a demo:
- Book via: mcporter call composio.GOOGLECALENDAR_CREATE_EVENT ...
- Notify team via: message action=send channel=telegram target=CHAT_ID ...
Restart after changes:
systemctl --user restart openclaw-whatsapp.service
Allowlist / Blocklist
Restrict which numbers the agent responds to:
agent:
allowlist: ["971586971337"] # only these (empty = all)
blocklist: ["spammer123"] # never these
CLI Reference
openclaw-whatsapp start [-c config.yaml] # Start the bridge
openclaw-whatsapp status [--addr URL] # Check connection status
openclaw-whatsapp send NUMBER MESSAGE # Send a message
openclaw-whatsapp stop # Stop the bridge
openclaw-whatsapp version # Print version
Troubleshooting
| Problem | Solution |
|---|---|
| QR expired | Refresh http://localhost:8555/qr — auto-refreshes every 3s |
| Bridge disconnected | openclaw-whatsapp status; auto-reconnects by default |
| Agent not replying | Check /tmp/openclaw-wa-agent/worker.log for errors |
| "stream replaced" errors | Multiple bridge instances — ensure only one runs (systemctl --user status openclaw-whatsapp + pgrep openclaw-whatsapp) |
| "openclaw: not found" | Edit wa-notify-worker.sh PATH to include openclaw binary |
| "not logged in" | Scan QR again — session expired |
Files
| Path | Description |
|---|---|
~/.openclaw-whatsapp/config.yaml | Bridge configuration |
~/.openclaw-whatsapp/messages.db | SQLite message store |
~/.openclaw-whatsapp/sessions/ | WhatsApp session data |
/tmp/openclaw-wa-agent/queue.jsonl | Message queue |
/tmp/openclaw-wa-agent/worker.log | Worker logs |
/tmp/openclaw-wa-agent/seen_message_ids.txt | Deduplication list |
API Endpoints
| Method | Path | Description |
|---|---|---|
GET | /status | Connection status |
GET | /qr | QR code page |
POST | /send/text | Send message {"to": "...", "message": "..."} |
GET | /chats | List all chats |
GET | /chats/{jid}/messages?limit=10 | Messages for a chat |
GET | /messages/search?q=keyword | Full-text search |
See references/api-reference.md for full API docs.