UNPKG

n8n-nodes-zalo-oa-integration

Version:

Tích hợp Zalo Official Account API v3.0 vào n8n

289 lines 11.9 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); Object.defineProperty(exports, "__esModule", { value: true }); exports.ZaloOAWebhook = void 0; const n8n_workflow_1 = require("n8n-workflow"); const crypto = __importStar(require("crypto")); class ZaloOAWebhook { constructor() { this.description = { displayName: 'Zalo OA Webhook', name: 'zaloOAWebhook', icon: 'file:zalooa.svg', group: ['trigger'], version: 1, description: 'Xử lý các sự kiện webhook từ Zalo OA', defaults: { name: 'Zalo OA Webhook', }, inputs: [], outputs: ["main"], credentials: [ { name: 'zaloOAApi', required: true, }, ], webhooks: [ { name: 'default', httpMethod: 'POST', responseMode: 'onReceived', path: 'webhook', }, ], properties: [ { displayName: 'OA Secret Key', name: 'oaSecretKey', type: 'string', default: '', required: true, description: 'OA Secret Key từ trang quản lý Zalo OA', typeOptions: { password: true, }, }, { displayName: 'Các Loại Sự Kiện', name: 'events', type: 'multiOptions', options: [ { name: 'Người Dùng Follow OA', value: 'follow', description: 'Khi người dùng bắt đầu theo dõi OA', }, { name: 'Người Dùng Unfollow OA', value: 'unfollow', description: 'Khi người dùng hủy theo dõi OA', }, { name: 'Người Dùng Gửi Tin Nhắn Văn Bản', value: 'user_send_text', description: 'Khi người dùng gửi tin nhắn văn bản', }, { name: 'Người Dùng Gửi Hình Ảnh', value: 'user_send_image', description: 'Khi người dùng gửi hình ảnh', }, { name: 'Người Dùng Gửi File', value: 'user_send_file', description: 'Khi người dùng gửi file', }, { name: 'Người Dùng Gửi Vị Trí', value: 'user_send_location', description: 'Khi người dùng gửi vị trí', }, { name: 'Người Dùng Gửi Sticker', value: 'user_send_sticker', description: 'Khi người dùng gửi sticker', }, { name: 'Người Dùng Gửi GIF', value: 'user_send_gif', description: 'Khi người dùng gửi GIF', }, { name: 'Người Dùng Nhấp Vào Nút', value: 'user_click_button', description: 'Khi người dùng nhấp vào nút trong tin nhắn', }, { name: 'Người Dùng Nhấp Vào Liên Kết', value: 'user_click_link', description: 'Khi người dùng nhấp vào liên kết trong tin nhắn', }, { name: 'Tất Cả Sự Kiện', value: 'all', description: 'Nhận tất cả các loại sự kiện', }, ], default: ['all'], required: true, description: 'Các loại sự kiện muốn nhận từ Zalo OA', }, { displayName: 'Xác Thực Mac', name: 'validateMac', type: 'boolean', default: true, description: 'Xác thực chữ ký MAC từ Zalo OA để đảm bảo an toàn', }, ], }; } async webhook() { const req = this.getRequestObject(); const headerData = this.getHeaderData(); const oaSecretKey = this.getNodeParameter('oaSecretKey'); const validateMac = this.getNodeParameter('validateMac'); const events = this.getNodeParameter('events'); if (req.method === 'GET') { const query = this.getQueryData(); if (Object.prototype.hasOwnProperty.call(query, 'hub.challenge')) { return { workflowData: [[ { json: { event_type: 'webhook_verification', challenge: query['hub.challenge'], timestamp: new Date().toISOString(), }, }, ]], webhookResponse: query['hub.challenge'], }; } } if (req.method === 'POST') { try { const body = req.body; if (validateMac) { const mac = headerData.mac; if (!mac) { return { workflowData: [[ { json: { event_type: 'error', error: 'Missing MAC header', timestamp: new Date().toISOString(), }, }, ]], webhookResponse: { statusCode: 401, body: { error: 'Missing MAC header', }, }, }; } const data = JSON.stringify(body); const calculatedMac = crypto.createHmac('sha256', oaSecretKey) .update(data) .digest('hex'); if (mac !== calculatedMac) { return { workflowData: [[ { json: { event_type: 'error', error: 'Invalid MAC', timestamp: new Date().toISOString(), }, }, ]], webhookResponse: { statusCode: 401, body: { error: 'Invalid MAC', }, }, }; } } const eventType = body.event_name; if (!events.includes('all') && !events.includes(eventType)) { return { workflowData: [[ { json: { event_type: 'ignored', original_event: eventType, message: 'Event ignored - not in selected events', timestamp: new Date().toISOString(), }, }, ]], webhookResponse: { statusCode: 200, body: { message: 'Event ignored', }, }, }; } const returnData = []; returnData.push({ json: { ...body, event_type: eventType, timestamp: new Date().toISOString(), }, }); return { workflowData: [returnData], webhookResponse: { statusCode: 200, body: { message: 'Webhook received', }, }, }; } catch (error) { throw new n8n_workflow_1.NodeOperationError(this.getNode(), error); } } return { workflowData: [[ { json: { event_type: 'error', error: 'Method not allowed', method: req.method, timestamp: new Date().toISOString(), }, }, ]], webhookResponse: { statusCode: 405, body: { error: 'Method not allowed', }, }, }; } } exports.ZaloOAWebhook = ZaloOAWebhook; //# sourceMappingURL=ZaloOAWebhook.node.js.map