@warriorteam/redai-zalo-sdk
Version:
Comprehensive TypeScript/JavaScript SDK for Zalo APIs - Official Account, ZNS, Consultation Service, Group Messaging, and Social APIs
391 lines (330 loc) • 11.7 kB
text/typescript
/**
* Ví dụ sử dụng ConsultationService - Dịch vụ tin nhắn tư vấn
*
* Ví dụ này minh họa cách sử dụng ConsultationService để:
* - Gửi tin nhắn tư vấn văn bản
* - Gửi hình ảnh hỗ trợ
* - Gửi file hướng dẫn
* - Xử lý lỗi và retry
* - Tích hợp với webhook
*/
import { ZaloSDK, ZaloSDKError, SendMessageResponse } from "../src/index";
// Cấu hình SDK
const zalo = new ZaloSDK({
appId: "your-app-id",
appSecret: "your-app-secret",
debug: true
});
// Access token của OA (lấy từ quá trình authentication)
const ACCESS_TOKEN = "your-oa-access-token";
/**
* Ví dụ 1: Gửi tin nhắn tư vấn cơ bản
*/
async function basicConsultationExample() {
console.log("=== Ví dụ 1: Tin nhắn tư vấn cơ bản ===");
try {
// Gửi tin nhắn văn bản tư vấn
const response = await zalo.consultation.sendTextMessage(
ACCESS_TOKEN,
{ user_id: "user-id-here" },
{
type: "text",
text: "Xin chào! Cảm ơn bạn đã liên hệ với chúng tôi. Tôi có thể hỗ trợ gì cho bạn hôm nay?"
}
);
console.log("✅ Gửi tin nhắn thành công!");
console.log("Message ID:", response.message_id);
console.log("User ID:", response.user_id);
if (response.quota) {
console.log("Quota còn lại:", response.quota.remain);
}
} catch (error) {
if (error instanceof ZaloSDKError) {
console.error("❌ Lỗi Zalo API:", error.message);
console.error("Mã lỗi:", error.code);
} else {
console.error("❌ Lỗi không xác định:", error);
}
}
}
/**
* Ví dụ 2: Gửi hình ảnh hỗ trợ
*/
async function imageConsultationExample() {
console.log("\n=== Ví dụ 2: Gửi hình ảnh hỗ trợ ===");
try {
const response = await zalo.consultation.sendImageMessage(
ACCESS_TOKEN,
{ user_id: "user-id-here" },
{
type: "image",
attachment: {
type: "image",
payload: {
url: "https://example.com/support-guide.jpg"
}
}
}
);
console.log("✅ Gửi hình ảnh hỗ trợ thành công!");
console.log("Message ID:", response.message_id);
} catch (error) {
console.error("❌ Lỗi gửi hình ảnh:", error);
}
}
/**
* Ví dụ 3: Gửi file hướng dẫn
*/
async function fileConsultationExample() {
console.log("\n=== Ví dụ 3: Gửi file hướng dẫn ===");
try {
const response = await zalo.consultation.sendFileMessage(
ACCESS_TOKEN,
{ user_id: "user-id-here" },
{
type: "file",
url: "https://example.com/user-manual.pdf",
filename: "Hướng dẫn sử dụng.pdf",
attachment: {
type: "file",
payload: {
url: "https://example.com/user-manual.pdf"
}
}
}
);
console.log("✅ Gửi file hướng dẫn thành công!");
console.log("Message ID:", response.message_id);
} catch (error) {
console.error("❌ Lỗi gửi file:", error);
}
}
/**
* Ví dụ 4: Hệ thống hỗ trợ khách hàng thông minh
*/
class SmartCustomerSupport {
private zalo: ZaloSDK;
private accessToken: string;
constructor(zalo: ZaloSDK, accessToken: string) {
this.zalo = zalo;
this.accessToken = accessToken;
}
/**
* Xử lý câu hỏi của khách hàng
*/
async handleCustomerQuestion(userId: string, question: string) {
console.log(`\n📞 Xử lý câu hỏi từ user ${userId}: "${question}"`);
try {
// Phân tích câu hỏi và tạo phản hồi
const response = this.analyzeQuestion(question);
// Gửi tin nhắn phản hồi
await this.zalo.consultation.sendTextMessage(
this.accessToken,
{ user_id: userId },
{
type: "text",
text: response.text
}
);
// Gửi thêm tài liệu hỗ trợ nếu cần
if (response.needsDocument) {
await this.sendSupportDocument(userId, response.documentType);
}
console.log("✅ Đã phản hồi khách hàng thành công!");
} catch (error) {
console.error("❌ Lỗi xử lý câu hỏi khách hàng:", error);
// Gửi tin nhắn lỗi cho khách hàng
await this.sendErrorMessage(userId);
}
}
/**
* Phân tích câu hỏi và tạo phản hồi
*/
private analyzeQuestion(question: string) {
const lowerQuestion = question.toLowerCase();
if (lowerQuestion.includes("đăng nhập") || lowerQuestion.includes("login")) {
return {
text: "Để đăng nhập vào hệ thống, bạn vui lòng:\n1. Truy cập trang đăng nhập\n2. Nhập email và mật khẩu\n3. Nhấn 'Đăng nhập'\n\nNếu quên mật khẩu, bạn có thể sử dụng chức năng 'Quên mật khẩu'.",
needsDocument: true,
documentType: "login_guide"
};
}
if (lowerQuestion.includes("thanh toán") || lowerQuestion.includes("payment")) {
return {
text: "Chúng tôi hỗ trợ các phương thức thanh toán sau:\n• Thẻ tín dụng/ghi nợ\n• Ví điện tử (MoMo, ZaloPay)\n• Chuyển khoản ngân hàng\n• Thanh toán khi nhận hàng (COD)\n\nBạn cần hỗ trợ về phương thức nào?",
needsDocument: true,
documentType: "payment_guide"
};
}
if (lowerQuestion.includes("giao hàng") || lowerQuestion.includes("shipping")) {
return {
text: "Thông tin về giao hàng:\n• Nội thành: 1-2 ngày\n• Ngoại thành: 2-3 ngày\n• Tỉnh khác: 3-5 ngày\n\nPhí ship được tính theo khoảng cách và trọng lượng đơn hàng.",
needsDocument: false,
documentType: null
};
}
// Phản hồi mặc định
return {
text: "Cảm ơn bạn đã liên hệ! Tôi đã ghi nhận câu hỏi của bạn. Đội ngũ hỗ trợ sẽ phản hồi trong vòng 24 giờ.\n\nCác vấn đề phổ biến:\n• Đăng nhập\n• Thanh toán\n• Giao hàng\n• Đổi trả\n\nBạn có thể hỏi cụ thể về các vấn đề này để được hỗ trợ nhanh hơn.",
needsDocument: false,
documentType: null
};
}
/**
* Gửi tài liệu hỗ trợ
*/
private async sendSupportDocument(userId: string, documentType: string) {
const documents = {
login_guide: {
url: "https://example.com/guides/login-guide.pdf",
filename: "Hướng dẫn đăng nhập.pdf"
},
payment_guide: {
url: "https://example.com/guides/payment-guide.pdf",
filename: "Hướng dẫn thanh toán.pdf"
}
};
const doc = documents[documentType as keyof typeof documents];
if (!doc) return;
await this.zalo.consultation.sendFileMessage(
this.accessToken,
{ user_id: userId },
{
type: "file",
url: doc.url,
filename: doc.filename,
attachment: {
type: "file",
payload: {
url: doc.url
}
}
}
);
}
/**
* Gửi tin nhắn lỗi
*/
private async sendErrorMessage(userId: string) {
try {
await this.zalo.consultation.sendTextMessage(
this.accessToken,
{ user_id: userId },
{
type: "text",
text: "Xin lỗi, hiện tại hệ thống đang gặp sự cố. Vui lòng thử lại sau hoặc liên hệ hotline: 1900-xxxx để được hỗ trợ trực tiếp."
}
);
} catch (error) {
console.error("❌ Không thể gửi tin nhắn lỗi:", error);
}
}
}
/**
* Ví dụ 5: Retry mechanism
*/
async function sendWithRetry(
userId: string,
message: string,
maxRetries: number = 3
): Promise<SendMessageResponse | null> {
console.log(`\n🔄 Gửi tin nhắn với retry (tối đa ${maxRetries} lần)`);
for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
console.log(`Lần thử ${attempt}/${maxRetries}`);
const response = await zalo.consultation.sendTextMessage(
ACCESS_TOKEN,
{ user_id: userId },
{ type: "text", text: message }
);
console.log("✅ Gửi thành công!");
return response;
} catch (error) {
console.log(`❌ Lần thử ${attempt} thất bại:`, error instanceof ZaloSDKError ? error.message : error);
if (attempt === maxRetries) {
console.log("❌ Đã thử hết số lần cho phép");
return null;
}
// Đợi trước khi thử lại (exponential backoff)
const delay = Math.pow(2, attempt) * 1000;
console.log(`⏳ Đợi ${delay}ms trước khi thử lại...`);
await new Promise(resolve => setTimeout(resolve, delay));
}
}
return null;
}
/**
* Ví dụ 6: Tích hợp với webhook
*/
function setupWebhookIntegration() {
console.log("\n🔗 Thiết lập tích hợp webhook");
const customerSupport = new SmartCustomerSupport(zalo, ACCESS_TOKEN);
// Giả lập xử lý webhook event
const handleWebhookEvent = async (event: any) => {
console.log("📨 Nhận webhook event:", event.event_name);
switch (event.event_name) {
case "user_send_text":
const userId = event.sender.id;
const userMessage = event.message.text;
// Kiểm tra xem có phải câu hỏi cần hỗ trợ không
if (userMessage.includes("help") ||
userMessage.includes("hỗ trợ") ||
userMessage.includes("support")) {
await customerSupport.handleCustomerQuestion(userId, userMessage);
}
break;
case "user_send_sticker":
// Phản hồi sticker bằng tin nhắn thân thiện
await zalo.consultation.sendTextMessage(
ACCESS_TOKEN,
{ user_id: event.sender.id },
{
type: "text",
text: "Cảm ơn bạn! 😊 Tôi có thể hỗ trợ gì cho bạn không?"
}
);
break;
default:
console.log("Event không cần xử lý:", event.event_name);
}
};
return handleWebhookEvent;
}
/**
* Chạy tất cả ví dụ
*/
async function runAllExamples() {
console.log("🚀 Bắt đầu chạy các ví dụ ConsultationService\n");
// Ví dụ cơ bản
await basicConsultationExample();
await imageConsultationExample();
await fileConsultationExample();
// Ví dụ hệ thống hỗ trợ thông minh
const customerSupport = new SmartCustomerSupport(zalo, ACCESS_TOKEN);
await customerSupport.handleCustomerQuestion("user123", "Tôi không đăng nhập được");
await customerSupport.handleCustomerQuestion("user456", "Làm sao để thanh toán?");
// Ví dụ retry
await sendWithRetry("user789", "Tin nhắn test retry");
// Thiết lập webhook
const webhookHandler = setupWebhookIntegration();
// Giả lập một số webhook events
await webhookHandler({
event_name: "user_send_text",
sender: { id: "user123" },
message: { text: "Tôi cần hỗ trợ về đăng nhập" }
});
console.log("\n✅ Hoàn thành tất cả ví dụ!");
}
// Chạy ví dụ nếu file được execute trực tiếp
if (require.main === module) {
runAllExamples().catch(console.error);
}
export {
basicConsultationExample,
imageConsultationExample,
fileConsultationExample,
SmartCustomerSupport,
sendWithRetry,
setupWebhookIntegration,
runAllExamples
};