npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@rurimeiko/zalo-channel

v1.0.13

Published

Zalo messaging integration for OpenClaw - Multi-account support with QR/cookie login, message sending, and event handling (TypeScript)

Downloads

1,311

Readme

OpenClaw Zalo Channel Plugin (TypeScript)

Zalo messaging integration for OpenClaw Gateway. Based on MultiZlogin architecture with support for multiple accounts, proxy rotation, and comprehensive event handling. Written in TypeScript for better type safety and maintainability.

Features

  • Multi-account support: Login and manage multiple Zalo accounts simultaneously
  • QR & Cookie login: Login via QR code or reuse saved cookies
  • Message handling: Send/receive text messages, images, stickers, reactions
  • Group support: Full support for group chats
  • Proxy support: Automatic proxy rotation and health checks
  • Webhook forwarding: Forward all events to external webhooks
  • Auto-relogin: Automatic reconnection when connection drops
  • Bot message filtering: Prevent echo loops using Redis caching
  • Health monitoring: Connection health checks and retry logic
  • TypeScript: Full type safety and IntelliSense support

Project Structure

openclaw-zalo-channel/
├── src/
│   ├── config/
│   │   ├── types.ts          # TypeScript interfaces and types
│   │   ├── constants.ts      # Constants and enums
│   │   └── env.ts            # Environment configuration
│   ├── services/
│   │   ├── zaloService.ts    # Core Zalo API (login, logout, messaging)
│   │   ├── eventService.ts   # Event handling and webhooks
│   │   ├── redisService.ts   # Redis caching for bot messages
│   │   └── proxyService.ts   # Proxy management
│   ├── controllers/
│   │   ├── channelController.ts   # Channel registration
│   │   ├── commandController.ts   # CLI commands
│   │   ├── toolController.ts      # Agent tools
│   │   └── serviceController.ts   # Background service
│   ├── utils/
│   │   └── helpers.ts        # Utility functions
│   └── index.ts              # Plugin entry point
├── dist/                     # Compiled JavaScript (after build)
├── openclaw.plugin.json      # Plugin manifest
├── package.json              # NPM configuration
├── tsconfig.json             # TypeScript configuration
└── README.md                 # This file

Installation

Prerequisites

  • Node.js 18+
  • TypeScript 5.3+
  • Redis server (optional, for bot message caching)

Build from Source

# Install dependencies
npm install

# Build TypeScript
npm run build

# Or watch for changes during development
npm run build:watch

Install to OpenClaw

# Copy plugin to OpenClaw extensions directory
cp -r openclaw-zalo-channel /path/to/openclaw/extensions/

# Or use OpenClaw CLI
openclaw plugin install ./openclaw-zalo-channel

Configuration

Add to your openclaw.json:

{
  "plugins": {
    "entries": {
      "openclaw-zalo-channel": {
        "enabled": true,
        "config": {
          "dataPath": "./data/zalo",
          "webhookUrl": "https://your-webhook-endpoint.com/webhook",
          "redisUrl": "redis://localhost:6379",
          "maxAccountsPerProxy": 3,
          "proxies": [
            "http://proxy1.example.com:8080",
            "http://proxy2.example.com:8080"
          ]
        }
      }
    }
  }
}

Configuration Options

| Option | Type | Default | Description | |--------|------|---------|-------------| | dataPath | string | ./data/zalo | Directory for storing cookies and credentials | | webhookUrl | string | - | URL to forward Zalo events (messages, reactions, group events) | | redisUrl | string | redis://localhost:6379 | Redis connection URL for bot message caching | | maxAccountsPerProxy | number | 3 | Maximum accounts per proxy | | proxies | array | [] | List of proxy URLs for rotation |

CLI Commands

/zalo:login [proxy_url]

Login to Zalo account via QR code or saved cookie.

/zalo:login
/zalo:login http://proxy.example.com:8080

/zalo:logout <ownId>

Logout from a specific Zalo account.

/zalo:logout 123456789

/zalo:accounts

List all logged in Zalo accounts with their connection status.

/zalo:accounts

/zalo:send <ownId> <threadId> <user|group> <message>

Send a message via a specific account.

/zalo:send 123456789 987654321 user Hello World!
/zalo:send 123456789 987654321 group Hello Group!

/zalo:status

Show plugin status (total accounts, online/offline count).

/zalo:status

Agent Tools

zalo_send_message

Send a text message to a Zalo user or group.

{
  accountId: string;    // Zalo account ID (ownId)
  threadId: string;     // Target user or group ID
  threadType: "user" | "group";
  message: string;      // Message content
}

zalo_send_image

Send an image to a conversation.

{
  accountId: string;
  threadId: string;
  threadType: "user" | "group";
  imageUrl: string;     // URL of the image
}

zalo_get_user_info

Get information about a Zalo user by phone number or user ID.

{
  accountId: string;
  phoneNumber?: string;  // Optional if userId provided
  userId?: string;       // Optional if phoneNumber provided
}

zalo_find_user

Find a Zalo user by phone number.

{
  accountId: string;
  phoneNumber: string;
}

zalo_send_typing

Send typing indicator to a conversation.

{
  accountId: string;
  threadId: string;
  threadType: "user" | "group";
}

zalo_add_reaction

Add a reaction (emoji) to a message.

{
  accountId: string;
  msgId: string;
  threadId: string;
  threadType: "user" | "group";
  icon: string;         // Emoji like ❤️, 👍, 😂
}

zalo_send_sticker

Send a sticker to a conversation.

{
  accountId: string;
  threadId: string;
  threadType: "user" | "group";
  sticker: object;      // Sticker object with id, type, etc.
}

zalo_get_group_info

Get information about a Zalo group.

{
  accountId: string;
  groupId: string;
}

Channel Integration

As a channel plugin, it integrates with OpenClaw's channel system:

// Send via OpenClaw Gateway
api.gateway.send({
  channel: "zalo",
  accountId: "<ownId>",
  target: { threadId: "<user_or_group_id>" },
  content: { text: "Hello from OpenClaw!" },
  metadata: { threadType: "user" }
});

Webhook Events

Events are sent to the configured webhookUrl:

Message Event

{
  "event": "message",
  "timestamp": 1234567890,
  "data": {
    "accountId": "123456789",
    "messageType": "user",
    "isGroup": false,
    "chatType": "personal",
    "bot": false,
    "raw": { /* raw message data */ }
  }
}

Login Success Event

{
  "event": "login_success",
  "timestamp": 1234567890,
  "data": {
    "ownId": "123456789",
    "displayName": "User Name",
    "phoneNumber": "+84123456789",
    "proxy": "http://proxy.example.com:8080"
  }
}

Group Event

{
  "event": "group_event",
  "timestamp": 1234567890,
  "data": {
    "accountId": "123456789",
    "raw": { /* group event data */ }
  }
}

Reaction Event

{
  "event": "reaction",
  "timestamp": 1234567890,
  "data": {
    "accountId": "123456789",
    "raw": { /* reaction data */ }
  }
}

Data Directory Structure

data/zalo/
├── cookies/
│   ├── cred_<ownId1>.json    # Saved credentials for account 1
│   └── cred_<ownId2>.json    # Saved credentials for account 2
└── proxies.json               # Proxy configuration (auto-generated)

Architecture

Services

  • zaloService.ts: Core Zalo functionality - login/logout, messaging, account management
  • eventService.ts: Event handling - message, group, reaction events and webhook forwarding
  • redisService.ts: Redis caching - bot message deduplication
  • proxyService.ts: Proxy management - rotation, health checks

Controllers

  • channelController.ts: Channel registration with OpenClaw
  • commandController.ts: CLI command handlers
  • toolController.ts: Agent tool registration
  • serviceController.ts: Background service (health checks, cleanup)

Utilities

  • helpers.ts: Common utilities - image download, file operations, validators

Auto-Relogin

The plugin automatically handles connection drops:

  • Detects disconnection via listener events and health checks
  • Attempts re-login using saved cookies
  • Exponential backoff retry (max 5 attempts)
  • Resets retry counter after 30 minutes
  • Lock mechanism prevents concurrent relogin attempts

Bot Message Caching

Uses Redis to prevent echo loops:

  • All sent messages are cached with TTL (24 hours)
  • Incoming messages are checked against cache
  • Marked with bot: true if from self
  • Prevents the bot from responding to its own messages

Dependencies

Runtime

  • zca-js: Zalo unofficial API SDK
  • https-proxy-agent: Proxy support
  • ioredis: Redis client
  • axios: HTTP requests

Development

  • typescript: TypeScript compiler
  • @types/node: Node.js type definitions

API Types

The plugin exports TypeScript interfaces for external use:

import {
  OpenClawApi,
  ZaloAccount,
  ZaloMessage,
  ZaloCredentials,
  SendTextParams,
  // ... and more
} from 'openclaw-zalo-channel';

Development

# Install dependencies
npm install

# Build
npm run build

# Watch mode
npm run build:watch

# Clean build artifacts
npm run clean

License

MIT