UNPKG

@warriorteam/zalo-personal

Version:

Unofficial Zalo Personal API for JavaScript - A powerful library for interacting with Zalo personal accounts with URL attachment support

543 lines (407 loc) 12.3 kB
# Hướng Dẫn Sử Dụng Zalo Personal SDK ## Tổng quan Zalo Personal SDK là một thư viện JavaScript/TypeScript mạnh mẽ cho phép tương tác với Zalo thông qua các API không chính thức. SDK hỗ trợ đầy đủ các chức năng như gửi tin nhắn, quản lý bạn bè, quản lý nhóm, và nhiều tính năng khác. ## Cài Đặt ```bash npm install zalo-personal-sdk ``` ## Khởi Tạo và Đăng Nhập ### 1. Đăng nhập bằng Cookie ```typescript import { Zalo } from 'zalo-personal-sdk'; const zalo = new Zalo(); // Thông tin đăng nhập const credentials = { imei: 'your-device-imei', cookie: [ // Cookie array từ browser ], userAgent: 'Mozilla/5.0...', language: 'vi' // Optional }; const api = await zalo.login(credentials); ``` ### 2. Đăng nhập bằng QR Code ```typescript const api = await zalo.loginQR({ userAgent: 'Mozilla/5.0...', language: 'vi', qrPath: './qr-code.png' // Optional: đường dẫn lưu QR code }, (event) => { switch (event.type) { case LoginQRCallbackEventType.QrCodeGenerated: console.log('QR Code được tạo:', event.data.qrCodePath); break; case LoginQRCallbackEventType.LoggedIn: console.log('Đăng nhập thành công!'); break; case LoginQRCallbackEventType.GotLoginInfo: console.log('Thông tin đăng nhập:', event.data); break; } }); ``` ## Gửi Tin Nhắn ### 1. Gửi Tin Nhắn Văn Bản Đơn Giản ```typescript import { ThreadType } from 'zalo-personal-sdk'; // Gửi tin nhắn cho người dùng await api.sendMessage('Xin chào!', 'user-id', ThreadType.User); // Gửi tin nhắn cho nhóm await api.sendMessage('Hello group!', 'group-id', ThreadType.Group); ``` ### 2. Gửi Tin Nhắn Với Định Dạng Văn Bản ```typescript import { TextStyle, Urgency } from 'zalo-personal-sdk'; const messageContent = { msg: 'Tin nhắn có định dạng', styles: [ { start: 0, len: 3, st: TextStyle.Bold }, // In đậm { start: 4, len: 4, st: TextStyle.Italic }, // In nghiêng { start: 9, len: 2, st: TextStyle.Red } // Màu đỏ ], urgency: Urgency.Important }; await api.sendMessage(messageContent, 'user-id', ThreadType.User); ``` ### 3. Gửi Tin Nhắn Có Mention (trong nhóm) ```typescript const messageContent = { msg: '@user1 @user2 Chào các bạn!', mentions: [ { pos: 0, len: 6, uid: 'user1-id' }, { pos: 7, len: 6, uid: 'user2-id' } ] }; await api.sendMessage(messageContent, 'group-id', ThreadType.Group); ``` ### 4. Gửi Tin Nhắn Trả Lời (Quote) ```typescript // Lấy tin nhắn để trả lời từ listener hoặc API khác const originalMessage = { content: 'Nội dung tin nhắn gốc', msgType: 'webchat', uidFrom: 'sender-id', msgId: 123456, cliMsgId: 'client-msg-id', ts: Date.now(), ttl: 0, propertyExt: {} }; const replyContent = { msg: 'Đây là câu trả lời', quote: originalMessage }; await api.sendMessage(replyContent, 'user-id', ThreadType.User); ``` ### 5. Gửi Tin Nhắn Với File Đính Kèm #### Gửi từ đường dẫn file local: ```typescript const messageContent = { msg: 'Ảnh đẹp không?', attachments: '/path/to/image.jpg' }; await api.sendMessage(messageContent, 'user-id', ThreadType.User); ``` #### Gửi từ URL: ```typescript const messageContent = { msg: 'Hình ảnh từ internet', attachments: { url: 'https://example.com/image.jpg', filename: 'downloaded-image.jpg', headers: { 'User-Agent': 'MyBot' } // Optional } }; await api.sendMessage(messageContent, 'user-id', ThreadType.User); ``` #### Gửi từ Buffer: ```typescript const fileBuffer = fs.readFileSync('./image.jpg'); const messageContent = { msg: 'Hình từ buffer', attachments: { data: fileBuffer, filename: 'buffer-image.jpg', metadata: { totalSize: fileBuffer.length, width: 1920, height: 1080 } } }; await api.sendMessage(messageContent, 'user-id', ThreadType.User); ``` #### Gửi nhiều file: ```typescript const messageContent = { msg: 'Gửi nhiều hình', attachments: [ '/path/to/image1.jpg', '/path/to/image2.png', { url: 'https://example.com/image3.gif', filename: 'animated.gif' } ] }; await api.sendMessage(messageContent, 'user-id', ThreadType.User); ``` ### 6. Gửi Tin Nhắn Tự Hủy (TTL) ```typescript const messageContent = { msg: 'Tin nhắn này sẽ tự hủy sau 60 giây', ttl: 60000 // TTL tính bằng milliseconds }; await api.sendMessage(messageContent, 'user-id', ThreadType.User); ``` ### 7. Các Loại Tin Nhắn Đặc Biệt #### Gửi Sticker: ```typescript await api.sendSticker('sticker-id', 'user-id', ThreadType.User, 'sticker-category-id'); ``` #### Gửi Link: ```typescript const linkOptions = { url: 'https://example.com', title: 'Tiêu đề link', description: 'Mô tả link', thumbnail: 'https://example.com/thumb.jpg' }; await api.sendLink(linkOptions, 'user-id', ThreadType.User); ``` #### Gửi Card/Danh thiếp: ```typescript const cardOptions = { userId: 'target-user-id' }; await api.sendCard(cardOptions, 'recipient-id', ThreadType.User); ``` #### Gửi Video: ```typescript const videoOptions = { filePath: '/path/to/video.mp4', duration: 30, // seconds width: 1920, height: 1080 }; await api.sendVideo(videoOptions, 'user-id', ThreadType.User); ``` #### Gửi Voice: ```typescript const voiceOptions = { filePath: '/path/to/audio.m4a', duration: 15 // seconds }; await api.sendVoice(voiceOptions, 'user-id', ThreadType.User); ``` ## Quản Lý Bạn Bè ### Lấy danh sách bạn bè ```typescript const friends = await api.getAllFriends(); console.log(friends); ``` ### Tìm kiếm người dùng ```typescript const users = await api.findUser('tên người dùng'); console.log(users); ``` ### Gửi lời mời kết bạn ```typescript await api.sendFriendRequest('user-id', 'Lời nhắn kèm theo'); ``` ### Chấp nhận lời mời kết bạn ```typescript await api.acceptFriendRequest('user-id'); ``` ### Hủy lời mời kết bạn ```typescript await api.undoFriendRequest('user-id'); ``` ### Xóa bạn bè ```typescript await api.removeFriend('user-id'); ``` ### Chặn/bỏ chặn người dùng ```typescript // Chặn await api.blockUser('user-id'); // Bỏ chặn await api.unblockUser('user-id'); ``` ## Quản Lý Nhóm ### Lấy danh sách nhóm ```typescript const groups = await api.getAllGroups(); console.log(groups); ``` ### Tạo nhóm mới ```typescript const groupOptions = { name: 'Tên nhóm', members: ['user-id-1', 'user-id-2'] }; const newGroup = await api.createGroup(groupOptions); ``` ### Thêm thành viên vào nhóm ```typescript await api.addUserToGroup('group-id', ['user-id-1', 'user-id-2']); ``` ### Xóa thành viên khỏi nhóm ```typescript await api.removeUserFromGroup('group-id', 'user-id'); ``` ### Rời nhóm ```typescript await api.leaveGroup('group-id'); ``` ### Thay đổi tên nhóm ```typescript await api.changeGroupName('group-id', 'Tên mới'); ``` ### Thay đổi avatar nhóm ```typescript await api.changeGroupAvatar('group-id', '/path/to/avatar.jpg'); ``` ### Chuyển quyền quản trị nhóm ```typescript await api.changeGroupOwner('group-id', 'new-owner-id'); ``` ## Lắng Nghe Sự Kiện (Listener) ### Khởi tạo listener ```typescript // Bắt đầu lắng nghe await api.listener.start(); // Xử lý tin nhắn mới api.listener.on('message', (message) => { console.log('Tin nhắn mới:', message); // Trả lời tự động if (message.data.content === 'hello') { api.sendMessage('Xin chào!', message.threadId, message.threadType); } }); // Xử lý sự kiện nhóm api.listener.on('group_event', (event) => { console.log('Sự kiện nhóm:', event); }); // Xử lý sự kiện bạn bè api.listener.on('friend_event', (event) => { console.log('Sự kiện bạn bè:', event); }); // Dừng lắng nghe await api.listener.stop(); ``` ### Xử lý các loại sự kiện ```typescript api.listener.on('message', (message) => { switch (message.type) { case 'text': console.log('Tin nhắn văn bản:', message.data.content); break; case 'image': console.log('Hình ảnh:', message.data.href); break; case 'video': console.log('Video:', message.data.href); break; case 'file': console.log('File:', message.data.fileName); break; } }); ``` ## Tính Năng Nâng Cao ### Upload file đính kèm ```typescript const uploadResult = await api.uploadAttachment(['/path/to/file.jpg'], 'thread-id', ThreadType.User); console.log(uploadResult); ``` ### Xem trước link ```typescript const linkPreview = await api.parseLink('https://example.com'); console.log(linkPreview); ``` ### Tạo poll/bình chọn ```typescript const pollOptions = { question: 'Bạn thích màu gì?', options: ['Đỏ', 'Xanh', 'Vàng'], multipleChoice: false }; await api.createPoll(pollOptions, 'group-id'); ``` ### Tạo reminder ```typescript const reminderOptions = { content: 'Nhắc nhở họp', time: new Date('2024-12-31T15:00:00'), members: ['user-id-1', 'user-id-2'] }; await api.createReminder(reminderOptions, 'group-id'); ``` ### Reaction tin nhắn ```typescript await api.addReaction('😍', { messageId: 'message-id', threadId: 'thread-id', threadType: ThreadType.User }); ``` ## Xử Lý Lỗi ```typescript import { ZaloApiError } from 'zalo-personal-sdk'; try { await api.sendMessage('Hello', 'user-id', ThreadType.User); } catch (error) { if (error instanceof ZaloApiError) { console.error('Lỗi Zalo API:', error.message); } else { console.error('Lỗi khác:', error); } } ``` ## Cấu Hình Nâng Cao ### Tùy chỉnh options ```typescript const zalo = new Zalo({ selfListen: true, // Lắng nghe tin nhắn của chính mình logLevel: 'info', // Mức độ log apiVersion: 'v1' // Phiên bản API }); ``` ### Custom API call ```typescript const customResult = await api.custom({ url: '/custom/endpoint', method: 'POST', params: { custom: 'data' } }); ``` ## Lưu Ý Quan Trọng 1. **Rate Limiting**: Không gửi quá nhiều tin nhắn trong thời gian ngắn để tránh bị Zalo chặn 2. **File Size**: Kiểm tra kích thước file trước khi gửi (max ~25MB) 3. **Cookie Expiry**: Cookie có thể hết hạn, cần xử lý việc đăng nhập lại 4. **Error Handling**: Luôn wrap API calls trong try-catch 5. **Thread Safety**: SDK không thread-safe, tránh gọi API đồng thời ## Ví Dụ Bot Đơn Giản ```typescript import { Zalo, ThreadType } from 'zalo-personal-sdk'; const zalo = new Zalo(); const api = await zalo.login(credentials); await api.listener.start(); api.listener.on('message', async (message) => { const { threadId, threadType, data } = message; if (data.content) { const text = data.content.toLowerCase(); if (text === '/help') { await api.sendMessage('Các lệnh có sẵn:\n/time - Xem giờ\n/weather - Xem thời tiết', threadId, threadType); } else if (text === '/time') { await api.sendMessage(`Bây giờ : ${new Date().toLocaleString()}`, threadId, threadType); } else if (text.startsWith('/weather')) { await api.sendMessage('Chức năng thời tiết đang phát triển...', threadId, threadType); } } }); console.log('Bot đang chạy...'); ``` Đây là hướng dẫn cơ bản để sử dụng Zalo Personal SDK. Tham khao thêm các file example trong thư mục `examples/` để hiểu rõ hơn cách sử dụng.