Zalo
Zalo bot: support status, capabilities, and configuration.
Status: Experimental. Currently supports DM (1:1) only; group support is "coming soon" per Zalo docs.
Plugin Installation Required
Zalo is provided as a plugin and is not packaged with the core installation.
- CLI install: openclaw plugins install @openclaw/zalo
- Or select Zalo in onboarding and confirm installation prompt
- Details: ''/plugin''
Quick Start for Beginners
1. Install Zalo plugin:
- From source checkout: openclaw plugins install ./extensions/zalo
- From npm (if published): openclaw plugins install @openclaw/zalo
- Or select Zalo in onboarding and confirm installation prompt
2. Set up token:
- Env: ZALO_BOT_TOKEN=...
- Or config: channels.zalo.botToken: "...".
3. Restart gateway (or complete onboarding).
4. DM defaults to pairing: first contact receives pairing code, approve to process messages.
Minimum configuration:
{
channels: {
zalo: {
enabled: true,
botToken: "12345689:abc-xyz",
dmPolicy: "pairing",
},
},
}What This Is
Zalo is a popular messaging app in Vietnam; Bot API allows Gateway to run a 1:1 bot. Suitable for support/notification scenarios (needs deterministic routing back to Zalo).
- A Zalo Bot API channel managed by Gateway.
- Deterministic routing: replies only go back to Zalo, model won't choose channel.
- DMs share agent main session.
- Group chat not yet supported (Zalo docs say "coming soon").
Setup (Quick Path)
#
1) Create bot token (Zalo Bot Platform)
1. Open https://bot.zaloplatforms.com and log in.
2. Create a new bot and complete setup.
3. Copy bot token (format: 12345689:abc-xyz).
#
2) Configure token (env or config)
Example:
{
channels: {
zalo: {
enabled: true,
botToken: "12345689:abc-xyz",
dmPolicy: "pairing",
},
},
}Environment variable method: ZALO_BOT_TOKEN=... (only applies to default account).
Multi-account: use channels.zalo.accounts to configure each account's token (optional name).
3. Restart gateway. Zalo starts when token is resolvable (env or config).
4. DM defaults to pairing: approve pairing code on first contact.
How It Works (Behavior)
- Inbound messages are normalized to generic channel envelope (with media placeholders).
- Replies always go back to same Zalo chat.
- Defaults to long-polling; can enable webhook mode via channels.zalo.webhookUrl.
Limitations
- Outbound text segmented by 2000 characters (Zalo API limit).
- Media download/upload limit: channels.zalo.mediaMaxMb (default 5MB).
- Streaming disabled by default due to 2000 character limit making streaming less meaningful.
Access Control (DM)
#
DM Access
- Default: channels.zalo.dmPolicy = "pairing". Unknown senders receive pairing code; messages ignored before approval (pairing code expires in 1 hour).
- Approve:
- openclaw pairing list zalo
- openclaw pairing approve zalo <CODE>
- Pairing is default token exchange. Details: ''/start/pairing''
- channels.zalo.allowFrom only accepts numeric user IDs (no username lookup).
Long-polling vs webhook
- Default: long-polling (no public URL required).
- Webhook mode: set channels.zalo.webhookUrl and channels.zalo.webhookSecret.
- Secret must be 8β256 characters.
- Webhook URL must be HTTPS.
- Zalo uses X-Bot-Api-Secret-Token header for verification.
- Gateway handles webhook at channels.zalo.webhookPath (defaults to webhook URL's path).
Note: Per Zalo API docs, getUpdates (polling) and webhook are mutually exclusive.
Supported Message Types
- Text: Fully supported (2000 character segmentation).
- Images: Supports downloading/processing inbound images; outbound via sendPhoto.
- Stickers: Logged but not fully processed (usually doesn't trigger agent reply).
- Unsupported types: Only logged (e.g., messages from protected users).
Capabilities
| Feature | Status |
| -- |
| DM | β Supported |
| Group chat | β Zalo docs say coming soon |
| Media (images) | β Supported |
| Reactions | β Not supported |
| Threads | β Not supported |
| Polls | β Not supported |
| Native tokens | β Not supported |
| Streaming | β οΈ Disabled by default (2000 char limit) |
Delivery Target (CLI/cron)
- target uses chat id.
- Example: openclaw message send --channel zalo --target 123456789 --message "hi".
Troubleshooting
Bot not responding:
- Use openclaw channels status --probe to check if token is valid
- Confirm sender is approved (pairing or allowFrom)
- Check logs: openclaw logs --follow
Webhook not receiving events:
- Confirm webhook URL is HTTPS
- Confirm secret length is 8β256 characters
- Confirm gateway's HTTP endpoint is reachable at configured path
- Confirm getUpdates polling is not running (mutually exclusive)
Configuration Reference (Zalo)
Full configuration: ''/gateway/configuration''
Provider options:
- channels.zalo.enabled
- channels.zalo.botToken
- channels.zalo.tokenFile (read from file)
- channels.zalo.dmPolicy: pairing | allowlist | open | disabled (default pairing)
- channels.zalo.allowFrom: DM allowlist (user IDs); open requires "*"; wizard asks for numeric ID
- channels.zalo.mediaMaxMb: Inbound/outbound media limit (MB, default 5)
- channels.zalo.webhookUrl: Enable webhook mode (requires HTTPS)
- channels.zalo.webhookSecret: Webhook secret (8β256 characters)
- channels.zalo.webhookPath: Gateway's webhook path
- channels.zalo.proxy: Proxy URL for API requests
Multi-account options:
- channels.zalo.accounts.<id>.botToken
- channels.zalo.accounts.<id>.tokenFile
- channels.zalo.accounts.<id>.name
- channels.zalo.accounts.<id>.enabled
- channels.zalo.accounts.<id>.dmPolicy
- channels.zalo.accounts.<id>.allowFrom
- channels.zalo.accounts.<id>.webhookUrl
- channels.zalo.accounts.<id>.webhookSecret
- channels.zalo.accounts.<id>.webhookPath
- channels.zalo.accounts.<id>.proxy