{ "title": "Zalo (Bot API)", "content": "Status: experimental. Direct messages only; groups coming soon per Zalo docs.\n\nZalo ships as a plugin and is not bundled with the core install.\n\n* Install via CLI: `openclaw plugins install @openclaw/zalo`\n* Or select **Zalo** during onboarding and confirm the install prompt\n* Details: [Plugins](/plugin)\n\n## Quick setup (beginner)\n\n1. Install the Zalo plugin:\n * From a source checkout: `openclaw plugins install ./extensions/zalo`\n * From npm (if published): `openclaw plugins install @openclaw/zalo`\n * Or pick **Zalo** in onboarding and confirm the install prompt\n2. Set the token:\n * Env: `ZALO_BOT_TOKEN=...`\n * Or config: `channels.zalo.botToken: \"...\"`.\n3. Restart the gateway (or finish onboarding).\n4. DM access is pairing by default; approve the pairing code on first contact.\n\nZalo is a Vietnam-focused messaging app; its Bot API lets the Gateway run a bot for 1:1 conversations.\nIt is a good fit for support or notifications where you want deterministic routing back to Zalo.\n\n* A Zalo Bot API channel owned by the Gateway.\n* Deterministic routing: replies go back to Zalo; the model never chooses channels.\n* DMs share the agent's main session.\n* Groups are not yet supported (Zalo docs state \"coming soon\").\n\n### 1) Create a bot token (Zalo Bot Platform)\n\n1. Go to **[https://bot.zaloplatforms.com](https://bot.zaloplatforms.com)** and sign in.\n2. Create a new bot and configure its settings.\n3. Copy the bot token (format: `12345689:abc-xyz`).\n\n### 2) Configure the token (env or config)\n\nEnv option: `ZALO_BOT_TOKEN=...` (works for the default account only).\n\nMulti-account support: use `channels.zalo.accounts` with per-account tokens and optional `name`.\n\n3. Restart the gateway. Zalo starts when a token is resolved (env or config).\n4. DM access defaults to pairing. Approve the code when the bot is first contacted.\n\n## How it works (behavior)\n\n* Inbound messages are normalized into the shared channel envelope with media placeholders.\n* Replies always route back to the same Zalo chat.\n* Long-polling by default; webhook mode available with `channels.zalo.webhookUrl`.\n\n* Outbound text is chunked to 2000 characters (Zalo API limit).\n* Media downloads/uploads are capped by `channels.zalo.mediaMaxMb` (default 5).\n* Streaming is blocked by default due to the 2000 char limit making streaming less useful.\n\n## Access control (DMs)\n\n* Default: `channels.zalo.dmPolicy = \"pairing\"`. Unknown senders receive a pairing code; messages are ignored until approved (codes expire after 1 hour).\n* Approve via:\n * `openclaw pairing list zalo`\n * `openclaw pairing approve zalo `\n* Pairing is the default token exchange. Details: [Pairing](/start/pairing)\n* `channels.zalo.allowFrom` accepts numeric user IDs (no username lookup available).\n\n## Long-polling vs webhook\n\n* Default: long-polling (no public URL required).\n* Webhook mode: set `channels.zalo.webhookUrl` and `channels.zalo.webhookSecret`.\n * The webhook secret must be 8-256 characters.\n * Webhook URL must use HTTPS.\n * Zalo sends events with `X-Bot-Api-Secret-Token` header for verification.\n * Gateway HTTP handles webhook requests at `channels.zalo.webhookPath` (defaults to the webhook URL path).\n\n**Note:** getUpdates (polling) and webhook are mutually exclusive per Zalo API docs.\n\n## Supported message types\n\n* **Text messages**: Full support with 2000 character chunking.\n* **Image messages**: Download and process inbound images; send images via `sendPhoto`.\n* **Stickers**: Logged but not fully processed (no agent response).\n* **Unsupported types**: Logged (e.g., messages from protected users).\n\n| Feature | Status |\n| --------------- | ----------------------------- |\n| Direct messages | ✅ Supported |\n| Groups | ❌ Coming soon (per Zalo docs) |\n| Media (images) | ✅ Supported |\n| Reactions | ❌ Not supported |\n| Threads | ❌ Not supported |\n| Polls | ❌ Not supported |\n| Native commands | ❌ Not supported |\n| Streaming | ⚠️ Blocked (2000 char limit) |\n\n## Delivery targets (CLI/cron)\n\n* Use a chat id as the target.\n* Example: `openclaw message send --channel zalo --target 123456789 --message \"hi\"`.\n\n**Bot doesn't respond:**\n\n* Check that the token is valid: `openclaw channels status --probe`\n* Verify the sender is approved (pairing or allowFrom)\n* Check gateway logs: `openclaw logs --follow`\n\n**Webhook not receiving events:**\n\n* Ensure webhook URL uses HTTPS\n* Verify secret token is 8-256 characters\n* Confirm the gateway HTTP endpoint is reachable on the configured path\n* Check that getUpdates polling is not running (they're mutually exclusive)\n\n## Configuration reference (Zalo)\n\nFull configuration: [Configuration](/gateway/configuration)\n\n* `channels.zalo.enabled`: enable/disable channel startup.\n* `channels.zalo.botToken`: bot token from Zalo Bot Platform.\n* `channels.zalo.tokenFile`: read token from file path.\n* `channels.zalo.dmPolicy`: `pairing | allowlist | open | disabled` (default: pairing).\n* `channels.zalo.allowFrom`: DM allowlist (user IDs). `open` requires `\"*\"`. The wizard will ask for numeric IDs.\n* `channels.zalo.mediaMaxMb`: inbound/outbound media cap (MB, default 5).\n* `channels.zalo.webhookUrl`: enable webhook mode (HTTPS required).\n* `channels.zalo.webhookSecret`: webhook secret (8-256 chars).\n* `channels.zalo.webhookPath`: webhook path on the gateway HTTP server.\n* `channels.zalo.proxy`: proxy URL for API requests.\n\nMulti-account options:\n\n* `channels.zalo.accounts..botToken`: per-account token.\n* `channels.zalo.accounts..tokenFile`: per-account token file.\n* `channels.zalo.accounts..name`: display name.\n* `channels.zalo.accounts..enabled`: enable/disable account.\n* `channels.zalo.accounts..dmPolicy`: per-account DM policy.\n* `channels.zalo.accounts..allowFrom`: per-account allowlist.\n* `channels.zalo.accounts..webhookUrl`: per-account webhook URL.\n* `channels.zalo.accounts..webhookSecret`: per-account webhook secret.\n* `channels.zalo.accounts..webhookPath`: per-account webhook path.\n* `channels.zalo.accounts..proxy`: per-account proxy URL.", "code_samples": [ { "code": "## What it is\n\nZalo is a Vietnam-focused messaging app; its Bot API lets the Gateway run a bot for 1:1 conversations.\nIt is a good fit for support or notifications where you want deterministic routing back to Zalo.\n\n* A Zalo Bot API channel owned by the Gateway.\n* Deterministic routing: replies go back to Zalo; the model never chooses channels.\n* DMs share the agent's main session.\n* Groups are not yet supported (Zalo docs state \"coming soon\").\n\n## Setup (fast path)\n\n### 1) Create a bot token (Zalo Bot Platform)\n\n1. Go to **[https://bot.zaloplatforms.com](https://bot.zaloplatforms.com)** and sign in.\n2. Create a new bot and configure its settings.\n3. Copy the bot token (format: `12345689:abc-xyz`).\n\n### 2) Configure the token (env or config)\n\nExample:", "language": "unknown" } ], "headings": [ { "level": "h2", "text": "Plugin required", "id": "plugin-required" }, { "level": "h2", "text": "Quick setup (beginner)", "id": "quick-setup-(beginner)" }, { "level": "h2", "text": "What it is", "id": "what-it-is" }, { "level": "h2", "text": "Setup (fast path)", "id": "setup-(fast-path)" }, { "level": "h3", "text": "1) Create a bot token (Zalo Bot Platform)", "id": "1)-create-a-bot-token-(zalo-bot-platform)" }, { "level": "h3", "text": "2) Configure the token (env or config)", "id": "2)-configure-the-token-(env-or-config)" }, { "level": "h2", "text": "How it works (behavior)", "id": "how-it-works-(behavior)" }, { "level": "h2", "text": "Limits", "id": "limits" }, { "level": "h2", "text": "Access control (DMs)", "id": "access-control-(dms)" }, { "level": "h3", "text": "DM access", "id": "dm-access" }, { "level": "h2", "text": "Long-polling vs webhook", "id": "long-polling-vs-webhook" }, { "level": "h2", "text": "Supported message types", "id": "supported-message-types" }, { "level": "h2", "text": "Capabilities", "id": "capabilities" }, { "level": "h2", "text": "Delivery targets (CLI/cron)", "id": "delivery-targets-(cli/cron)" }, { "level": "h2", "text": "Troubleshooting", "id": "troubleshooting" }, { "level": "h2", "text": "Configuration reference (Zalo)", "id": "configuration-reference-(zalo)" } ], "url": "llms-txt#zalo-(bot-api)", "links": [] }