UNPKG

@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

404 lines 16.6 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.MessageManagementService = void 0; const common_1 = require("../types/common"); /** * Service xử lý các API quản lý tin nhắn của Zalo Official Account * * Bao gồm các chức năng: * - Kiểm tra hạn mức gửi tin nhắn * - Lấy danh sách tin nhắn trong cuộc hội thoại với user cụ thể * - Lấy thông tin tin nhắn gần nhất * - Upload file và hình ảnh * * ĐIỀU KIỆN SỮCDNG: * * 1. KIỂM TRA HẠN MỨC: * - Cần quyền truy cập thông tin quota từ Zalo * - Quota được reset hàng ngày vào 00:00 GMT+7 * * 2. LẤY TIN NHẮN: * - API hỗ trợ lấy thông tin tin nhắn giữa OA và một người dùng cụ thể * - Mỗi request lấy tối đa được 10 tin nhắn * - Tin nhắn gần nhất có thứ tự là 0 * * 3. UPLOAD FILE: * - Kích thước tối đa 5MB * - Hỗ trợ các định dạng: PDF, DOC, DOCX * - Quota: 5000 request/tháng * * 4. UPLOAD HÌNH ẢNH: * - Dung lượng tối đa 1MB * - Hỗ trợ các định dạng: JPG và PNG * - Ảnh sẽ được lưu trên server tối đa 7 ngày * - Quota: 5000 request/tháng * * 5. UPLOAD ẢNH GIF: * - Kích thước tối đa 5MB * - Chỉ hỗ trợ định dạng GIF * - Ảnh GIF được lưu trên server tối đa 7 ngày * - Quota: 5000 request/tháng */ class MessageManagementService { constructor(client) { this.client = client; // Zalo API endpoints - organized by functionality this.endpoints = { // Message management endpoints message: { quota: "https://openapi.zalo.me/v2.0/oa/quota", conversation: "https://openapi.zalo.me/v2.0/oa/conversation", recentConversations: "https://openapi.zalo.me/v2.0/oa/listrecentchat", }, // Upload endpoints upload: { file: "https://openapi.zalo.me/v2.0/oa/upload/file", image: "https://openapi.zalo.me/v2.0/oa/upload/image", gif: "https://openapi.zalo.me/v2.0/oa/upload/gif", }, }; } /** * Kiểm tra hạn mức gửi tin nhắn đến user cụ thể * @param accessToken Access token của Official Account * @param userId ID của người dùng Zalo * @returns Thông tin hạn mức gửi tin nhắn */ async checkMessageQuota(accessToken, userId) { try { const result = await this.client.apiGet(this.endpoints.message.quota, accessToken, { user_id: userId }); if (result.error !== 0) { throw new common_1.ZaloSDKError(result.message || "Failed to check message quota", result.error, result); } if (!result.data) { throw new common_1.ZaloSDKError("No quota data received", -1); } return result.data; } catch (error) { if (error instanceof common_1.ZaloSDKError) { throw error; } throw new common_1.ZaloSDKError(`Failed to check message quota: ${error.message}`, -1, error); } } /** * Lấy danh sách tin nhắn trong cuộc hội thoại với user * * API hỗ trợ lấy thông tin tin nhắn giữa OA và một người dùng cụ thể. * * @param accessToken Access token của Official Account * @param userId ID của người dùng Zalo cần lấy danh sách hội thoại * @param offset Thứ tự của tin nhắn đầu tiên trong danh sách trả về (tin nhắn gần nhất có thứ tự là 0) * @param count Số lượng tin nhắn cần lấy (mỗi request lấy tối đa 10 tin nhắn) * @returns Danh sách tin nhắn * * @example * ```typescript * const messages = await messageService.getConversationMessages( * accessToken, * '2512523625412515', * 0, * 5 * ); * ``` */ async getConversationMessages(accessToken, userId, offset = 0, count = 10) { try { // Validate count theo docs: mỗi request lấy tối đa 10 tin nhắn if (count > 10) { throw new common_1.ZaloSDKError("Mỗi request lấy tối đa được 10 tin nhắn", -1); } // Theo docs Zalo: params phải được wrap trong object data dạng JSON string const params = { data: JSON.stringify({ user_id: userId, offset, count, }), }; const result = await this.client.apiGet(this.endpoints.message.conversation, accessToken, params); if (result.error !== 0) { throw new common_1.ZaloSDKError(result.message || "Failed to get conversation messages", result.error, result); } if (!result.data) { throw new common_1.ZaloSDKError("No conversation data received", -1); } // Response trả về mảng trực tiếp trong data return result.data; } catch (error) { if (error instanceof common_1.ZaloSDKError) { throw error; } throw new common_1.ZaloSDKError(`Failed to get conversation messages: ${error.message}`, -1, error); } } /** * Lấy danh sách tin nhắn trong cuộc hội thoại với user (sử dụng POST method) * * API hỗ trợ lấy thông tin tin nhắn giữa OA và một người dùng cụ thể sử dụng phương thức POST. * * @param accessToken Access token của Official Account * @param userId ID của người dùng Zalo cần lấy danh sách hội thoại * @param offset Thứ tự của tin nhắn đầu tiên trong danh sách trả về (tin nhắn gần nhất có thứ tự là 0) * @param count Số lượng tin nhắn cần lấy (mỗi request lấy tối đa 10 tin nhắn) * @returns Danh sách tin nhắn * * @example * ```typescript * const messages = await messageService.postConversationMessages( * accessToken, * '2512523625412515', * 0, * 5 * ); * ``` */ async postConversationMessages(accessToken, userId, offset = 0, count = 10) { try { // Validate count theo docs: mỗi request lấy tối đa 10 tin nhắn if (count > 10) { throw new common_1.ZaloSDKError("Mỗi request lấy tối đa được 10 tin nhắn", -1); } // Body format for POST request - gửi trực tiếp các tham số const body = { user_id: userId, offset, count, }; const result = await this.client.apiPost(this.endpoints.message.conversation, accessToken, body); if (result.error !== 0) { throw new common_1.ZaloSDKError(result.message || "Failed to get conversation messages", result.error, result); } if (!result.data) { throw new common_1.ZaloSDKError("No conversation data received", -1); } // Response trả về mảng trực tiếp trong data return result.data; } catch (error) { if (error instanceof common_1.ZaloSDKError) { throw error; } throw new common_1.ZaloSDKError(`Failed to get conversation messages: ${error.message}`, -1, error); } } /** * Lấy thông tin tin nhắn gần nhất * * API hỗ trợ lấy thông tin tối đa 10 tin nhắn gần nhất giữa OA và người dùng. * * @param accessToken Access token của Official Account * @param offset Thứ tự của tin nhắn đầu tiên trong danh sách trả về (tin nhắn gần nhất có thứ tự là 0) * @param count Số lượng tin nhắn muốn lấy (mỗi request lấy tối đa 10 tin nhắn) * @returns Danh sách tin nhắn gần nhất * * @example * ```typescript * const recentMessages = await messageService.getRecentConversations( * accessToken, * 0, * 5 * ); * ``` */ async getRecentConversations(accessToken, offset = 0, count = 10) { try { // Validate count theo docs: mỗi request lấy tối đa 10 tin nhắn if (count > 10) { throw new common_1.ZaloSDKError("Mỗi request lấy tối đa 10 tin nhắn", -1); } // Theo docs Zalo: params phải được wrap trong object data dạng JSON string const params = { data: JSON.stringify({ offset, count, }), }; const result = await this.client.apiGet(this.endpoints.message.recentConversations, accessToken, params); if (result.error !== 0) { throw new common_1.ZaloSDKError(result.message || "Failed to get recent messages", result.error, result); } if (!result.data) { throw new common_1.ZaloSDKError("No recent messages data received", -1); } // Response trả về mảng trực tiếp trong data return result.data; } catch (error) { if (error instanceof common_1.ZaloSDKError) { throw error; } throw new common_1.ZaloSDKError(`Failed to get recent messages: ${error.message}`, -1, error); } } /** * Upload file để sử dụng trong tin nhắn * @param accessToken Access token của Official Account * @param fileData Dữ liệu file (base64 hoặc buffer) * @param fileName Tên file * @returns Token của file đã upload * * Lưu ý: * - Chỉ hỗ trợ file PDF/DOC/DOCX * - Dung lượng file không vượt quá 5MB * - File sẽ được lưu trên server tối đa 7 ngày * - Quota: 5000 request/tháng */ async uploadFile(accessToken, fileData, fileName) { try { // Validate file format (only PDF/DOC/DOCX) const allowedExtensions = ['.pdf', '.doc', '.docx']; const fileExt = fileName.toLowerCase().substring(fileName.lastIndexOf('.')); if (!allowedExtensions.includes(fileExt)) { throw new common_1.ZaloSDKError("Chỉ hỗ trợ file PDF, DOC, DOCX", -1); } // Validate file size (max 5MB) const maxSize = 5 * 1024 * 1024; // 5MB let fileSize; if (typeof fileData === "string") { // Base64 string fileSize = Buffer.from(fileData, "base64").length; } else { // Buffer fileSize = fileData.length; } if (fileSize > maxSize) { throw new common_1.ZaloSDKError("Kích thước file không được vượt quá 5MB", -1); } let buffer; if (typeof fileData === "string") { buffer = Buffer.from(fileData, "base64"); } else { buffer = fileData; } const result = await this.client.apiUploadFile(this.endpoints.upload.file, accessToken, buffer, fileName); if (result.error !== 0) { throw new common_1.ZaloSDKError(result.message || "Failed to upload file", result.error, result); } if (!result.data) { throw new common_1.ZaloSDKError("No upload result received", -1); } return result.data; } catch (error) { if (error instanceof common_1.ZaloSDKError) { throw error; } throw new common_1.ZaloSDKError(`Failed to upload file: ${error.message}`, -1, error); } } /** * Upload hình ảnh để sử dụng trong tin nhắn * @param accessToken Access token của Official Account * @param imageData Dữ liệu hình ảnh (base64 hoặc buffer) * @param fileName Tên file hình ảnh * @returns ID của ảnh đã upload * * Lưu ý: * - Hỗ trợ các định dạng: JPG và PNG * - Dung lượng tối đa: 1MB * - Ảnh sẽ được lưu trên server tối đa 7 ngày * - Quota: 5000 request/tháng */ async uploadImage(accessToken, imageData, fileName) { try { // Validate image size (max 1MB) const maxSize = 1 * 1024 * 1024; // 1MB let imageSize; if (typeof imageData === "string") { // Base64 string imageSize = Buffer.from(imageData, "base64").length; } else { // Buffer imageSize = imageData.length; } if (imageSize > maxSize) { throw new common_1.ZaloSDKError("Kích thước hình ảnh không được vượt quá 1MB", -1); } let buffer; if (typeof imageData === "string") { buffer = Buffer.from(imageData, "base64"); } else { buffer = imageData; } const result = await this.client.apiUploadFile(this.endpoints.upload.image, accessToken, buffer, fileName); if (result.error !== 0) { throw new common_1.ZaloSDKError(result.message || "Failed to upload image", result.error, result); } if (!result.data) { throw new common_1.ZaloSDKError("No upload result received", -1); } return result.data; } catch (error) { if (error instanceof common_1.ZaloSDKError) { throw error; } throw new common_1.ZaloSDKError(`Failed to upload image: ${error.message}`, -1, error); } } /** * Upload ảnh GIF để sử dụng trong tin nhắn * @param accessToken Access token của Official Account * @param gifData Dữ liệu ảnh GIF (base64 hoặc buffer) * @param fileName Tên file ảnh GIF * @returns Thông tin ảnh GIF đã upload * * Lưu ý: * - Dung lượng tối đa: 5MB * - Ảnh GIF sẽ được lưu trên server tối đa 7 ngày * - Quota: 5000 request/tháng * - Định dạng hỗ trợ: GIF */ async uploadGif(accessToken, gifData, fileName) { try { // Validate GIF size (max 5MB) const maxSize = 5 * 1024 * 1024; // 5MB let gifSize; if (typeof gifData === "string") { // Base64 string gifSize = Buffer.from(gifData, "base64").length; } else { // Buffer gifSize = gifData.length; } if (gifSize > maxSize) { throw new common_1.ZaloSDKError("Kích thước ảnh GIF không được vượt quá 5MB", -1); } // Validate file extension if (!fileName.toLowerCase().endsWith(".gif")) { throw new common_1.ZaloSDKError("File phải có định dạng GIF", -1); } let buffer; if (typeof gifData === "string") { buffer = Buffer.from(gifData, "base64"); } else { buffer = gifData; } const result = await this.client.apiUploadFile(this.endpoints.upload.gif, accessToken, buffer, fileName); if (result.error !== 0) { throw new common_1.ZaloSDKError(result.message || "Failed to upload GIF", result.error, result); } if (!result.data) { throw new common_1.ZaloSDKError("No upload result received", -1); } return result.data; } catch (error) { if (error instanceof common_1.ZaloSDKError) { throw error; } throw new common_1.ZaloSDKError(`Failed to upload GIF: ${error.message}`, -1, error); } } } exports.MessageManagementService = MessageManagementService; //# sourceMappingURL=message-management.service.js.map