WhatsApp Channel
The WhatsApp channel enables ZeroClaw to communicate via WhatsApp Business Cloud API using Meta’s official platform with webhook-based message delivery.Overview
- Channel Name:
whatsapp - Transport: Webhook (push-based)
- Authentication: Access token (Meta Business)
- Public Port Required: Yes (HTTPS webhook endpoint)
- Supports: Text messages, phone number allowlist
Configuration
Required Settings
Complete Configuration
Environment Variables
Setup
Prerequisites
- Meta Business Account: Create at business.facebook.com
- WhatsApp Business App: Register in Meta Business Settings
- Phone Number: Add and verify a business phone number
- Public HTTPS Endpoint: Required for webhook callbacks
Getting Access Token
- Go to Meta for Developers
- Create new app (Business type)
- Add “WhatsApp” product
- Go to API Settings
- Generate Temporary Access Token (24 hours) or Permanent Token:
- Navigate to System Users (Business Settings)
- Create system user
- Assign WhatsApp permissions
- Generate token
Getting Phone Number ID
- In WhatsApp Business settings
- Find your phone number
- Copy the Phone Number ID (not the actual phone number)
Webhook Setup
- In WhatsApp product settings, go to Configuration
- Set Callback URL:
https://your-domain.com/whatsapp - Set Verify Token: Choose a secure random string
- Subscribe to webhook fields:
messages(required)
- Verify webhook (Meta will send GET request)
- Start receiving POST requests
hub.challenge if hub.verify_token matches.
Features
Webhook Mode (Push-Based)
Unlike polling channels, WhatsApp uses webhooks: Incoming Message Flow:- User sends WhatsApp message to your business number
- Meta WhatsApp API sends POST request to your webhook endpoint
- ZeroClaw validates webhook signature (if configured)
- Parses webhook payload
- Checks allowlist
- Converts to
ChannelMessage - Sends to agent for processing
- The
listen()method keeps channel alive but doesn’t poll - Actual message delivery happens via gateway webhook handler
Phone Number Allowlist
E.164 Format Required
All phone numbers must use E.164 international format:- US:
+1234567890 - UK:
+447911123456 - India:
+919876543210
Configuration
Allow All (testing only):+ prefix are normalized:
Message Type Support
Supported (Current)
- Text messages: Full support
Unsupported (Skipped)
- Images
- Audio/Voice
- Video
- Documents
- Stickers
- Locations
- Contacts
- Reactions
Webhook Payload Parsing
Meta sends nested JSON structure:- Navigate:
entry[].changes[].value.messages[] - Get sender:
fromfield - Normalize: Add
+prefix if missing - Check allowlist
- Extract text:
text.body - Get timestamp:
timestamp(Unix seconds) - Create
ChannelMessage
HTTPS Security
All API calls enforce HTTPS:- Message send:
https://graph.facebook.com/v18.0/{phone_number_id}/messages - Health check:
https://graph.facebook.com/v18.0/{phone_number_id}
Implementation Details
Source Location
src/channels/whatsapp.rs (1140 lines)
Key Components
WhatsAppChannel Struct
Gateway Integration
Webhook handler in gateway:API Endpoints Used
| Method | Endpoint | Purpose |
|---|---|---|
| POST | /v18.0/{phone_number_id}/messages | Send messages |
| GET | /v18.0/{phone_number_id} | Health check |
Message Send Format
+ prefix stripped for API.
Error Handling
API errors are sanitized:- Access tokens
- Sensitive headers
- Internal details
Common Errors
Webhook Verification Failed
verify_token doesn’t match Meta’s expected value
Solution:
- Check token in Meta webhook settings
- Update config:
- Restart daemon
Unauthorized Number
API Error 401
- Generate new permanent token (System User method)
- Update config:
API Error 403
- Verify WhatsApp Business Account is active
- Check phone number is verified
- Ensure System User has
whatsapp_business_messagingpermission
Webhook Not Receiving Messages
Check Webhook URL:WhatsApp channel active (webhook mode).WhatsApp: ignoring message from unauthorized number:WhatsApp webhook verified successfully
Best Practices
- Use Permanent Token: Generate via System User, not temporary 24h token
- Secure Verify Token: Use long random string (32+ chars)
- HTTPS Required: Never use HTTP for webhook
- Allowlist Numbers: Start with
*, then restrict to known users - Monitor Quota: Meta has message limits (check Business Manager)
- Phone Number Verification: Ensure business number is verified
- Error Monitoring: Watch logs for API errors
Troubleshooting
No Messages Received
1. Check Gateway:messages field is subscribed.
3. Check Allowlist:
+1234567890
Messages Not Sending
1. Verify Access Token:Performance
Message Latency
Inbound:- Webhook delivery: <1 second (Meta → your server)
- Processing: Depends on agent/provider
- Total: Usually <5 seconds
- API call: <500ms (your server → Meta)
- WhatsApp delivery: <2 seconds (Meta → recipient)
- Total: Usually <3 seconds
Scalability
Webhook Concurrency:- Gateway handles multiple concurrent webhooks
- Each message processed independently
- Meta enforces per-number limits
- Check Business Manager for current quota
- Tier 1 (default): 1,000 messages/day
- Higher tiers: Request from Meta
Security
Access Token Protection
- Never log access tokens
- Sanitized from error messages
- Store in config with restricted permissions:
chmod 600 config.toml
Webhook Verification
GET Request (initial setup):- Verify
hub.verify_tokenif signature checking is implemented - Check
allowed_numbersallowlist
HTTPS Enforcement
- All API calls use HTTPS
- Webhook endpoint must be HTTPS
- Certificate validation enabled
Comparison with WhatsApp Web Mode
ZeroClaw also supports WhatsApp Web mode (requires--features whatsapp-web):
| Feature | Cloud API (this doc) | Web Mode |
|---|---|---|
| Setup | Business account required | QR code pairing |
| Transport | Webhook (HTTPS) | WebSocket |
| Public endpoint | Required | Not required |
| Official | Yes (Meta) | No (reverse-engineered) |
| Rate limits | Enforced by Meta | Less strict |
| Multimedia | Limited (text only now) | Full support |
| Best for | Production/business | Personal/testing |