UNPKG

n8n-nodes-livo

Version:

n8n Livo App integration with triggers and actions for orders, products, customers, and repairs

279 lines (278 loc) 13.3 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.LivoProductEvents = void 0; const n8n_workflow_1 = require("n8n-workflow"); class LivoProductEvents { constructor() { this.description = { displayName: 'Livo Product Events', name: 'livoProductEvents', icon: 'file:product.svg', group: ['trigger'], version: 1, subtitle: '={{$parameter["eventType"]}}', description: 'Lắng nghe các sự kiện sản phẩm từ ứng dụng Livo', defaults: { name: 'Livo Product Events', }, inputs: [], outputs: ['main'], webhooks: [ { name: 'default', httpMethod: 'POST', responseMode: 'onReceived', path: 'webhook', }, ], properties: [ { displayName: 'Event Type', name: 'eventType', type: 'options', options: [ { name: 'Lấy danh sách sản phẩm', value: 'product.list', description: 'Trigger khi lấy danh sách sản phẩm', }, { name: 'Chi tiết sản phẩm', value: 'product.detail', description: 'Trigger khi xem chi tiết sản phẩm', }, { name: 'Tạo sản phẩm', value: 'product.created', description: 'Trigger khi tạo mới sản phẩm', }, { name: 'Cập nhật sản phẩm', value: 'product.updated', description: 'Trigger khi cập nhật sản phẩm', }, { name: 'Xóa sản phẩm', value: 'product.deleted', description: 'Trigger khi xóa sản phẩm', }, { name: 'Nhập kho', value: 'product.stock_in', description: 'Trigger khi nhập hàng vào kho', }, { name: 'Xuất kho', value: 'product.stock_out', description: 'Trigger khi xuất hàng khỏi kho', }, ], default: 'product.created', required: true, }, { displayName: 'Advanced Filters', name: 'advancedFilters', type: 'collection', placeholder: 'Add Filter', default: {}, options: [ { displayName: 'Category', name: 'category', type: 'string', default: '', description: 'Lọc theo danh mục sản phẩm', }, { displayName: 'Brand', name: 'brand', type: 'string', default: '', description: 'Lọc theo thương hiệu', }, { displayName: 'Min Price', name: 'minPrice', type: 'number', default: 0, description: 'Giá sản phẩm tối thiểu', }, { displayName: 'Max Price', name: 'maxPrice', type: 'number', default: 0, description: 'Giá sản phẩm tối đa (0 = không giới hạn)', }, { displayName: 'Stock Threshold', name: 'stockThreshold', type: 'number', default: 0, description: 'Ngưỡng tồn kho để lọc', }, { displayName: 'Assigned Staff', name: 'assignedStaff', type: 'string', default: '', description: 'Lọc theo nhân viên phụ trách', }, { displayName: 'Branch', name: 'branch', type: 'string', default: '', description: 'Lọc theo chi nhánh', }, ], }, { displayName: 'Authentication', name: 'authentication', type: 'collection', placeholder: 'Add Authentication', default: {}, options: [ { displayName: 'Secret Token', name: 'secretToken', type: 'string', typeOptions: { password: true, }, default: '', description: 'Token bí mật để xác thực webhook', }, { displayName: 'Header Name', name: 'headerName', type: 'string', default: 'X-Webhook-Secret', description: 'Tên header chứa token xác thực', }, ], }, ], }; } async webhook() { const bodyData = this.getBodyData(); const headers = this.getHeaderData(); const query = this.getQueryData(); const req = this.getRequestObject(); const expectedEventType = this.getNodeParameter('eventType'); const advancedFilters = this.getNodeParameter('advancedFilters', {}); const authentication = this.getNodeParameter('authentication', {}); if (authentication.secretToken) { const headerName = authentication.headerName || 'X-Webhook-Secret'; const receivedToken = headers[headerName.toLowerCase()] || headers[headerName]; if (!receivedToken || receivedToken !== authentication.secretToken) { throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Xác thực webhook thất bại: Token không hợp lệ'); } } if (!bodyData || typeof bodyData !== 'object') { throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Dữ liệu webhook không hợp lệ'); } const eventData = bodyData; const receivedEvent = eventData.event || headers['x-event-type']; if (receivedEvent !== expectedEventType) { return { noWebhookResponse: true, }; } if (advancedFilters.category && eventData.category !== advancedFilters.category) { return { noWebhookResponse: true }; } if (advancedFilters.brand && eventData.brand !== advancedFilters.brand) { return { noWebhookResponse: true }; } if (advancedFilters.minPrice && (eventData.unit_price || 0) < advancedFilters.minPrice) { return { noWebhookResponse: true }; } if (advancedFilters.maxPrice && advancedFilters.maxPrice > 0 && (eventData.unit_price || 0) > advancedFilters.maxPrice) { return { noWebhookResponse: true }; } if (advancedFilters.stockThreshold && (eventData.stock_quantity || 0) < advancedFilters.stockThreshold) { return { noWebhookResponse: true }; } if (advancedFilters.assignedStaff && eventData.assigned_staff !== advancedFilters.assignedStaff) { return { noWebhookResponse: true }; } if (advancedFilters.branch && eventData.branch !== advancedFilters.branch) { return { noWebhookResponse: true }; } const outputData = { app_name: 'Livo', event: receivedEvent, event_time: new Date().toISOString(), event_category: 'product', id: eventData.id || eventData.product_id, code: eventData.code || eventData.product_code, status: eventData.status || eventData.trang_thai, created_date: eventData.created_date || eventData.ngay_tao, updated_date: eventData.updated_date || eventData.ngay_cap_nhat, assigned_staff: eventData.assigned_staff || eventData.nhan_vien_phu_trach, branch: eventData.branch || eventData.chi_nhanh, notes: eventData.notes || eventData.ghi_chu, product_id: eventData.product_id || eventData.ma_san_pham, product_name: eventData.product_name || eventData.ten_san_pham, product_code: eventData.product_code || eventData.ma_san_pham, sku: eventData.sku || eventData.ma_sku, barcode: eventData.barcode || eventData.ma_vach, category: eventData.category || eventData.danh_muc, subcategory: eventData.subcategory || eventData.danh_muc_con, brand: eventData.brand || eventData.thuong_hieu, model: eventData.model || eventData.model, variant: eventData.variant || eventData.bien_the, description: eventData.description || eventData.mo_ta, short_description: eventData.short_description || eventData.mo_ta_ngan, specifications: eventData.specifications || eventData.thong_so_ky_thuat || {}, features: eventData.features || eventData.tinh_nang || [], unit_price: eventData.unit_price || eventData.gia_ban, cost_price: eventData.cost_price || eventData.gia_von, wholesale_price: eventData.wholesale_price || eventData.gia_si, retail_price: eventData.retail_price || eventData.gia_le, discount_price: eventData.discount_price || eventData.gia_khuyen_mai, stock_quantity: eventData.stock_quantity || eventData.ton_kho, min_stock_level: eventData.min_stock_level || eventData.ton_kho_toi_thieu, max_stock_level: eventData.max_stock_level || eventData.ton_kho_toi_da, reorder_point: eventData.reorder_point || eventData.diem_dat_hang_lai, weight: eventData.weight || eventData.trong_luong, dimensions: eventData.dimensions || eventData.kich_thuoc, color: eventData.color || eventData.mau_sac, size: eventData.size || eventData.kich_co, material: eventData.material || eventData.chat_lieu, is_active: eventData.is_active || eventData.dang_hoat_dong, is_featured: eventData.is_featured || eventData.san_pham_noi_bat, sales_count: eventData.sales_count || eventData.so_luong_ban, view_count: eventData.view_count || eventData.luot_xem, rating: eventData.rating || eventData.danh_gia, review_count: eventData.review_count || eventData.so_binh_luan, meta_title: eventData.meta_title || eventData.tieu_de_seo, meta_description: eventData.meta_description || eventData.mo_ta_seo, keywords: eventData.keywords || eventData.tu_khoa || [], tags: eventData.tags || eventData.the_bai || [], images: eventData.images || eventData.hinh_anh || [], thumbnail: eventData.thumbnail || eventData.hinh_dai_dien, gallery: eventData.gallery || eventData.thu_vien_anh || [], raw_data: eventData, headers: headers, query: query, webhook_url: req.url, }; return { workflowData: [ [ { json: outputData, }, ], ], }; } } exports.LivoProductEvents = LivoProductEvents;