UNPKG

@traien/n8n-nodes-espocrm

Version:
277 lines 10.7 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.EspoCRMTrigger = void 0; const n8n_workflow_1 = require("n8n-workflow"); const crypto_1 = require("crypto"); class EspoCRMTrigger { constructor() { this.description = { displayName: 'EspoCRM Trigger', name: 'espoCrmTrigger', icon: 'file:espocrm-trigger.svg', group: ['trigger'], version: 1, subtitle: '={{$parameter["eventType"] + ": " + $parameter["entityType"]}}', description: 'Handle EspoCRM Webhooks', defaults: { name: 'EspoCRM Trigger', }, inputs: [], outputs: ['main'], documentationUrl: 'https://docs.espocrm.com/administration/webhooks', credentials: [ { name: 'espoCRMApi', required: true, }, ], webhooks: [ { name: 'default', httpMethod: 'POST', responseMode: 'onReceived', path: 'webhook', }, ], properties: [ { displayName: 'Event Type', name: 'eventType', type: 'options', options: [ { name: 'Record Created', value: 'create', description: 'Triggered when a record is created', }, { name: 'Record Updated', value: 'update', description: 'Triggered when a record is updated', }, { name: 'Record Deleted', value: 'delete', description: 'Triggered when a record is deleted', }, { name: 'Field Updated', value: 'fieldUpdate', description: 'Triggered when a specific field is updated', }, ], default: 'create', required: true, description: 'Type of event to listen for', }, { displayName: 'Entity Type', name: 'entityType', type: 'string', default: '', required: true, description: 'Type of entity to monitor (e.g., Contact, Account, Lead)', placeholder: 'Account', }, { displayName: 'Field Name', name: 'fieldName', type: 'string', default: '', placeholder: 'assignedUserId', description: 'Name of the field to monitor for updates', displayOptions: { show: { eventType: ['fieldUpdate'], }, }, }, { displayName: 'Verification', name: 'verification', type: 'boolean', default: true, description: 'Whether to verify the webhook signature to ensure it comes from EspoCRM', }, ], }; } async webhookCreate() { const webhookUrl = this.getNodeWebhookUrl('default'); const webhookData = this.getWorkflowStaticData('node'); const eventType = this.getNodeParameter('eventType'); const entityType = this.getNodeParameter('entityType'); const credentials = await this.getCredentials('espoCRMApi'); let eventName = `${entityType}.${eventType}`; if (eventType === 'fieldUpdate') { const fieldName = this.getNodeParameter('fieldName'); if (!fieldName) { throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Field name is required for field update events'); } eventName += `.${fieldName}`; } const options = { method: 'POST', url: '/Webhook', headers: { 'Accept': 'application/json', 'Content-Type': 'application/json', }, body: { event: eventName, url: webhookUrl, }, }; if (credentials.authType === 'hmac' && credentials.secretKey) { const hmacString = 'POST /Webhook'; const hmac = (0, crypto_1.createHmac)('sha256', credentials.secretKey); hmac.update(hmacString); const signature = hmac.digest('base64'); const authPart = Buffer.from(credentials.apiKey + ':').toString('base64') + signature; options.headers['X-Hmac-Authorization'] = authPart; } else { options.headers['X-Api-Key'] = credentials.apiKey; } try { const response = await this.helpers.httpRequest({ baseURL: `${credentials.baseUrl}/api/v1`, ...options, }); if (response.id && response.secretKey) { webhookData.webhookId = response.id; webhookData.secretKey = response.secretKey; return true; } else { throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Failed to create webhook in EspoCRM: Invalid response'); } } catch (error) { if (error.response && error.response.body) { const errorMessage = error.response.body.message || error.message; const statusCode = error.statusCode; throw new n8n_workflow_1.NodeOperationError(this.getNode(), `EspoCRM API error: ${errorMessage}. Status: ${statusCode}`); } throw error; } } async webhookDelete() { const webhookData = this.getWorkflowStaticData('node'); if (!webhookData.webhookId) { return true; } const credentials = await this.getCredentials('espoCRMApi'); const options = { method: 'DELETE', url: `/Webhook/${webhookData.webhookId}`, headers: { 'Accept': 'application/json', }, }; if (credentials.authType === 'hmac' && credentials.secretKey) { const hmacString = `DELETE /Webhook/${webhookData.webhookId}`; const hmac = (0, crypto_1.createHmac)('sha256', credentials.secretKey); hmac.update(hmacString); const signature = hmac.digest('base64'); const authPart = Buffer.from(credentials.apiKey + ':').toString('base64') + signature; options.headers['X-Hmac-Authorization'] = authPart; } else { options.headers['X-Api-Key'] = credentials.apiKey; } try { await this.helpers.httpRequest({ baseURL: `${credentials.baseUrl}/api/v1`, ...options, }); delete webhookData.webhookId; delete webhookData.secretKey; return true; } catch (error) { if (error.statusCode === 410 || error.statusCode === 404) { delete webhookData.webhookId; delete webhookData.secretKey; return true; } if (error.response && error.response.body) { const errorMessage = error.response.body.message || error.message; const statusCode = error.statusCode; throw new n8n_workflow_1.NodeOperationError(this.getNode(), `EspoCRM API error: ${errorMessage}. Status: ${statusCode}`); } throw error; } } async webhook() { const webhookData = this.getWorkflowStaticData('node'); const bodyData = this.getBodyData(); const headerData = this.getHeaderData(); const verification = this.getNodeParameter('verification'); if (verification && webhookData.secretKey && webhookData.webhookId) { const signature = headerData.signature || headerData['x-signature']; if (!signature) { return { webhookResponse: { body: { error: 'Signature missing' }, statusCode: 401, }, }; } try { const payload = JSON.stringify(bodyData); const calculatedSignature = Buffer.from(`${webhookData.webhookId}:${(0, crypto_1.createHmac)('sha256', webhookData.secretKey).update(payload).digest('hex')}`).toString('base64'); if (signature !== calculatedSignature) { return { webhookResponse: { body: { error: 'Invalid signature' }, statusCode: 401, }, }; } } catch (error) { return { webhookResponse: { body: { error: 'Failed to verify signature' }, statusCode: 500, }, }; } } if (Array.isArray(bodyData)) { const returnData = []; for (const item of bodyData) { returnData.push({ json: item, pairedItem: { item: 0, }, }); } return { workflowData: [ [ ...returnData, ], ], }; } else { return { workflowData: [ [ { json: bodyData, pairedItem: { item: 0, }, }, ], ], }; } } } exports.EspoCRMTrigger = EspoCRMTrigger; //# sourceMappingURL=EspoCRMTrigger.node.js.map