UNPKG

n8n-nodes-salla

Version:

n8n node for Salla.sa e-commerce platform integration with OAuth2.0

254 lines (253 loc) 10.4 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.SallaTrigger = void 0; const n8n_workflow_1 = require("n8n-workflow"); const GenericFunctions_1 = require("./GenericFunctions"); class SallaTrigger { constructor() { this.description = { displayName: 'Salla Trigger', name: 'sallaTrigger', icon: 'file:salla.svg', group: ['trigger'], version: 1, description: 'Handle Salla webhooks', defaults: { name: 'Salla Trigger', }, inputs: [], outputs: ["main" /* NodeConnectionType.Main */], credentials: [ { name: 'sallaOAuth2Api', required: false, }, ], webhooks: [ { name: 'default', httpMethod: 'POST', responseMode: 'onReceived', path: 'webhook', }, ], properties: [ { displayName: 'Events', name: 'events', type: 'multiOptions', options: [ { name: 'Order Created', value: 'order.created', description: 'Triggered when a new order is created', }, { name: 'Order Updated', value: 'order.updated', description: 'Triggered when an order is updated', }, { name: 'Order Cancelled', value: 'order.cancelled', description: 'Triggered when an order is cancelled', }, { name: 'Order Shipped', value: 'order.shipped', description: 'Triggered when an order is shipped', }, { name: 'Order Delivered', value: 'order.delivered', description: 'Triggered when an order is delivered', }, { name: 'Product Created', value: 'product.created', description: 'Triggered when a new product is created', }, { name: 'Product Updated', value: 'product.updated', description: 'Triggered when a product is updated', }, { name: 'Product Deleted', value: 'product.deleted', description: 'Triggered when a product is deleted', }, { name: 'Customer Created', value: 'customer.created', description: 'Triggered when a new customer is created', }, { name: 'Customer Updated', value: 'customer.updated', description: 'Triggered when a customer is updated', }, { name: 'Customer Deleted', value: 'customer.deleted', description: 'Triggered when a customer is deleted', }, { name: 'Payment Created', value: 'payment.created', description: 'Triggered when a payment is created', }, { name: 'Payment Updated', value: 'payment.updated', description: 'Triggered when a payment is updated', }, { name: 'Coupon Used', value: 'coupon.used', description: 'Triggered when a coupon is used', }, { name: 'Special Offer Applied', value: 'special_offer.applied', description: 'Triggered when a special offer is applied', }, { name: 'Shipment Created', value: 'shipment.created', description: 'Triggered when a shipment is created', }, { name: 'Shipment Updated', value: 'shipment.updated', description: 'Triggered when a shipment is updated', }, { name: 'Review Created', value: 'review.created', description: 'Triggered when a new review is created', }, { name: 'All Events', value: '*', description: 'Triggered for all webhook events', }, ], default: [], description: 'The events to listen to', required: true, }, { displayName: 'Validate Webhook', name: 'validateWebhook', type: 'boolean', default: true, description: 'Whether to validate the webhook signature', }, { displayName: 'Webhook Secret', name: 'webhookSecret', type: 'string', typeOptions: { password: true, }, displayOptions: { show: { validateWebhook: [true], }, }, default: '', description: 'The webhook secret for signature validation. If empty, will use the secret from credentials.', }, { displayName: 'Return Raw Data', name: 'returnRawData', type: 'boolean', default: false, description: 'Whether to return the raw webhook data instead of the parsed event data', }, ], }; } async webhook() { const bodyData = this.getBodyData(); const headers = this.getHeaderData(); const events = this.getNodeParameter('events'); const validateWebhookSignature = this.getNodeParameter('validateWebhook'); const webhookSecret = this.getNodeParameter('webhookSecret'); const returnRawData = this.getNodeParameter('returnRawData'); let eventType = headers['x-salla-event-type']; if (!eventType) { eventType = bodyData.event || 'unknown'; } // Check if this event should be processed const shouldProcess = events.includes('*') || events.includes(eventType); if (!shouldProcess) { return { webhookResponse: { status: 200, body: { message: 'Event ignored' }, }, }; } // Validate webhook signature if enabled if (validateWebhookSignature) { const signature = headers['x-salla-signature']; let secret = webhookSecret; // If no secret provided in node, try to get from credentials if (!secret) { try { const credentials = await this.getCredentials('sallaOAuth2Api'); secret = credentials.webhookSecret; } catch (error) { // Credentials not required for webhook, continue without validation } } if (secret && signature) { // Get raw body from request object for signature validation const req = this.getRequestObject(); const rawBody = typeof req.body === 'string' ? req.body : JSON.stringify(req.body); const isValid = (0, GenericFunctions_1.validateWebhook)(rawBody, signature, secret); if (!isValid) { throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Invalid webhook signature'); } } } // Parse and format the webhook data let responseData; if (returnRawData) { responseData = { headers, body: bodyData, event: eventType, timestamp: new Date().toISOString(), }; } else { responseData = { event: eventType, timestamp: headers['x-salla-timestamp'] || new Date().toISOString(), merchantId: headers['x-salla-merchant'] || bodyData.merchant_id, data: bodyData.data || bodyData, ...bodyData, }; // Remove redundant fields delete responseData.merchant_id; } return { workflowData: [ [ { json: responseData, }, ], ], webhookResponse: { status: 200, body: { message: 'Webhook received successfully' }, }, }; } } exports.SallaTrigger = SallaTrigger;