import { IHookFunctions, IWebhookFunctions, } from 'n8n-core'; import { IDataObject, ILoadOptionsFunctions, INodeType, INodeTypeDescription, IWebhookResponseData, } from 'n8n-workflow'; import { lemlistApiRequest, } from './GenericFunctions'; export class LemlistTrigger implements INodeType { description: INodeTypeDescription = { displayName: 'Lemlist Trigger', name: 'lemlistTrigger', icon: 'file:lemlist.svg', group: ['trigger'], version: 1, subtitle: '={{$parameter["event"]}}', description: 'Handle Lemlist events via webhooks', defaults: { name: 'Lemlist Trigger', color: '#4d19ff', }, inputs: [], outputs: ['main'], credentials: [ { name: 'lemlistApi', required: true, }, ], webhooks: [ { name: 'default', httpMethod: 'POST', responseMode: 'onReceived', path: 'webhook', }, ], properties: [ { displayName: 'Event', name: 'event', type: 'options', required: true, default: '', options: [ { name: 'Email Bounced', value: 'emailsBounced', }, { name: 'Email Clicked', value: 'emailsClicked', }, { name: 'Email Opened', value: 'emailsOpened', }, { name: 'Email Replied', value: 'emailsReplied', }, { name: 'Email Send Failed', value: 'emailsSendFailed', }, { name: 'Email Sent', value: 'emailsSent', }, { name: 'Email Unsubscribed', value: 'emailsUnsubscribed', }, ], }, { displayName: 'Options', name: 'options', type: 'collection', placeholder: 'Add Field', default: {}, options: [ { displayName: 'Campaing ID', name: 'campaignId', type: 'options', typeOptions: { loadOptionsMethod: 'getCampaigns', }, default: '', description: ` We'll call this hook only for this campaignId.`, }, { displayName: 'Is First', name: 'isFirst', type: 'boolean', default: false, description: `We'll call this hook only the first time this activity happened.`, }, ], }, ], }; methods = { loadOptions: { async getCampaigns(this: ILoadOptionsFunctions) { const campaigns = await lemlistApiRequest.call(this, 'GET', '/campaigns'); return campaigns.map(({ _id, name }: { _id: string, name: string }) => ({ name, value: _id, })); }, }, }; // @ts-ignore webhookMethods = { default: { async checkExists(this: IHookFunctions): Promise { const webhookData = this.getWorkflowStaticData('node'); const webhookUrl = this.getNodeWebhookUrl('default'); const webhooks = await lemlistApiRequest.call(this, 'GET', '/hooks'); for (const webhook of webhooks) { if (webhook.targetUrl === webhookUrl) { await lemlistApiRequest.call(this, 'DELETE', `/hooks/${webhookData.webhookId}`); return false; } } return false; }, async create(this: IHookFunctions): Promise { const webhookUrl = this.getNodeWebhookUrl('default'); const webhookData = this.getWorkflowStaticData('node'); const options = this.getNodeParameter('options') as IDataObject; const event = this.getNodeParameter('event') as string[]; const body: IDataObject = { targetUrl: webhookUrl, event, }; Object.assign(body, options); const webhook = await lemlistApiRequest.call(this, 'POST', '/hooks', body); webhookData.webhookId = webhook._id; return true; }, async delete(this: IHookFunctions): Promise { const webhookData = this.getWorkflowStaticData('node'); try { await lemlistApiRequest.call(this, 'DELETE', `/hooks/${webhookData.webhookId}`); } catch (error) { return false; } delete webhookData.webhookId; return true; }, }, }; async webhook(this: IWebhookFunctions): Promise { const req = this.getRequestObject(); return { workflowData: [ this.helpers.returnJsonArray(req.body), ], }; } }