@warriorteam/redai-zalo-sdk
Version:
Comprehensive TypeScript/JavaScript SDK for Zalo APIs - Official Account v3.0, ZNS with Full Type Safety, Consultation Service, Broadcast Service, Group Messaging with List APIs, Social APIs, Enhanced Article Management, Promotion Service v3.0 with Multip
482 lines (384 loc) • 13.2 kB
Markdown
# 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)