redai-automation-web-sdk
Version:
TypeScript SDK for RedAI Automation Web API - Zalo Personal automation, messaging, advanced sticker search, and bulk operations. 100% compatible with automation-web backend. v1.5.3: Removed alias imports (@/), using relative imports for better portability
822 lines (662 loc) • 22 kB
Markdown
# RedAI Automation Web SDK
TypeScript/JavaScript SDK cho RedAI Automation Web API - Tự động hóa Zalo Personal và messaging.
## 🚀 Tính Năng
- ✅ **Authentication**: QR Code login, Credentials login, Session management
- ✅ **Messaging**: Gửi tin nhắn text, hình ảnh, video, voice, sticker, file, link, card
- ✅ **Sticker Search** 🆕: Tìm kiếm sticker, lấy chi tiết, sticker phổ biến với API cải tiến
- ✅ **Webhook Management**: Quản lý webhook listeners, thống kê, event history
- ✅ **Bulk Operations**: Batch check/add accounts to groups (Zalo Seeding)
- ✅ **Group Management**: Quản lý nhóm, thành viên, tạo/rời/giải tán nhóm
- ✅ **Friend Management**: Quản lý bạn bè, gửi/nhận lời mời kết bạn, block/unblock
- ✅ **Conversation Management**: Quản lý cuộc trò chuyện, pin/hide, lịch sử tin nhắn
- ✅ **User Info Management**: Lấy thông tin user, profile, kiểm tra tồn tại
- ✅ **Typed Webhook Events**: Type-safe webhook events với đầy đủ type definitions
- ✅ **Queue Job Types**: Cấu trúc job chuẩn khi đưa vào queue system
## 📦 Cài Đặt
```bash
npm install @redai/automation-web-sdk
```
## 🔧 Sử Dụng Cơ Bản
### Khởi tạo SDK
```typescript
import { AutomationWebClient } from '@redai/automation-web-sdk';
const client = new AutomationWebClient({
baseUrl: 'http://localhost:3000',
timeout: 30000,
logging: true,
});
```
### Authentication
#### QR Code Login
```typescript
// Tạo QR Code
const qrResult = await client.auth.generateQRCode({
userUuid: 'your-user-uuid',
timeout: 300, // 5 phút
});
console.log('QR Code:', qrResult.qrCode);
// Chờ đăng nhập
const loginStatus = await client.auth.waitForQRLogin(qrResult.sessionId, {
timeout: 300,
pollInterval: 2000,
onStatusChange: (status) => {
console.log('Trạng thái:', status.status);
},
});
if (loginStatus.status === 'success') {
console.log('Đăng nhập thành công!', loginStatus.userData);
}
```
#### Credentials Login
```typescript
const loginResult = await client.auth.loginWithCredentials({
userUuid: 'your-user-uuid',
credentials: {
cookie: [], // Zalo cookies từ browser
imei: 'device-imei',
userAgent: 'browser-user-agent',
language: 'vi',
},
options: {
selfListen: false,
autoReconnect: true,
},
});
```
### Messaging
#### Gửi tin nhắn text
```typescript
import { ThreadType } from '@redai/automation-web-sdk';
const result = await client.messaging.sendMessage({
sessionId: 'your-session-id',
threadId: 'target-user-id',
threadType: ThreadType.USER,
content: 'Xin chào từ SDK! 👋',
});
```
#### Gửi hình ảnh
```typescript
const result = await client.messaging.sendImage({
sessionId: 'your-session-id',
threadId: 'target-user-id',
threadType: ThreadType.USER,
imageUrl: 'https://example.com/image.jpg',
caption: 'Hình ảnh đẹp!',
});
```
#### Gửi video
```typescript
const result = await client.messaging.sendVideo({
sessionId: 'your-session-id',
threadId: 'target-user-id',
threadType: ThreadType.USER,
videoUrl: 'https://example.com/video.mp4',
caption: 'Video thú vị!',
});
```
### Webhook Events
```typescript
// Lắng nghe tin nhắn đến
client.onMessageReceived(async (event) => {
console.log('Tin nhắn mới:', event.data.eventData);
});
// Lắng nghe tin nhắn đã gửi
client.onMessageSent(async (event) => {
console.log('Đã gửi tin nhắn:', event.data.eventData);
});
// Lắng nghe sự kiện typing
client.onTyping(async (event) => {
console.log('Đang gõ:', event.data.eventData);
});
// Lắng nghe reaction
client.onMessageReaction(async (event) => {
console.log('Reaction:', event.data.eventData);
});
// Lắng nghe lỗi
client.onError(async (event) => {
console.error('Lỗi:', event.data.eventData);
});
```
### Session Management
```typescript
// Lấy danh sách session
const sessions = await client.auth.getSessions('user-uuid');
// Thống kê session
const stats = await client.auth.getSessionStatistics('user-uuid');
// Dọn dẹp session hết hạn
const cleanup = await client.auth.cleanupExpiredSessions('user-uuid');
// Debug session
const debugInfo = await client.auth.debugSession('session-id');
// Refresh session
const refreshed = await client.auth.refreshSession('session-id');
```
## 📚 API Reference
### AutomationWebClient
#### Constructor
```typescript
new AutomationWebClient(config: AutomationWebConfig)
```
**Config Options:**
- `baseUrl`: URL của automation-web API
- `timeout`: Timeout cho requests (ms)
- `retryCount`: Số lần retry khi lỗi
- `retryDelay`: Delay giữa các retry (ms)
- `apiKey`: API key (nếu cần)
- `userAgent`: Custom user agent
- `logging`: Bật/tắt logging
#### Services
- `client.auth`: Authentication service
- `client.messaging`: Messaging service
- `client.webhook`: Webhook management service
- `client.bulk`: Bulk operations service (Zalo Seeding)
- `client.groups`: Group management
- `client.friends`: Friend management
- `client.conversations`: Conversation management
- `client.userInfo`: User info management
- `client.profile`: Profile & Account management
### AuthService
#### Methods
- `generateQRCode(request)`: Tạo QR Code đăng nhập
- `getLoginStatus(sessionId, timeout?)`: Kiểm tra trạng thái đăng nhập
- `waitForQRLogin(sessionId, options)`: Chờ QR Code được scan
- `loginWithCredentials(request)`: Đăng nhập bằng credentials
- `getSessions(userUuid)`: Lấy danh sách session
- `deleteSession(sessionId)`: Xóa session
- `bulkDeleteSessions(request)`: Xóa nhiều session
- `debugSession(sessionId)`: Debug thông tin session
- `refreshSession(sessionId)`: Refresh session
- `getSessionStatistics(userUuid)`: Thống kê session
- `cleanupExpiredSessions(userUuid)`: Dọn dẹp session hết hạn
### MessagingService
#### Methods
- `sendMessage(request)`: Gửi tin nhắn text
- `sendImage(request)`: Gửi hình ảnh
- `sendVideo(request)`: Gửi video
- `sendVoice(request)`: Gửi voice
- `sendSticker(request)`: Gửi sticker
- `sendFile(request)`: Gửi file
- `sendLink(request)`: Gửi link
- `forwardMessage(request)`: Forward tin nhắn
- `deleteMessage(request)`: Xóa tin nhắn
- `undoMessage(request)`: Undo tin nhắn
- `addReaction(request)`: Thêm reaction
- `markAsDelivered(request)`: Đánh dấu đã nhận
- `markAsSeen(request)`: Đánh dấu đã xem
### SearchService (🆕 New APIs)
#### Sticker Search Methods
- `getStickers(request)`: Tìm sticker theo từ khóa (cải tiến với limit, includeDetails)
- `searchStickersWithDetails(request)`: Tìm sticker và lấy chi tiết trong một lần gọi (mới)
- `getPopularStickers(request)`: Lấy danh sách sticker phổ biến (mới)
- `getStickersDetail(request)`: Lấy chi tiết sticker theo IDs
#### Convenience Methods
- `searchStickersWithDetailsConvenience(sessionId, keyword, limit)`: Tìm sticker với chi tiết (convenience)
- `getPopularStickersConvenience(sessionId, limit, categoryId)`: Lấy sticker phổ biến (convenience)
- `quickSearchStickers(sessionId, keyword, limit)`: Tìm kiếm nhanh chỉ trả về IDs
- `fullSearchStickers(sessionId, keyword, limit)`: Tìm kiếm đầy đủ với metadata
#### Example Usage
```typescript
// Tìm sticker cơ bản (cải tiến)
const basicSearch = await client.search.getStickers({
sessionId: 'session-123',
keyword: 'hello',
limit: 20,
includeDetails: false
});
// Tìm sticker với chi tiết trong một lần gọi (API mới)
const detailedSearch = await client.search.searchStickersWithDetails({
sessionId: 'session-123',
keyword: 'love',
limit: 10
});
console.log(`Found ${detailedSearch.result.total} stickers in ${detailedSearch.result.searchTime}ms`);
// Lấy sticker phổ biến (API mới)
const popularStickers = await client.search.getPopularStickers({
sessionId: 'session-123',
limit: 15,
categoryId: 1 // Optional filter
});
// Convenience methods
const quickIds = await client.search.quickSearchStickers('session-123', 'happy', 5);
const fullResult = await client.search.fullSearchStickers('session-123', 'sad', 3);
```
## 🔧 Configuration
### Environment Variables
```bash
AUTOMATION_WEB_BASE_URL=http://localhost:3000
AUTOMATION_WEB_TIMEOUT=30000
AUTOMATION_WEB_RETRY_COUNT=3
AUTOMATION_WEB_LOGGING=true
```
### TypeScript Configuration
SDK được viết bằng TypeScript và cung cấp đầy đủ type definitions.
```typescript
import {
AutomationWebClient,
ThreadType,
Urgency,
WebhookEventType,
LoginStatus,
MessageType
} from '@redai/automation-web-sdk';
```
## 🚨 Error Handling
```typescript
import { HttpError, ValidationError } from '@redai/automation-web-sdk';
try {
await client.messaging.sendMessage(request);
} catch (error) {
if (error instanceof HttpError) {
console.error('HTTP Error:', error.status, error.message);
} else if (error instanceof ValidationError) {
console.error('Validation Error:', error.field, error.message);
} else {
console.error('Unknown Error:', error);
}
}
```
## 📝 Examples
Xem thêm examples trong thư mục `/examples`:
- [Basic Usage](./examples/basic-usage.ts)
- [Messaging Examples](./examples/messaging.ts)
- [Webhook Handling](./examples/webhook-handling.ts)
### GroupService
#### Methods
- `getAllGroups(request)`: Lấy tất cả groups của user
- `getGroupInfo(request)`: Lấy thông tin chi tiết của group
- `createGroup(request)`: Tạo group mới
- `addMembersToGroup(request)`: Thêm members vào group
- `removeMemberFromGroup(request)`: Remove member khỏi group
- `changeGroupName(request)`: Đổi tên group
- `getGroupMembers(request)`: Lấy danh sách members của group
- `leaveGroup(request)`: Rời nhóm
- `disperseGroup(request)`: Giải tán nhóm (chỉ owner)
- `joinGroup(request)`: Tham gia nhóm qua link
#### Example
```typescript
// Lấy tất cả groups
const allGroups = await client.groups.getAllGroups({ sessionId });
// Tạo group mới
const newGroup = await client.groups.createGroup({
sessionId,
groupName: 'Test Group',
memberIds: ['friend-id-1', 'friend-id-2'],
});
// Thêm members
await client.groups.addMembersToGroup({
sessionId,
groupId: newGroup.result.groupId,
memberIds: ['friend-id-3'],
});
```
### FriendService
#### Methods
- `getAllFriends(request)`: Lấy tất cả friends
- `searchFriends(request)`: Tìm kiếm friends theo keyword
- `getFriendsInfo(request)`: Lấy thông tin chi tiết friends
- `getOnlineFriends(request)`: Lấy friends đang online
- `getFriendsStats(request)`: Lấy thống kê friends
- `sendFriendRequest(request)`: Gửi lời mời kết bạn
- `acceptFriendRequest(request)`: Chấp nhận lời mời kết bạn
- `getReceivedFriendRequests(request)`: Lấy lời mời nhận được
- `getSentFriendRequests(request)`: Lấy lời mời đã gửi
- `undoFriendRequest(request)`: Hủy lời mời đã gửi
- `removeFriend(request)`: Xóa bạn bè
- `findUser(request)`: Tìm user theo số điện thoại
- `blockUser(request)`: Chặn user
- `unblockUser(request)`: Bỏ chặn user
- `changeFriendAlias(request)`: Thay đổi biệt danh
- `removeFriendAlias(request)`: Xóa biệt danh
- `getAliasList(request)`: Lấy danh sách biệt danh
- `getLastOnline(request)`: Lấy thông tin last online
- `getOwnId(request)`: Lấy ID của chính mình
- `fetchAccountInfo(request)`: Lấy thông tin tài khoản
#### Example
```typescript
// Lấy tất cả friends
const friends = await client.friends.getAllFriends({ sessionId });
// Gửi lời mời kết bạn
await client.friends.sendFriendRequest({
sessionId,
userId: 'target-user-id',
message: 'Xin chào! Kết bạn nhé!',
});
// Lấy thống kê friends
const stats = await client.friends.getFriendsStats({ sessionId });
console.log(`Total friends: ${stats.result.totalFriends}`);
```
### ConversationService
#### Methods
- `getConversations(request)`: Lấy danh sách conversations
- `getMessageHistory(request)`: Lấy lịch sử tin nhắn
- `pinConversation(request)`: Pin/Unpin conversation
- `hideConversation(request)`: Hide/Unhide conversation
- `deleteChat(request)`: Xóa chat
#### Example
```typescript
// Lấy tất cả conversations
const conversations = await client.conversations.getConversations({
sessionId,
limit: 20,
type: ConversationType.ALL,
});
// Lấy lịch sử tin nhắn
const history = await client.conversations.getMessageHistory({
sessionId,
threadId: 'conversation-id',
limit: 50,
});
// Pin conversation
await client.conversations.pinConversation({
sessionId,
threadId: 'conversation-id',
type: ThreadType.USER,
isPinned: true,
});
```
### UserInfoService
#### Methods
- `getUserInfo(request)`: Lấy thông tin user (POST)
- `getSingleUserInfo(request)`: Lấy thông tin user đơn lẻ (GET)
- `getBasicUserInfo(request)`: Lấy thông tin cơ bản
- `checkUserExists(request)`: Kiểm tra user có tồn tại
- `getMultipleUsersInfo(request)`: Lấy thông tin nhiều users
#### Example
```typescript
// Lấy thông tin user
const userInfo = await client.userInfo.getUserInfo({
sessionId,
userId: 'target-user-id',
});
// Kiểm tra user có tồn tại
const exists = await client.userInfo.checkUserExists({
sessionId,
userId: 'target-user-id',
});
// Lấy thông tin nhiều users
const multipleUsers = await client.userInfo.getMultipleUsersInfo({
sessionId,
userIds: ['user1', 'user2', 'user3'],
});
```
### ProfileService
#### Methods
- `fetchAccountInfo(request)`: Lấy thông tin tài khoản
- `changeAccountAvatar(request)`: Thay đổi avatar tài khoản
- `deleteAvatar(request)`: Xóa avatar
- `reuseAvatar(request)`: Sử dụng lại avatar
- `getAvatarList(request)`: Lấy danh sách avatar
- `updateProfile(request)`: Cập nhật profile
#### Example
```typescript
import { Gender } from '@redai/automation-web-sdk';
// Lấy thông tin tài khoản
const accountInfo = await client.profile.fetchAccountInfo({
sessionId,
});
// Cập nhật profile
const updateResult = await client.profile.updateProfile({
sessionId,
name: 'Tên mới',
dob: '1990-01-01',
gender: Gender.Male,
});
// Thay đổi avatar
const changeAvatarResult = await client.profile.changeAccountAvatar({
sessionId,
avatarSource: {
data: 'base64-image-data',
filename: 'avatar.jpg',
metadata: {
width: 200,
height: 200,
size: 15000,
type: 'image/jpeg',
},
},
});
// Lấy danh sách avatar
const avatarList = await client.profile.getAvatarList({
sessionId,
});
// Sử dụng lại avatar cũ
const reuseResult = await client.profile.reuseAvatar({
sessionId,
avatarId: 'avatar-id',
});
```
### Typed Webhook Events
SDK cung cấp type-safe webhook events 100% tương thích với `@warriorteam/zalo-personal`:
#### Event Types
- `Message`: Tin nhắn (UserMessage | GroupMessage)
- `Typing`: Sự kiện đang gõ
- `Reaction`: Phản ứng tin nhắn
- `SeenMessage`: Tin nhắn đã xem
- `DeliveredMessage`: Tin nhắn đã gửi
- `FriendEvent`: Sự kiện bạn bè
- `GroupEvent`: Sự kiện nhóm
- `Undo`: Sự kiện thu hồi tin nhắn
#### Typed Event Handlers
```typescript
import {
AutomationWebClient,
Message,
Typing,
Reaction,
ThreadType,
FriendEventType,
GroupEventType,
Reactions,
} from 'redai-automation-web-sdk';
const client = new AutomationWebClient({
baseURL: 'http://localhost:3000',
});
// Message events với type safety
client.onTypedMessage((message: Message) => {
console.log(`Message from ${message.data.uidFrom}: ${message.data.content}`);
console.log(`Thread type: ${message.type === ThreadType.USER ? 'User' : 'Group'}`);
console.log(`Is self: ${message.isSelf}`);
});
// Typing events
client.onTypedTyping((typing: Typing) => {
console.log(`${typing.data.uid} is typing in ${typing.threadId}`);
});
// Reaction events với emoji decoding
client.onTypedReaction((reaction: Reaction) => {
const reactionName = Object.entries(Reactions)
.find(([_, value]) => value === reaction.data.content.rIcon)?.[0];
console.log(`Reaction: ${reactionName} from ${reaction.data.uidFrom}`);
});
// Friend events với type discrimination
client.onTypedFriendEvent((friendEvent: FriendEvent) => {
switch (friendEvent.type) {
case FriendEventType.REQUEST:
console.log('Friend request received');
break;
case FriendEventType.ADD:
console.log('Friend added');
break;
// ... other cases
}
});
// Group events với detailed data
client.onTypedGroupEvent((groupEvent: GroupEvent) => {
switch (groupEvent.type) {
case GroupEventType.JOIN:
console.log('Member joined group');
break;
case GroupEventType.LEAVE:
console.log('Member left group');
break;
// ... other cases
}
});
```
#### Enums & Constants
```typescript
// Thread types
ThreadType.USER = 0
ThreadType.GROUP = 1
// Friend event types
FriendEventType.ADD = 0
FriendEventType.REMOVE = 1
FriendEventType.REQUEST = 2
// ... và nhiều hơn
// Group event types
GroupEventType.JOIN = 1
GroupEventType.LEAVE = 2
GroupEventType.REMOVE_MEMBER = 3
// ... và nhiều hơn
// Reaction emojis
Reactions.HEART = "/-heart"
Reactions.LIKE = "/-strong"
Reactions.HAHA = ":>"
// ... và nhiều hơn
```
### Queue Job Types
SDK cung cấp cấu trúc job chuẩn 100% tương thích với automation-web queue system:
#### Job Structure
```typescript
import {
ZaloWebhookEvent,
ZaloWebhookEventType,
WebhookQueueJob,
MessageQueueJob,
JobPriority,
JobStatus,
} from 'redai-automation-web-sdk';
// Base webhook event structure
interface BaseZaloWebhookEvent {
sessionId: string;
userUuid: string;
timestamp: number;
eventType: ZaloWebhookEventType;
metadata?: Record<string, any>;
}
// Queue job structure
interface BaseQueueJob<T = any> {
id?: string;
name: string;
data: T;
opts?: {
priority?: JobPriority;
delay?: number;
attempts?: number;
backoff?: {
type: 'fixed' | 'exponential';
delay: number;
};
removeOnComplete?: number | boolean;
removeOnFail?: number | boolean;
};
}
```
#### Event Types (100+ events)
```typescript
// Message events (44 events)
ZaloWebhookEventType.TEXT_MESSAGE_SENT_TO_USER
ZaloWebhookEventType.TEXT_MESSAGE_RECEIVED_FROM_GROUP
ZaloWebhookEventType.IMAGE_MESSAGE_SENT_TO_USER
// ... và nhiều hơn
// Friend events (13 events)
ZaloWebhookEventType.FRIEND_EVENT_ADD
ZaloWebhookEventType.FRIEND_EVENT_REQUEST
ZaloWebhookEventType.FRIEND_EVENT_BLOCK
// ... và nhiều hơn
// Group events (23 events)
ZaloWebhookEventType.GROUP_EVENT_JOIN
ZaloWebhookEventType.GROUP_EVENT_LEAVE
ZaloWebhookEventType.GROUP_EVENT_ADD_ADMIN
// ... và nhiều hơn
// System events (17 events)
ZaloWebhookEventType.CONNECTION_STATUS_CONNECTED
ZaloWebhookEventType.ERROR_SYSTEM
ZaloWebhookEventType.UPLOAD_ATTACHMENT_COMPLETED
// ... và nhiều hơn
```
#### Usage Example
```typescript
import {
Message,
ZaloTextMessageEvent,
MessageQueueJob,
JobPriority,
isMessageEvent,
getEventCategory,
} from 'redai-automation-web-sdk';
// Tạo message event job
function createMessageJob(message: Message): MessageQueueJob {
const messageEvent: ZaloTextMessageEvent = {
sessionId: 'session123',
userUuid: 'user-uuid-123',
timestamp: Date.now(),
eventType: ZaloWebhookEventType.TEXT_MESSAGE_RECEIVED_FROM_USER,
data: message, // Sử dụng trực tiếp Message từ SDK
};
return {
name: 'message-event',
data: messageEvent,
opts: {
priority: JobPriority.NORMAL,
attempts: 3,
backoff: {
type: 'exponential',
delay: 2000,
},
},
};
}
// Xử lý job với type guards
function processJob(job: WebhookQueueJob): void {
const event = job.data;
if (isMessageEvent(event)) {
const message = event.data; // Trực tiếp Message từ SDK
console.log(`Message: ${message.data.content}`);
console.log(`Thread: ${message.threadId}`);
console.log(`Is Self: ${message.isSelf}`);
}
console.log(`Category: ${getEventCategory(event.eventType)}`);
}
```
#### Helper Functions
```typescript
// Type guards
isMessageEvent(event) // Check if message event
isTypingEvent(event) // Check if typing event
isFriendEvent(event) // Check if friend event
isGroupEvent(event) // Check if group event
isSystemEvent(event) // Check if system event
// Event analysis
getEventCategory(eventType) // Get event category
getThreadTypeFromEvent(eventType) // Get thread type (user/group)
getActorTypeFromEvent(eventType) // Get actor type (self/other)
```
## 🤝 Contributing
1. Fork repository
2. Tạo feature branch: `git checkout -b feature/amazing-feature`
3. Commit changes: `git commit -m 'Add amazing feature'`
4. Push to branch: `git push origin feature/amazing-feature`
5. Tạo Pull Request
## 📄 License
MIT License - xem [LICENSE](LICENSE) file.
## 🆘 Support
- GitHub Issues: [https://github.com/redai/automation-web-sdk/issues](https://github.com/redai/automation-web-sdk/issues)
- Documentation: [https://docs.redai.com/automation-web-sdk](https://docs.redai.com/automation-web-sdk)
- Discord: [https://discord.gg/redai](https://discord.gg/redai)
## 🗺️ Roadmap
- [x] Authentication & Session Management
- [x] Basic Messaging
- [x] Webhook Events
- [x] Group Management
- [x] Friend Management
- [x] Bulk Operations
- [x] Conversation Management
- [x] User Info Management
- [x] Typed Webhook Events (100% tương thích với zalo-personal-sdk)
- [x] Queue Job Types (100% tương thích với automation-web queue system)
- [ ] File Upload Support
- [ ] Rate Limiting
- [ ] Retry Mechanisms
- [ ] Browser Support
- [ ] React Native Support
---
Made with ❤️ by RedAI Team