OpenClawSkills
GitHub
Channels β€’ TutorialHeader.readTime

Zalo

Zalo bot: support status, capabilities, and configuration.

Status: Experimental. Currently supports DM (1:1) only; group support is "coming soon" per Zalo docs.

Tutorial.step

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''

Tutorial.step

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:

Json5
{
  channels: {
    zalo: {
      enabled: true,
      botToken: "12345689:abc-xyz",
      dmPolicy: "pairing",
    },
  },
}
Tutorial.step

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").

Tutorial.step

Setup (Quick Path)

#

Tutorial.step

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).

#

Tutorial.step

2) Configure token (env or config)

Example:

Json5
{
  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.

Tutorial.step

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.

Tutorial.step

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.

Tutorial.step

Access Control (DM)

#

Tutorial.step

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).

Tutorial.step

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.

Tutorial.step

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).

Tutorial.step

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) |

Tutorial.step

Delivery Target (CLI/cron)

- target uses chat id.

- Example: openclaw message send --channel zalo --target 123456789 --message "hi".

Tutorial.step

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)

Tutorial.step

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