TypeScript SDK for the Zalo Bot API with a practical node-style API: events, regex text handlers, long polling, webhook helpers, and CommonJS-friendly usage.
Docs public | Tiếng Việt | English docs
new Bot(token, { polling: true })ornew Bot({ token, polling: true })bot.on("message" | "text" | "photo" | "sticker" | "command", callback)bot.onText(regexp, callback)for regex-based text handlersbot.startPolling(),bot.stopPolling(),bot.isPolling()bot.processUpdate(update)for webhook flowsbot.sendMessage(),bot.sendPhoto(),bot.sendSticker(),bot.sendChatAction()bot.setWebHook(),bot.deleteWebHook(),bot.getWebHookInfo()bot.getMe()andbot.getUpdates()
npm i zalo-bot-jsZALO_BOT_TOKEN=your_zalo_bot_token_here
ZALO_BOT_LANG=viZALO_BOT_LANG currently supports vi and en.
const { ZaloBot } = require("zalo-bot-js");
require("dotenv").config();
const bot = new ZaloBot(process.env.ZALO_BOT_TOKEN, {
polling: true,
});
bot.on("message", async (msg) => {
console.log("Received message:", msg.text ?? msg.messageId);
});
bot.onText(/\/start (.+)/, async (msg, match) => {
await bot.sendMessage(msg.chat.id, `Ban vua gui: ${match[1]}`);
});import "dotenv/config";
import { Bot } from "zalo-bot-js";
const bot = new Bot(process.env.ZALO_BOT_TOKEN!, {
polling: true,
});
bot.on("text", async (msg) => {
if (msg.text && !msg.text.startsWith("/")) {
await bot.sendMessage(msg.chat.id, `Ban vua noi: ${msg.text}`);
}
});
bot.onText(/\/start(?:\s+(.+))?/, async (msg, match) => {
const payload = match[1]?.trim() ?? "ban";
await bot.sendMessage(msg.chat.id, `Xin chao ${payload}!`);
});import "dotenv/config";
import express from "express";
import { Bot } from "zalo-bot-js";
const app = express();
const secretToken = process.env.ZALO_WEBHOOK_SECRET!;
const bot = new Bot(process.env.ZALO_BOT_TOKEN!, {
polling: false,
});
app.use(express.json());
bot.on("message", async (msg) => {
await bot.sendMessage(msg.chat.id, "Xin chao!");
});
app.post("/webhook", async (req, res) => {
if (req.headers["x-bot-api-secret-token"] !== secretToken) {
res.status(403).json({ message: "Unauthorized" });
return;
}
await bot.processUpdate(req.body);
res.sendStatus(200);
});
await bot.setWebHook(process.env.ZALO_WEBHOOK_URL!, {
secret_token: secretToken,
});bot.on(event, callback)bot.onText(regexp, callback)
Supported event names today:
messagetextphotostickercommand
bot.sendMessage(chatId, text, [options])bot.sendPhoto(chatId, caption, photo, [options])bot.sendSticker(chatId, sticker, [options])bot.sendChatAction(chatId, action, [options])
bot.startPolling([options])bot.stopPolling()bot.isPolling()bot.processUpdate(update)bot.setWebHook(url, [options])bot.deleteWebHook()bot.getWebHookInfo()
bot.getMe([options])bot.getUpdates([options])
src/request: transport and API error mappingsrc/models:User,Chat,Message,Update,WebhookInfosrc/core:Bot,Application,ApplicationBuilder,CallbackContextsrc/handlers: legacy handler-based APIsrc/filters: composable filtersexamples: example integrationstest: local scripts and focused verification
npm run check
npm run build
npm testUseful local scripts:
npm run test:tokennpm run test:hello-botnpm run test:event-debugnpm run test:bot-api
- The SDK currently focuses on the practical bot core first.
- Multipart media upload is still incomplete.
- Sending multiple images in a single native album-style Zalo message is not implemented.
Applicationand handler/filter APIs are still exported for backward compatibility.
MIT License. See LICENSE for details.
