2026-01-15 05:03:50 +00:00
---
summary: "Zalo bot support status, capabilities, and configuration"
read_when:
- Working on Zalo features or webhooks
2026-01-31 16:04:03 -05:00
title: "Zalo"
2026-01-15 05:03:50 +00:00
---
2026-01-31 21:13:13 +09:00
2026-01-15 05:03:50 +00:00
# Zalo (Bot API)
2026-03-15 20:40:35 +01:00
Status: experimental. DMs are supported. The [Capabilities ](#capabilities ) section below reflects current Marketplace-bot behavior.
2026-01-15 05:03:50 +00:00
2026-01-15 05:36:23 +00:00
## Plugin required
2026-01-31 21:13:13 +09:00
2026-01-15 05:36:23 +00:00
Zalo ships as a plugin and is not bundled with the core install.
2026-01-31 21:13:13 +09:00
2026-01-30 03:15:10 +01:00
- Install via CLI: `openclaw plugins install @openclaw/zalo`
2026-03-15 21:07:18 -07:00
- Or select **Zalo** during setup and confirm the install prompt
2026-02-07 15:40:35 -05:00
- Details: [Plugins ](/tools/plugin )
2026-01-15 05:36:23 +00:00
2026-02-21 11:18:29 -05:00
## Quick setup (beginner)
2026-01-31 21:13:13 +09:00
1. Install the Zalo plugin:
2026-01-30 03:15:10 +01:00
- From a source checkout: `openclaw plugins install ./extensions/zalo`
- From npm (if published): `openclaw plugins install @openclaw/zalo`
2026-03-15 21:07:18 -07:00
- Or pick **Zalo** in setup and confirm the install prompt
2026-01-31 21:13:13 +09:00
2. Set the token:
2026-01-15 05:03:50 +00:00
- Env: `ZALO_BOT_TOKEN=...`
2026-03-15 20:40:35 +01:00
- Or config: `channels.zalo.accounts.default.botToken: "..."` .
2026-03-15 21:07:18 -07:00
3. Restart the gateway (or finish setup).
2026-01-31 21:13:13 +09:00
4. DM access is pairing by default; approve the pairing code on first contact.
2026-01-15 05:03:50 +00:00
Minimal config:
2026-01-31 21:13:13 +09:00
2026-01-15 05:03:50 +00:00
```json5
{
channels: {
zalo: {
enabled: true,
2026-03-15 20:40:35 +01:00
accounts: {
default: {
botToken: "12345689:abc-xyz",
dmPolicy: "pairing",
},
},
2026-01-31 21:13:13 +09:00
},
},
2026-01-15 05:03:50 +00:00
}
```
## What it is
2026-01-31 21:13:13 +09:00
2026-01-15 06:26:55 +00:00
Zalo is a Vietnam-focused messaging app; its Bot API lets the Gateway run a bot for 1:1 conversations.
It is a good fit for support or notifications where you want deterministic routing back to Zalo.
2026-01-31 21:13:13 +09:00
2026-03-15 20:40:35 +01:00
This page reflects current OpenClaw behavior for **Zalo Bot Creator / Marketplace bots** .
**Zalo Official Account (OA) bots** are a different Zalo product surface and may behave differently.
2026-01-15 05:03:50 +00:00
- A Zalo Bot API channel owned by the Gateway.
- Deterministic routing: replies go back to Zalo; the model never chooses channels.
- DMs share the agent's main session.
2026-03-15 20:40:35 +01:00
- The [Capabilities ](#capabilities ) section below shows current Marketplace-bot support.
2026-01-15 05:03:50 +00:00
2026-02-21 11:18:29 -05:00
## Setup (fast path)
2026-01-15 05:03:50 +00:00
### 1) Create a bot token (Zalo Bot Platform)
2026-01-31 21:13:13 +09:00
2026-02-06 10:08:59 -05:00
1. Go to [https://bot.zaloplatforms.com ](https://bot.zaloplatforms.com ) and sign in.
2026-01-31 21:13:13 +09:00
2. Create a new bot and configure its settings.
2026-03-15 20:40:35 +01:00
3. Copy the full bot token (typically `numeric_id:secret` ). For Marketplace bots, the usable runtime token may appear in the bot's welcome message after creation.
2026-01-15 05:03:50 +00:00
### 2) Configure the token (env or config)
2026-01-31 21:13:13 +09:00
2026-01-15 05:03:50 +00:00
Example:
```json5
{
channels: {
zalo: {
enabled: true,
2026-03-15 20:40:35 +01:00
accounts: {
default: {
botToken: "12345689:abc-xyz",
dmPolicy: "pairing",
},
},
2026-01-31 21:13:13 +09:00
},
},
2026-01-15 05:03:50 +00:00
}
```
2026-03-15 20:40:35 +01:00
If you later move to a Zalo bot surface where groups are available, you can add group-specific config such as `groupPolicy` and `groupAllowFrom` explicitly. For current Marketplace-bot behavior, see [Capabilities ](#capabilities ).
2026-01-15 05:03:50 +00:00
Env option: `ZALO_BOT_TOKEN=...` (works for the default account only).
Multi-account support: use `channels.zalo.accounts` with per-account tokens and optional `name` .
2026-02-06 10:00:08 -05:00
3. Restart the gateway. Zalo starts when a token is resolved (env or config).
4. DM access defaults to pairing. Approve the code when the bot is first contacted.
2026-01-15 05:03:50 +00:00
## How it works (behavior)
2026-01-31 21:13:13 +09:00
2026-01-15 05:03:50 +00:00
- Inbound messages are normalized into the shared channel envelope with media placeholders.
- Replies always route back to the same Zalo chat.
- Long-polling by default; webhook mode available with `channels.zalo.webhookUrl` .
## Limits
2026-01-31 21:13:13 +09:00
2026-01-15 05:03:50 +00:00
- Outbound text is chunked to 2000 characters (Zalo API limit).
- Media downloads/uploads are capped by `channels.zalo.mediaMaxMb` (default 5).
- Streaming is blocked by default due to the 2000 char limit making streaming less useful.
## Access control (DMs)
### DM access
2026-01-31 21:13:13 +09:00
2026-01-15 05:03:50 +00:00
- Default: `channels.zalo.dmPolicy = "pairing"` . Unknown senders receive a pairing code; messages are ignored until approved (codes expire after 1 hour).
- Approve via:
2026-01-30 03:15:10 +01:00
- `openclaw pairing list zalo`
- `openclaw pairing approve zalo <CODE>`
2026-02-07 15:40:35 -05:00
- Pairing is the default token exchange. Details: [Pairing ](/channels/pairing )
2026-01-18 22:51:09 +00:00
- `channels.zalo.allowFrom` accepts numeric user IDs (no username lookup available).
2026-01-15 05:03:50 +00:00
2026-02-24 23:30:05 +00:00
## Access control (Groups)
2026-03-15 20:40:35 +01:00
For **Zalo Bot Creator / Marketplace bots** , group support was not available in practice because the bot could not be added to a group at all.
That means the group-related config keys below exist in the schema, but were not usable for Marketplace bots:
2026-02-24 23:30:05 +00:00
- `channels.zalo.groupPolicy` controls group inbound handling: `open | allowlist | disabled` .
- `channels.zalo.groupAllowFrom` restricts which sender IDs can trigger the bot in groups.
- If `groupAllowFrom` is unset, Zalo falls back to `allowFrom` for sender checks.
- Runtime note: if `channels.zalo` is missing entirely, runtime still falls back to `groupPolicy="allowlist"` for safety.
2026-03-15 20:40:35 +01:00
The group policy values (when group access is available on your bot surface) are:
- `groupPolicy: "disabled"` — blocks all group messages.
- `groupPolicy: "open"` — allows any group member (mention-gated).
- `groupPolicy: "allowlist"` — fail-closed default; only allowed senders are accepted.
If you are using a different Zalo bot product surface and have verified working group behavior, document that separately rather than assuming it matches the Marketplace-bot flow.
2026-01-15 05:03:50 +00:00
## Long-polling vs webhook
2026-01-31 21:13:13 +09:00
2026-01-15 05:03:50 +00:00
- Default: long-polling (no public URL required).
- Webhook mode: set `channels.zalo.webhookUrl` and `channels.zalo.webhookSecret` .
- The webhook secret must be 8-256 characters.
- Webhook URL must use HTTPS.
- Zalo sends events with `X-Bot-Api-Secret-Token` header for verification.
- Gateway HTTP handles webhook requests at `channels.zalo.webhookPath` (defaults to the webhook URL path).
2026-02-19 13:31:04 +01:00
- Requests must use `Content-Type: application/json` (or `+json` media types).
- Duplicate events (`event_name + message_id` ) are ignored for a short replay window.
- Burst traffic is rate-limited per path/source and may return HTTP 429.
2026-01-15 05:03:50 +00:00
**Note:** getUpdates (polling) and webhook are mutually exclusive per Zalo API docs.
## Supported message types
2026-01-31 21:13:13 +09:00
2026-03-15 20:40:35 +01:00
For a quick support snapshot, see [Capabilities ](#capabilities ). The notes below add detail where the behavior needs extra context.
2026-01-15 05:03:50 +00:00
- **Text messages**: Full support with 2000 character chunking.
2026-03-15 20:40:35 +01:00
- **Plain URLs in text**: Behave like normal text input.
- **Link previews / rich link cards**: See the Marketplace-bot status in [Capabilities ](#capabilities ); they did not reliably trigger a reply.
- **Image messages**: See the Marketplace-bot status in [Capabilities ](#capabilities ); inbound image handling was unreliable (typing indicator without a final reply).
- **Stickers**: See the Marketplace-bot status in [Capabilities ](#capabilities ).
- **Voice notes / audio files / video / generic file attachments**: See the Marketplace-bot status in [Capabilities ](#capabilities ).
- **Unsupported types**: Logged (for example, messages from protected users).
2026-01-15 05:03:50 +00:00
## Capabilities
2026-01-31 21:13:13 +09:00
2026-03-15 20:40:35 +01:00
This table summarizes current **Zalo Bot Creator / Marketplace bot** behavior in OpenClaw.
| Feature | Status |
| --------------------------- | --------------------------------------- |
| Direct messages | ✅ Supported |
| Groups | ❌ Not available for Marketplace bots |
| Media (inbound images) | ⚠️ Limited / verify in your environment |
| Media (outbound images) | ⚠️ Not re-tested for Marketplace bots |
| Plain URLs in text | ✅ Supported |
| Link previews | ⚠️ Unreliable for Marketplace bots |
| Reactions | ❌ Not supported |
| Stickers | ⚠️ No agent reply for Marketplace bots |
| Voice notes / audio / video | ⚠️ No agent reply for Marketplace bots |
| File attachments | ⚠️ No agent reply for Marketplace bots |
| Threads | ❌ Not supported |
| Polls | ❌ Not supported |
| Native commands | ❌ Not supported |
| Streaming | ⚠️ Blocked (2000 char limit) |
2026-01-15 05:03:50 +00:00
## Delivery targets (CLI/cron)
2026-01-31 21:13:13 +09:00
2026-01-15 05:03:50 +00:00
- Use a chat id as the target.
2026-01-30 03:15:10 +01:00
- Example: `openclaw message send --channel zalo --target 123456789 --message "hi"` .
2026-01-15 05:03:50 +00:00
## Troubleshooting
**Bot doesn't respond:**
2026-01-31 21:13:13 +09:00
2026-01-30 03:15:10 +01:00
- Check that the token is valid: `openclaw channels status --probe`
2026-01-15 05:03:50 +00:00
- Verify the sender is approved (pairing or allowFrom)
2026-01-30 03:15:10 +01:00
- Check gateway logs: `openclaw logs --follow`
2026-01-15 05:03:50 +00:00
**Webhook not receiving events:**
2026-01-31 21:13:13 +09:00
2026-01-15 05:03:50 +00:00
- Ensure webhook URL uses HTTPS
- Verify secret token is 8-256 characters
- Confirm the gateway HTTP endpoint is reachable on the configured path
- Check that getUpdates polling is not running (they're mutually exclusive)
2026-02-21 11:18:29 -05:00
## Configuration reference (Zalo)
2026-01-31 21:13:13 +09:00
2026-01-15 05:03:50 +00:00
Full configuration: [Configuration ](/gateway/configuration )
2026-03-15 20:40:35 +01:00
The flat top-level keys (`channels.zalo.botToken` , `channels.zalo.dmPolicy` , and similar) are a legacy single-account shorthand. Prefer `channels.zalo.accounts.<id>.*` for new configs. Both forms are still documented here because they exist in the schema.
2026-01-15 05:03:50 +00:00
Provider options:
2026-01-31 21:13:13 +09:00
2026-01-15 05:03:50 +00:00
- `channels.zalo.enabled` : enable/disable channel startup.
- `channels.zalo.botToken` : bot token from Zalo Bot Platform.
2026-03-10 23:40:10 +00:00
- `channels.zalo.tokenFile` : read token from a regular file path. Symlinks are rejected.
2026-01-15 05:03:50 +00:00
- `channels.zalo.dmPolicy` : `pairing | allowlist | open | disabled` (default: pairing).
2026-01-18 22:51:09 +00:00
- `channels.zalo.allowFrom` : DM allowlist (user IDs). `open` requires `"*"` . The wizard will ask for numeric IDs.
2026-03-15 20:40:35 +01:00
- `channels.zalo.groupPolicy` : `open | allowlist | disabled` (default: allowlist). Present in config; see [Capabilities ](#capabilities ) and [Access control (Groups) ](#access-control-groups ) for current Marketplace-bot behavior.
2026-02-24 23:30:05 +00:00
- `channels.zalo.groupAllowFrom` : group sender allowlist (user IDs). Falls back to `allowFrom` when unset.
2026-01-15 05:03:50 +00:00
- `channels.zalo.mediaMaxMb` : inbound/outbound media cap (MB, default 5).
- `channels.zalo.webhookUrl` : enable webhook mode (HTTPS required).
- `channels.zalo.webhookSecret` : webhook secret (8-256 chars).
- `channels.zalo.webhookPath` : webhook path on the gateway HTTP server.
- `channels.zalo.proxy` : proxy URL for API requests.
Multi-account options:
2026-01-31 21:13:13 +09:00
2026-01-15 05:03:50 +00:00
- `channels.zalo.accounts.<id>.botToken` : per-account token.
2026-03-10 23:40:10 +00:00
- `channels.zalo.accounts.<id>.tokenFile` : per-account regular token file. Symlinks are rejected.
2026-01-15 05:03:50 +00:00
- `channels.zalo.accounts.<id>.name` : display name.
- `channels.zalo.accounts.<id>.enabled` : enable/disable account.
- `channels.zalo.accounts.<id>.dmPolicy` : per-account DM policy.
- `channels.zalo.accounts.<id>.allowFrom` : per-account allowlist.
2026-03-15 20:40:35 +01:00
- `channels.zalo.accounts.<id>.groupPolicy` : per-account group policy. Present in config; see [Capabilities ](#capabilities ) and [Access control (Groups) ](#access-control-groups ) for current Marketplace-bot behavior.
2026-02-24 23:30:05 +00:00
- `channels.zalo.accounts.<id>.groupAllowFrom` : per-account group sender allowlist.
2026-01-15 05:03:50 +00:00
- `channels.zalo.accounts.<id>.webhookUrl` : per-account webhook URL.
- `channels.zalo.accounts.<id>.webhookSecret` : per-account webhook secret.
- `channels.zalo.accounts.<id>.webhookPath` : per-account webhook path.
- `channels.zalo.accounts.<id>.proxy` : per-account proxy URL.