UNPKG

n8n-nodes-evolution-tools

Version:

n8n node para integrar com Evolution API WhatsApp como ferramenta para agentes com IA

269 lines (252 loc) 6.17 kB
import { IExecuteFunctions } from 'n8n-core'; import { INodeExecutionData, INodeType, INodeTypeDescription, NodeOperationError, } from 'n8n-workflow'; import axios from 'axios'; export class EvolutionApiTool implements INodeType { description: INodeTypeDescription = { displayName: 'Evolution API Tool', name: 'evolutionApiTool', icon: 'file:evolutionApi.svg', group: ['transform'], version: 1, subtitle: '={{$parameter["operation"]}}', description: 'Evolution API WhatsApp integration', defaults: { name: 'Evolution API Tool', }, inputs: ['main'], outputs: ['main'], credentials: [ { name: 'evolutionApiApi', required: true, }, ], properties: [ { displayName: 'Operation', name: 'operation', type: 'options', noDataExpression: true, options: [ { name: 'Send Message', value: 'sendMessage', description: 'Send a message to a contact', action: 'Send a message to a contact', }, { name: 'Send Media', value: 'sendMedia', description: 'Send media to a contact', action: 'Send media to a contact', }, { name: 'Get QR Code', value: 'getQrCode', description: 'Get QR Code for connection', action: 'Get QR Code for connection', }, ], default: 'sendMessage', }, // Fields for SendMessage operation { displayName: 'Instance', name: 'instance', type: 'string', required: true, default: '', description: 'The name of the WhatsApp instance', displayOptions: { show: { operation: [ 'sendMessage', 'sendMedia', 'getQrCode', ], }, }, }, { displayName: 'Phone Number', name: 'phoneNumber', type: 'string', required: true, default: '', description: 'Phone number with country code', displayOptions: { show: { operation: [ 'sendMessage', 'sendMedia', ], }, }, }, { displayName: 'Message', name: 'message', type: 'string', required: true, default: '', description: 'Message to be sent', displayOptions: { show: { operation: [ 'sendMessage', ], }, }, }, // Fields for SendMedia operation { displayName: 'Media Type', name: 'mediaType', type: 'options', required: true, options: [ { name: 'Image', value: 'image', }, { name: 'Document', value: 'document', }, { name: 'Video', value: 'video', }, { name: 'Audio', value: 'audio', }, ], default: 'image', description: 'Type of media to send', displayOptions: { show: { operation: [ 'sendMedia', ], }, }, }, { displayName: 'Media URL', name: 'mediaUrl', type: 'string', required: true, default: '', description: 'URL of the media to send', displayOptions: { show: { operation: [ 'sendMedia', ], }, }, }, { displayName: 'Caption', name: 'caption', type: 'string', required: false, default: '', description: 'Caption for the media', displayOptions: { show: { operation: [ 'sendMedia', ], }, }, }, ], }; async execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> { const items = this.getInputData(); const returnData: INodeExecutionData[] = []; const credentials = await this.getCredentials('evolutionApiApi'); const baseUrl = credentials.url as string; const apiKey = credentials.apiKey as string; const headers = { 'Content-Type': 'application/json', 'apiKey': apiKey, }; // For each item for (let i = 0; i < items.length; i++) { try { const operation = this.getNodeParameter('operation', i) as string; const instance = this.getNodeParameter('instance', i) as string; let responseData; if (operation === 'sendMessage') { const phoneNumber = this.getNodeParameter('phoneNumber', i) as string; const message = this.getNodeParameter('message', i) as string; const endpoint = `${baseUrl}/message/text/${instance}`; const data = { number: phoneNumber, options: { delay: 1200, }, textMessage: { text: message, }, }; const response = await axios.post(endpoint, data, { headers }); responseData = response.data; } else if (operation === 'sendMedia') { const phoneNumber = this.getNodeParameter('phoneNumber', i) as string; const mediaType = this.getNodeParameter('mediaType', i) as string; const mediaUrl = this.getNodeParameter('mediaUrl', i) as string; const caption = this.getNodeParameter('caption', i) as string; const endpoint = `${baseUrl}/message/media/${instance}`; const data = { number: phoneNumber, options: { delay: 1200, }, mediaMessage: { mediatype: mediaType, media: mediaUrl, caption: caption, }, }; const response = await axios.post(endpoint, data, { headers }); responseData = response.data; } else if (operation === 'getQrCode') { const endpoint = `${baseUrl}/instance/qrcode/${instance}`; const response = await axios.get(endpoint, { headers }); responseData = response.data; } else { throw new NodeOperationError(this.getNode(), `The operation "${operation}" is not supported!`); } // Return the data const executionData = this.helpers.constructExecutionMetaData( this.helpers.returnJsonArray(responseData), { itemData: { item: i } }, ); returnData.push(...executionData); } catch (error) { if (this.continueOnFail()) { const executionData = this.helpers.constructExecutionMetaData( this.helpers.returnJsonArray({ error: error.message }), { itemData: { item: i } }, ); returnData.push(...executionData); continue; } throw error; } } return this.prepareOutputData(returnData); } }