Package Exports
- @warriorteam/redai-zalo-sdk
- @warriorteam/redai-zalo-sdk/dist/index.js
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (@warriorteam/redai-zalo-sdk) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
RedAI Zalo SDK
A comprehensive TypeScript/JavaScript SDK for Zalo APIs, providing easy-to-use interfaces for:
- Official Account (OA) API - Manage your Zalo Official Account
- Consultation Service - Send customer support messages within 48-hour window
- Broadcast Service - Send mass communication messages with targeting criteria
- Zalo Notification Service (ZNS) - Send template-based notification messages
- Social API - Access user social information and authentication
- Group Message Framework (GMF) - Send messages to Zalo groups
- User Management - Comprehensive user profile and tag management
- Content Management - Upload and manage media content (images, files, articles)
- Enhanced Article Management - Get all articles with auto-pagination and progress tracking
- Video Upload - Upload and manage video content with processing
- Tag Management - User tagging and segmentation
- Webhook handling - Process Zalo webhook events
Features
- π TypeScript Support - Full type safety and IntelliSense
- π OAuth 2.0 Flow - Complete authentication handling
- π Auto Retry - Built-in retry mechanism for failed requests
- π Comprehensive Logging - Debug and monitor API calls
- π‘οΈ Error Handling - Detailed error information and handling
- π¦ Zero Dependencies - Only requires axios and form-data
- π― Promise-based - Modern async/await support
- π Auto-Pagination - Automatically fetch all articles with progress tracking
Installation
npm install @warriorteam/redai-zalo-sdk
π¨ Version 1.9.0 - Breaking Changes
ZNS Template API has been completely restructured to match Zalo API 100%
What Changed:
- β Fixed: All ZNS template interfaces now match official Zalo API docs
- β
Added: Proper
layout
structure with header/body/footer components - β Added: Complete enum support for template types, tags, buttons, and params
- β Added: Validation helpers and constants
- β Removed: Non-existent fields like
templateContent
,timeout
,previewUrl
- π Changed: Field names from camelCase to snake_case (e.g.,
templateId
βtemplate_id
)
Migration Required:
// β Before v1.9.0 (BROKEN)
const templateData = {
templateId: "123",
templateContent: "Hello" // Field doesn't exist in Zalo API
};
// β
After v1.9.0 (CORRECT)
import { ZNSTemplateType, ZNSTemplateTag } from '@warriorteam/redai-zalo-sdk';
const templateData = {
template_id: "123",
template_name: "My Template",
template_type: ZNSTemplateType.CUSTOM,
tag: ZNSTemplateTag.TRANSACTION,
layout: {
body: {
components: [{ TITLE: { value: "Hello" } }]
}
},
tracking_id: "track_001"
};
See CHANGELOG.md for complete migration guide.
π Documentation
π Getting Started
- API Reference - Complete API documentation and method reference
- Authentication Guide - OAuth 2.0 flows for OA and Social APIs
- Architecture Overview - SDK architecture and design patterns
- Services Added - Detailed breakdown of all services and features
π¨ Messaging & Communication
- Message Services - Complete guide for all message types and services
- Consultation Service - Customer service messaging guide
- ZNS Service - Zalo Notification Service for template messages
- Group Management - Group messaging and management
π₯ User & Content Management
User Management - User profiles, followers, and management
Tag Management - User tagging and segmentation system
Article Management - Content and article management
Webhook Types (Source of Truth) - Strongly-typed webhook event definitions
π Events & Integration
- Webhook Events Guide - Complete guide for all 70+ webhook event types
Development
Build from source
# Clone the repository
git clone https://github.com/redai/redai-zalo-sdk.git
cd redai-zalo-sdk
# Install dependencies
npm install
# Build the SDK
npm run build
# Run examples
npm run dev
Quick Start
Initialize the SDK
import { ZaloSDK } from "@warriorteam/redai-zalo-sdk";
const zalo = new ZaloSDK({
appId: "your-app-id",
appSecret: "your-app-secret",
debug: true, // Enable debug logging
});
Authentication Flow
Official Account (OA) Authentication
// 1. Create authorization URL
const authUrl = zalo.createOAAuthUrl("https://your-app.com/callback");
console.log("Visit:", authUrl);
// 2. Exchange authorization code for access token
const accessToken = await zalo.getOAAccessToken(
"authorization-code-from-callback",
"https://your-app.com/callback"
);
console.log("Access Token:", accessToken.access_token);
Social API Authentication
// 1. Generate PKCE for security (recommended)
const pkce = zalo.generatePKCE();
// 2. Create authorization URL
const authUrl = zalo.createSocialAuthUrl("https://your-app.com/callback");
// 3. Exchange code for access token
const accessToken = await zalo.getSocialAccessToken(
"authorization-code",
"https://your-app.com/callback",
pkce.code_verifier
);
Official Account Operations
// Get OA information
const oaInfo = await zalo.getOAInfo(accessToken.access_token);
console.log("OA Name:", oaInfo.name);
console.log("Followers:", oaInfo.num_follower);
// Check message quota
const quota = await zalo.getMessageQuota(accessToken.access_token);
console.log("Daily Quota:", quota.daily_quota);
console.log("Remaining:", quota.remaining_quota);
// Get detailed quota information
const detailedQuota = await zalo.oa.getQuotaSummary(accessToken.access_token);
console.log("Consultation Quota:", detailedQuota.consultation);
console.log("Transaction Quota:", detailedQuota.transaction);
Social API Operations
// Get user information
const userInfo = await zalo.getSocialUserInfo(
accessToken.access_token,
"id,name,picture,birthday"
);
console.log("User ID:", userInfo.id);
console.log("Name:", userInfo.name);
console.log("Avatar:", userInfo.picture?.data.url);
Token Management
// Refresh OA access token
const newOAToken = await zalo.refreshOAAccessToken(refreshToken);
// Refresh Social access token
const newSocialToken = await zalo.refreshSocialAccessToken(refreshToken);
// Validate token
const isValid = await zalo.validateAccessToken(accessToken.access_token, "oa");
Advanced Usage
Custom API Requests
// Make custom API calls
const customData = await zalo.customRequest(
"POST",
"/v3.0/oa/message/cs",
accessToken.access_token,
{
recipient: { user_id: "user-id" },
message: { text: "Hello from SDK!" },
}
);
File Upload
import fs from "fs";
// Upload image
const fileBuffer = fs.readFileSync("image.jpg");
const uploadResult = await zalo.uploadFile(
"/v2.0/oa/upload/image",
accessToken.access_token,
fileBuffer,
"image.jpg"
);
console.log("Uploaded URL:", uploadResult.data.url);
Error Handling
import { ZaloSDKError } from "redai-zalo-sdk";
try {
const oaInfo = await zalo.getOAInfo(accessToken.access_token);
} catch (error) {
if (error instanceof ZaloSDKError) {
console.error("Zalo API Error:", error.message);
console.error("Error Code:", error.code);
console.error("Details:", error.details);
} else {
console.error("Unexpected error:", error);
}
}
Configuration Options
const zalo = new ZaloSDK({
appId: "your-app-id",
appSecret: "your-app-secret",
// Optional configurations
timeout: 30000, // Request timeout in ms (default: 30000)
debug: false, // Enable debug logging (default: false)
apiBaseUrl: "https://openapi.zalo.me", // Custom API base URL
// Retry configuration
retry: {
attempts: 3, // Number of retry attempts (default: 3)
delay: 1000, // Delay between retries in ms (default: 1000)
},
});
API Reference
ZaloSDK Class
Constructor
new ZaloSDK(config: ZaloSDKConfig)
Authentication Methods
createOAAuthUrl(redirectUri: string, state?: string): string
createSocialAuthUrl(redirectUri: string, state?: string): string
getOAAccessToken(code: string, redirectUri: string): Promise<AccessToken>
getSocialAccessToken(code: string, redirectUri: string, codeVerifier?: string): Promise<AccessToken>
refreshOAAccessToken(refreshToken: string): Promise<AccessToken>
refreshSocialAccessToken(refreshToken: string): Promise<AccessToken>
OA Methods
getOAInfo(accessToken: string): Promise<OAInfo>
getMessageQuota(accessToken: string): Promise<MessageQuota>
Social Methods
getSocialUserInfo(accessToken: string, fields?: string): Promise<SocialUserInfo>
Utility Methods
validateAccessToken(accessToken: string, scope?: 'oa' | 'social'): Promise<boolean>
generatePKCE(): PKCEConfig
testConnection(): Promise<boolean>
Services
AuthService
- Complete OAuth 2.0 flow handling
- PKCE support for Social API
- Token validation and refresh
OAService
- Official Account information management
- Quota monitoring and management
- Profile updates
Error Handling
The SDK throws ZaloSDKError
for all Zalo API related errors:
class ZaloSDKError extends Error {
code: number; // Zalo API error code
details?: any; // Additional error details
}
Common error codes:
-216
: Invalid access token-201
: Invalid parameters-223
: Quota exceeded
TypeScript Support
The SDK is written in TypeScript and provides comprehensive type definitions:
import {
ZaloSDK,
ZaloSDKConfig,
AccessToken,
OAInfo,
SocialUserInfo,
ZaloSDKError,
} from "redai-zalo-sdk";
Contributing
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature
) - Commit your changes (
git commit -m 'Add some amazing feature'
) - Push to the branch (
git push origin feature/amazing-feature
) - Open a Pull Request
License
This project is licensed under the MIT License - see the LICENSE file for details.
Support
For support and questions:
- Create an issue on GitHub
- Contact RedAI team
Broadcast Service (Mass Communication)
// Create targeting criteria
const target = zalo.broadcast.createBroadcastTarget({
gender: "FEMALE", // Target female users
ages: ["18-24", "25-34"], // Age 18-34
cities: ["Hα» ChΓ Minh", "HΓ Nα»i"], // Ho Chi Minh City and Hanoi
platforms: ["ANDROID", "IOS"] // Android and iOS users
});
// Send broadcast message
const result = await zalo.broadcast.sendBroadcastMessage(
accessToken,
{ target },
"article-attachment-id"
);
console.log("Broadcast sent:", result.data.message_id);
// Simple city targeting
const hcmTarget = zalo.broadcast.createBroadcastTarget({
cities: ["Hα» ChΓ Minh"]
});
await zalo.broadcast.sendBroadcastMessage(
accessToken,
{ target: hcmTarget },
"article-id"
);
// Send multiple broadcast messages
const attachmentIds = ["article-1", "article-2", "article-3"];
const multipleResult = await zalo.broadcast.sendMultipleBroadcastMessages(
accessToken,
{ target: hcmTarget },
attachmentIds,
{
mode: 'sequential',
delay: 2000, // 2 seconds between messages
onProgress: (progress) => {
console.log(`Progress: ${progress.completed}/${progress.total}`);
}
}
);
console.log(`Sent ${multipleResult.successfulMessages}/${multipleResult.totalMessages} messages`);
Consultation Service (Customer Support)
// Send consultation text message
await zalo.consultation.sendTextMessage(accessToken,
{ user_id: "user-id" },
{
type: "text",
text: "Xin chà o! Tôi có thỠhỠtrợ gì cho bẑn?"
}
);
// Send consultation image with guide
await zalo.consultation.sendImageMessage(accessToken,
{ user_id: "user-id" },
{
type: "image",
attachment: {
type: "image",
payload: {
url: "https://example.com/support-guide.jpg"
}
}
}
);
// Send file attachment for support
await zalo.consultation.sendFileMessage(accessToken,
{ user_id: "user-id" },
{
type: "file",
url: "https://example.com/manual.pdf",
filename: "User Manual.pdf",
attachment: {
type: "file",
payload: {
url: "https://example.com/manual.pdf"
}
}
}
);
ZNS (Zalo Notification Service)
// Send ZNS notification
await zalo.zns.sendMessage(accessToken, {
phone: "0123456789",
template_id: "your-template-id",
template_data: {
customer_name: "John Doe",
order_id: "12345",
},
});
// Get ZNS quota
const quota = await zalo.zns.getQuotaInfo(accessToken);
// Manage ZNS templates
const templates = await zalo.zns.getTemplateList(accessToken);
const template = await zalo.zns.createTemplate(accessToken, {
templateName: "Order Confirmation",
templateContent:
"Hello {{customer_name}}, your order {{order_id}} is confirmed.",
templateType: 3, // Confirmation type
});
Group Messaging
// Send text message to group
await zalo.groupMessage.sendTextMessage(accessToken, groupId, {
type: "text",
text: "Hello everyone!",
});
// Send image to group
await zalo.groupMessage.sendImageMessage(accessToken, groupId, {
type: "image",
imageUrl: "https://example.com/image.jpg",
caption: "Check this out!",
});
// Get group information
const groupInfo = await zalo.groupMessage.getGroupInfo(accessToken, groupId);
const members = await zalo.groupMessage.getGroupMembers(accessToken, groupId);
User Management
// Get user profile
const profile = await zalo.userManagement.getUserProfile(accessToken, userId);
// Tag management
await zalo.tag.createTag(accessToken, "VIP Customer");
await zalo.tag.tagUser(accessToken, userId, ["VIP Customer", "Premium"]);
const userTags = await zalo.tag.getUserTags(accessToken, userId);
// Get followers list
const followers = await zalo.userManagement.getFollowersList(accessToken);
Content Management
// Upload image
const imageResult = await zalo.content.uploadImage(accessToken, imageBuffer);
// Create article
const article = await zalo.content.createArticle(accessToken, {
title: "Welcome to our service",
body: "Article content here...",
cover_photo_id: imageResult.data.attachment_id,
});
// Share article to user
await zalo.content.shareArticle(accessToken, userId, article.data.id);
Video Upload
// Upload video
const uploadResult = await zalo.videoUpload.uploadVideo(
accessToken,
videoBuffer,
"video.mp4"
);
// Wait for processing completion
const finalResult = await zalo.videoUpload.waitForUploadCompletion(
accessToken,
uploadResult.data.token
);
if (finalResult.status === "ready") {
// Send video message
await zalo.videoUpload.sendVideoMessage(
accessToken,
userId,
finalResult.attachment_id,
"Check out this video!"
);
}
Social API
// Get user social information
const userInfo = await zalo.social.getUserInfo(accessToken);
// Get friends list
const friends = await zalo.social.getFriendsList(accessToken);
// Post to timeline
await zalo.social.postToTimeline(accessToken, "Hello from Zalo SDK!");
π Webhook Events
The SDK provides comprehensive webhook event handling with 70+ event types:
import { WebhookHandlers } from "@warriorteam/redai-zalo-sdk";
const handlers: WebhookHandlers = {
// User message events
user_send_text: async (event) => {
console.log("User sent:", event.message.text);
},
// Group events
user_send_group_audio: async (event) => {
console.log("Audio in group:", event.message.attachments[0].payload.url);
},
// ZNS events
change_template_status: async (event) => {
console.log("Template status:", event.status);
},
// Widget events
widget_interaction_accepted: async (event) => {
console.log("Widget accepted:", event.data.user_external_id);
},
// System events
permission_revoked: async (event) => {
console.log("Permission revoked by:", event.data.action_by);
},
};
Event Categories:
- User Message Events (11 types): text, image, video, audio, file, sticker, gif, location, link, business card, reaction
- OA Message Events (11 types): All message types + anonymous + template
- Group Events (22 types): Create, join, admin, leave + all message types for both user and OA
- ZNS Events (8 types): Quota, template, journey, delivery, status changes
- Widget Events (2 types): Interaction accepted, sync failures
- System Events (4 types): Permission, extension, user info, tags
- Call Events (2 types): OA call user, user call OA
- Anonymous Events (4 types): Anonymous chat support
- Shop Events (1 type): Order management
π― Message Classification Helpers
The SDK provides helper functions to easily classify webhook message events:
import {
isUserMessageEvent,
isGroupMessageEvent,
isOAToUserMessageEvent,
isOAToGroupMessageEvent,
getMessageDirection,
} from "@warriorteam/redai-zalo-sdk";
function handleWebhook(event: WebhookEvent) {
if (isUserMessageEvent(event)) {
console.log("Message from individual user");
} else if (isGroupMessageEvent(event)) {
console.log("Message from group");
} else if (isOAToUserMessageEvent(event)) {
console.log("OA sent message to user");
} else if (isOAToGroupMessageEvent(event)) {
console.log("OA sent message to group");
}
// Or use the unified helper
const { direction, target, description } = getMessageDirection(event);
console.log(`${direction} message to ${target}: ${description}`);
}
For complete webhook documentation, see:
- Webhook Events Guide - Complete guide for all 70+ webhook event types
- Message Classification Helpers - Helper functions for message classification
Changelog
v1.0.0
- Initial release
- Official Account API support
- ZNS (Zalo Notification Service) support
- Group Message Framework (GMF) support
- Social API support
- User Management features
- Content and Video Upload capabilities
- Tag Management system
- Comprehensive webhook handling
- Social API support
- Authentication flow
- TypeScript support