UNPKG

@warriorteam/redai-zalo-sdk

Version:

Comprehensive TypeScript/JavaScript SDK for Zalo APIs - Official Account, ZNS, Consultation Service, Group Messaging, and Social APIs

482 lines (384 loc) 13.7 kB
# User Management - Hướng Dẫn Sử Dụng ## Tổng Quan `UserService` cung cấp các công cụ toàn diện để quản lý người dùng Zalo Official Account, bao gồm: - 👥 **User Information** - Lấy thông tin chi tiết người dùng - 📋 **User Lists** - Quản lý danh sách người dùng với phân trang - 🏷️ **Tag Management** - Gắn và quản lý tags cho users - 📊 **Custom Info** - Quản lý thông tin tùy chỉnh - 🔄 **Bulk Operations** - Xử lý hàng loạt users **Endpoints sử dụng:** - User Info: `https://openapi.zalo.me/v3.0/oa/user/detail` - User List: `https://openapi.zalo.me/v3.0/oa/user/getlist` - Update User: `https://openapi.zalo.me/v3.0/oa/user/update` - Custom Info: `https://openapi.zalo.me/v3.0/oa/user/getcustominfo` - Tags: `https://openapi.zalo.me/v3.0/oa/tag/gettagsofoa` ## Khởi Tạo Service ```typescript import { UserService } from "@warriorteam/redai-zalo-sdk"; import { ZaloClient } from "@warriorteam/redai-zalo-sdk"; const client = new ZaloClient(); const userService = new UserService(client); ``` ## Các Phương Thức Chính ### 1. Lấy Thông Tin User Chi Tiết ```typescript // Lấy thông tin chi tiết của một user const userInfo = await userService.getUserInfo( accessToken, "user-id-here" ); console.log("User Info:", { userId: userInfo.user_id, displayName: userInfo.display_name, avatar: userInfo.avatar, userGender: userInfo.user_gender, userAlias: userInfo.user_alias, isFollower: userInfo.is_follower, sharedInfo: userInfo.shared_info }); ``` **Tham số:** - `accessToken`: Access token của OA - `userId`: ID người dùng cần lấy thông tin ### 2. Lấy Danh Sách Users ```typescript // Lấy danh sách users với filter const userList = await userService.getUserList(accessToken, { offset: 0, count: 50, tag_name: "VIP_CUSTOMER", // Lọc theo tag (tùy chọn) is_follower: true, // Chỉ lấy followers (tùy chọn) last_interaction_period: "L7D" // Tương tác trong 7 ngày qua }); console.log("Total users:", userList.total); console.log("Count:", userList.count); console.log("Offset:", userList.offset); userList.users.forEach(user => { console.log(`${user.display_name} - ${user.user_id}`); }); ``` **Tham số:** - `offset`: Vị trí bắt đầu (0-based) - `count`: Số lượng users mỗi page (tối đa 50) - `tag_name`: Lọc theo tag (tùy chọn) - `is_follower`: true/false để lọc followers - `last_interaction_period`: "TODAY", "YESTERDAY", "L7D", "L30D" ### 3. Lấy Tất Cả Users (Auto Pagination) ```typescript // Lấy tất cả users với phân trang tự động const allUsers = await userService.getAllUsers(accessToken, { is_follower: true, tag_name: "PREMIUM" }); console.log(`Total users fetched: ${allUsers.length}`); ``` **Lưu ý:** - Zalo giới hạn max offset = 9951 (tương ứng ~10000 users) - Method này tự động handle pagination và warning khi vượt giới hạn ### 4. Lấy Danh Sách User IDs (Tối Ưu) ```typescript // Chỉ lấy user IDs, không lấy thông tin chi tiết (nhanh hơn) const userIds = await userService.getAllUserIds(accessToken, { is_follower: true }); console.log(`Total user IDs: ${userIds.length}`); ``` ### 5. Helper Methods ```typescript // Lấy chỉ followers const followers = await userService.getFollowers(accessToken, 0, 50); // Lấy users theo tag const vipUsers = await userService.getUsersByTag(accessToken, "VIP", 0, 50); // Lấy users theo thời gian tương tác const recentUsers = await userService.getUsersByInteraction( accessToken, "L7D", // 7 ngày qua 0, 50 ); ``` ## User Management Operations ### 6. Cập Nhật Thông Tin User ```typescript // Cập nhật thông tin user const success = await userService.updateUser(accessToken, { user_id: "user-id-here", notes: "Customer quan tâm sản phẩm cao cấp", // Các field khác có thể cập nhật }); console.log("Update success:", success); ``` ### 7. Xóa Thông Tin User ```typescript // Xóa thông tin user khỏi OA (không ảnh hưởng tài khoản Zalo) const success = await userService.deleteUserInfo(accessToken, "user-id-here"); console.log("Delete success:", success); ``` ### 8. Quản Lý Custom Info ```typescript // Lấy custom info của user const customInfo = await userService.getUserCustomInfo(accessToken, { user_id: "user-id-here", fields_to_export: ["customer_tier", "total_spent"] // Tùy chọn }); console.log("Custom Info:", customInfo.custom_info); // Cập nhật custom info const updateSuccess = await userService.updateUserCustomInfo(accessToken, { user_id: "user-id-here", custom_info: { customer_tier: "VIP", total_spent: "10000000", last_purchase: "2024-12-01" } }); ``` **Lưu ý:** Cấu trúc `custom_info` phụ thuộc vào thiết lập OA ## Tag Management ### 9. Quản Lý Tags ```typescript // Lấy danh sách tất cả tags của OA const tags = await userService.getLabels(accessToken); console.log("Available tags:", tags); // Thêm tag cho user const addSuccess = await userService.addTagToUser(accessToken, { user_id: "user-id-here", tag_name: "VIP_CUSTOMER" }); // Xóa tag khỏi user const removeSuccess = await userService.removeTagFromUser(accessToken, { user_id: "user-id-here", tag_name: "OLD_TAG" }); // Xóa tag khỏi OA (xóa hoàn toàn) const deleteSuccess = await userService.deleteLabel(accessToken, "UNUSED_TAG"); ``` ### 10. Bulk Operations ```typescript // Bulk add tag cho nhiều users const bulkAddResult = await userService.bulkAddTag( accessToken, ["user1", "user2", "user3"], "FLASH_SALE_2024" ); console.log("Success:", bulkAddResult.success); console.log("Failed:", bulkAddResult.failed); // Bulk remove tag const bulkRemoveResult = await userService.bulkRemoveTag( accessToken, ["user1", "user2", "user3"], "OLD_CAMPAIGN" ); ``` ## API Methods Summary | Method | Description | Parameters | |--------|-------------|------------| | `getUserInfo` | Lấy thông tin chi tiết user | `accessToken`, `userId` | | `getUserList` | Lấy danh sách users với pagination | `accessToken`, `request` | | `getAllUsers` | Lấy tất cả users (auto pagination) | `accessToken`, `filters?` | | `getAllUserIds` | Lấy tất cả user IDs (tối ưu) | `accessToken`, `filters?` | | `updateUser` | Cập nhật thông tin user | `accessToken`, `request` | | `deleteUserInfo` | Xóa thông tin user | `accessToken`, `userId` | | `getUserCustomInfo` | Lấy custom info | `accessToken`, `request` | | `updateUserCustomInfo` | Cập nhật custom info | `accessToken`, `request` | | `getLabels` | Lấy danh sách tags | `accessToken` | | `addTagToUser` | Thêm tag cho user | `accessToken`, `request` | | `removeTagFromUser` | Xóa tag khỏi user | `accessToken`, `request` | | `deleteLabel` | Xóa tag khỏi OA | `accessToken`, `tagName` | | `getUsersByTag` | Lấy users theo tag | `accessToken`, `tagName`, `offset?`, `count?` | | `getFollowers` | Lấy chỉ followers | `accessToken`, `offset?`, `count?` | | `getUsersByInteraction` | Lấy users theo thời gian tương tác | `accessToken`, `period`, `offset?`, `count?` | | `bulkAddTag` | Bulk add tag | `accessToken`, `userIds`, `tagName` | | `bulkRemoveTag` | Bulk remove tag | `accessToken`, `userIds`, `tagName` | ## Ví Dụ Thực Tế ### 1. Customer Support System ```typescript class CustomerSupportSystem { constructor(private userService: UserService, private accessToken: string) {} async handleNewCustomer(userId: string) { // Lấy thông tin customer const userInfo = await this.userService.getUserInfo(this.accessToken, userId); // Thêm tag "NEW_CUSTOMER" await this.userService.addTagToUser(this.accessToken, { user_id: userId, tag_name: "NEW_CUSTOMER" }); // Cập nhật custom info await this.userService.updateUserCustomInfo(this.accessToken, { user_id: userId, custom_info: { registration_date: new Date().toISOString(), customer_tier: "STANDARD", total_interactions: "1" } }); console.log(`New customer ${userInfo.display_name} processed`); } async promoteToVIP(userId: string) { // Remove old tags await this.userService.removeTagFromUser(this.accessToken, { user_id: userId, tag_name: "STANDARD" }); // Add VIP tag await this.userService.addTagToUser(this.accessToken, { user_id: userId, tag_name: "VIP" }); // Update custom info await this.userService.updateUserCustomInfo(this.accessToken, { user_id: userId, custom_info: { customer_tier: "VIP", promotion_date: new Date().toISOString() } }); } } } ``` ### 2. Bulk Campaign System ```typescript class BulkCampaignSystem { constructor(private userService: UserService, private accessToken: string) {} async runSegmentedCampaign(campaignConfig: { segments: string[]; message: string; batchSize?: number; }) { const results = { totalSent: 0, totalFailed: 0, segmentResults: new Map<string, any>() }; for (const segment of campaignConfig.segments) { console.log(`Processing segment: ${segment}`); // Get users by tag const users = await this.userService.getUsersByTag( this.accessToken, segment, 0, 1000 ); // Bulk add campaign tag const userIds = users.users.map(u => u.user_id); const bulkResult = await this.userService.bulkAddTag( this.accessToken, userIds, `CAMPAIGN_${Date.now()}` ); results.segmentResults.set(segment, { totalUsers: users.total, tagged: bulkResult.success.length, failed: bulkResult.failed.length }); results.totalSent += bulkResult.success.length; results.totalFailed += bulkResult.failed.length; } return results; } } ``` ## Error Handling ```typescript import { ZaloSDKError } from "@warriorteam/redai-zalo-sdk"; try { const userInfo = await userService.getUserInfo(accessToken, "user-id"); console.log("User found:", userInfo.display_name); } catch (error) { if (error instanceof ZaloSDKError) { switch (error.code) { case -216: console.error("Access token không hợp lệ"); break; case -233: console.error("User không tồn tại hoặc đã unfollow"); break; case -201: console.error("Tham số không hợp lệ"); break; default: console.error("Lỗi khác:", error.message); } } else { console.error("Unexpected error:", error); } } ``` ## Giới Hạn API ### Zalo API Limits 1. **User List Pagination**: - Max offset: 9951 - Max count per request: 50 - Tối đa ~10000 users có thể lấy được 2. **Rate Limiting**: - Nên có delay giữa các requests - Sử dụng batch operations khi có thể 3. **Custom Info**: - Cấu trúc phụ thuộc vào thiết lập OA - Tất cả giá trị đều là string ## Best Practices ### 1. Performance Optimization ```typescript // ✅ Sử dụng getAllUserIds cho performance tốt hơn const userIds = await userService.getAllUserIds(accessToken); // ✅ Batch operations const bulkResult = await userService.bulkAddTag( accessToken, userIds.slice(0, 100), "NEW_TAG" ); // ✅ Pagination với reasonable page size const users = await userService.getUserList(accessToken, { offset: 0, count: 50 // Không quá 50 }); ``` ### 2. Error Handling ```typescript // ✅ Validate user ID format function validateUserId(userId: string): boolean { return /^[0-9]+$/.test(userId) && userId.length > 0; } // ✅ Safe operations async function safeGetUser(userId: string) { if (!validateUserId(userId)) { throw new Error("Invalid user ID format"); } try { return await userService.getUserInfo(accessToken, userId); } catch (error) { if (error.code === -233) { return null; // User not found } throw error; } } ``` ## Troubleshooting ### Common Issues **Q: "User not found" error** ``` A: User có thể đã unfollow OA hoặc chặn OA. Kiểm tra is_follower field trước. ``` **Q: Không lấy được phone number** ``` A: Phone chỉ có khi user đã share với OA. Sử dụng request_user_info để yêu cầu. ``` **Q: getAllUsers không lấy hết** ``` A: Zalo giới hạn max offset = 9951. Chỉ lấy được ~10000 users đầu tiên. ``` **Q: Custom info không cập nhật** ``` A: Kiểm tra cấu trúc custom_info trong OA settings. Tất cả values phải là string. ``` ## Tài Liệu Liên Quan - [Zalo Official Account API](https://developers.zalo.me/docs/api/official-account-api) - [User Management API](https://developers.zalo.me/docs/api/official-account-api/quan-ly-nguoi-dung) - [Tag Management API](https://developers.zalo.me/docs/api/official-account-api/quan-ly-nhan) - [Consultation Service](./CONSULTATION_SERVICE.md) - [Tag Management](./TAG_MANAGEMENT.md)