diff --git a/packages/nodes-base/nodes/Mailjet/EmailDescription.ts b/packages/nodes-base/nodes/Mailjet/EmailDescription.ts index 7039757192..56f8982dcb 100644 --- a/packages/nodes-base/nodes/Mailjet/EmailDescription.ts +++ b/packages/nodes-base/nodes/Mailjet/EmailDescription.ts @@ -31,9 +31,9 @@ export const emailOperations = [ export const emailFields = [ -/* -------------------------------------------------------------------------- */ -/* email:send */ -/* -------------------------------------------------------------------------- */ + /* -------------------------------------------------------------------------- */ + /* email:send */ + /* -------------------------------------------------------------------------- */ { displayName: 'From Email', name: 'fromEmail', @@ -162,11 +162,18 @@ export const emailFields = [ type: 'number', default: 2, }, + { + displayName: 'Reply To', + name: 'replyTo', + type: 'string', + description: 'The reply-to email address. Multiple ones can be separated by comma.', + default: '', + }, { displayName: 'Template Language', name: 'templateLanguage', type: 'boolean', - default: true, + default: false, }, { displayName: 'Track Clicks', @@ -258,9 +265,9 @@ export const emailFields = [ }, ], }, -/* -------------------------------------------------------------------------- */ -/* email:sendTemplate */ -/* -------------------------------------------------------------------------- */ + /* -------------------------------------------------------------------------- */ + /* email:sendTemplate */ + /* -------------------------------------------------------------------------- */ { displayName: 'From Email', name: 'fromEmail', @@ -301,7 +308,10 @@ export const emailFields = [ { displayName: 'Template ID', name: 'templateId', - type: 'string', + type: 'options', + typeOptions: { + loadOptionsMethod: 'getTemplates', + }, required: true, default: '', displayOptions: { @@ -336,7 +346,7 @@ export const emailFields = [ displayName: 'Bcc Email', name: 'bccEmail', type: 'string', - description: 'Bcc Recipients of the email separated by ,.', + description: 'BCC Recipients of the email separated by ,.', default: '', }, { @@ -358,6 +368,13 @@ export const emailFields = [ type: 'number', default: 2, }, + { + displayName: 'Reply To', + name: 'replyTo', + type: 'string', + description: 'The reply-to email address. Multiple ones can be separated by comma.', + default: '', + }, { displayName: 'Subject', name: 'subject', @@ -382,7 +399,7 @@ export const emailFields = [ displayName: 'Template Language', name: 'templateLanguage', type: 'boolean', - default: true, + default: false, }, ], }, diff --git a/packages/nodes-base/nodes/Mailjet/GenericFunctions.ts b/packages/nodes-base/nodes/Mailjet/GenericFunctions.ts index 6f101a1619..fba2c896ce 100644 --- a/packages/nodes-base/nodes/Mailjet/GenericFunctions.ts +++ b/packages/nodes-base/nodes/Mailjet/GenericFunctions.ts @@ -1,10 +1,18 @@ -import { OptionsWithUri } from 'request'; +import { + OptionsWithUri, +} from 'request'; + import { IExecuteFunctions, IExecuteSingleFunctions, ILoadOptionsFunctions, } from 'n8n-core'; -import { IDataObject, IHookFunctions, NodeApiError } from 'n8n-workflow'; + +import { + IDataObject, + IHookFunctions, + NodeApiError, +} from 'n8n-workflow'; export async function mailjetApiRequest(this: IExecuteFunctions | IExecuteSingleFunctions | IHookFunctions | ILoadOptionsFunctions, method: string, resource: string, body: any = {}, qs: IDataObject = {}, uri?: string, option: IDataObject = {}): Promise { // tslint:disable-line:no-any const emailApiCredentials = this.getCredentials('mailjetEmailApi'); @@ -16,7 +24,7 @@ export async function mailjetApiRequest(this: IExecuteFunctions | IExecuteSingle method, qs, body, - uri: uri ||`https://api.mailjet.com${resource}`, + uri: uri || `https://api.mailjet.com${resource}`, json: true, }; options = Object.assign({}, options, option); @@ -25,12 +33,10 @@ export async function mailjetApiRequest(this: IExecuteFunctions | IExecuteSingle } if (emailApiCredentials !== undefined) { const base64Credentials = Buffer.from(`${emailApiCredentials.apiKey}:${emailApiCredentials.secretKey}`).toString('base64'); - //@ts-ignore - options.headers['Authorization'] = `Basic ${base64Credentials}`; + options.headers!['Authorization'] = `Basic ${base64Credentials}`; } else { const smsApiCredentials = this.getCredentials('mailjetSmsApi'); - //@ts-ignore - options.headers['Authorization'] = `Bearer ${smsApiCredentials.token}`; + options.headers!['Authorization'] = `Bearer ${smsApiCredentials!.token}`; } try { return await this.helpers.request!(options); @@ -57,3 +63,20 @@ export async function mailjetApiRequestAllItems(this: IExecuteFunctions | IHookF ); return returnData; } + +export interface IMessage { + From?: { Email?: string, Name?: string }; + Subject?: string; + To?: IDataObject[]; + Cc?: IDataObject[]; + Bcc?: IDataObject[]; + Variables?: IDataObject; + TemplateLanguage?: boolean; + TemplateID?: number; + HTMLPart?: string; + TextPart?: string; + TrackOpens?: string; + ReplyTo?: IDataObject; + TrackClicks?: string; + Priority?: number; +} diff --git a/packages/nodes-base/nodes/Mailjet/Mailjet.node.ts b/packages/nodes-base/nodes/Mailjet/Mailjet.node.ts index a30d7ada15..5e85b47848 100644 --- a/packages/nodes-base/nodes/Mailjet/Mailjet.node.ts +++ b/packages/nodes-base/nodes/Mailjet/Mailjet.node.ts @@ -1,19 +1,26 @@ import { IExecuteFunctions, } from 'n8n-core'; + import { IDataObject, + ILoadOptionsFunctions, INodeExecutionData, + INodePropertyOptions, INodeType, INodeTypeDescription, } from 'n8n-workflow'; + import { + IMessage, mailjetApiRequest, } from './GenericFunctions'; + import { emailFields, emailOperations, } from './EmailDescription'; + import { smsFields, smsOperations, @@ -23,7 +30,7 @@ export class Mailjet implements INodeType { description: INodeTypeDescription = { displayName: 'Mailjet', name: 'mailjet', - icon: 'file:mailjet.png', + icon: 'file:mailjet.svg', group: ['output'], version: 1, subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}', @@ -83,6 +90,24 @@ export class Mailjet implements INodeType { ], }; + methods = { + loadOptions: { + // Get all the available custom fields to display them to user so that he can + // select them easily + async getTemplates(this: ILoadOptionsFunctions): Promise { + const returnData: INodePropertyOptions[] = []; + const { Data: templates } = await mailjetApiRequest.call(this, 'GET', '/v3/REST/template'); + for (const template of templates) { + returnData.push({ + name: template.Name, + value: template.ID, + }); + } + return returnData; + }, + }, + }; + async execute(this: IExecuteFunctions): Promise { const items = this.getInputData(); const returnData: IDataObject[] = []; @@ -103,80 +128,71 @@ export class Mailjet implements INodeType { const toEmail = (this.getNodeParameter('toEmail', i) as string).split(',') as string[]; const variables = (this.getNodeParameter('variablesUi', i) as IDataObject).variablesValues as IDataObject[]; - const body: IDataObject = { - Messages: [ - { - From: { - email: fromEmail, - }, - subject, - to: [], - Cc: [], - Bcc: [], - Variables: {}, - }, - ], - //SandboxMode: true, + const body: IMessage = { + From: { + Email: fromEmail, + }, + Subject: subject, + To: [], + Cc: [], + Bcc: [], + Variables: {}, }; + for (const email of toEmail) { - //@ts-ignore - body.Messages[0].to.push({ - email, + body.To?.push({ + Email: email, }); } if (variables) { for (const variable of variables) { - //@ts-ignore - body.Messages[0].Variables[variable.name] = variable.value; + body.Variables![variable.name as string] = variable.value; } } if (htmlBody) { - //@ts-ignore - body.Messages[0].HTMLPart = htmlBody; + body.HTMLPart = htmlBody; } if (textBody) { - //@ts-ignore - body.Messages[0].TextPart = textBody; + body.TextPart = textBody; } if (additionalFields.bccEmail) { const bccEmail = (additionalFields.bccEmail as string).split(',') as string[]; for (const email of bccEmail) { - //@ts-ignore - body.Messages[0].Bcc.push({ - email, + body.Bcc!.push({ + Email: email, }); } } - if (additionalFields.ccEmail) { - const ccEmail = (additionalFields.ccEmail as string).split(',') as string[]; + if (additionalFields.ccAddresses) { + const ccEmail = (additionalFields.ccAddresses as string).split(',') as string[]; for (const email of ccEmail) { - //@ts-ignore - body.Messages[0].Cc.push({ - email, + body.Cc!.push({ + Email: email, }); } } if (additionalFields.trackOpens) { - //@ts-ignore - body.Messages[0].TrackOpens = additionalFields.trackOpens as string; + body.TrackOpens = additionalFields.trackOpens as string; + } + if (additionalFields.replyTo) { + const replyTo = additionalFields.replyTo as string; + body['ReplyTo'] = { + Email: replyTo, + }; } if (additionalFields.trackClicks) { - //@ts-ignore - body.Messages[0].TrackClicks = additionalFields.trackClicks as string; + body.TrackClicks = additionalFields.trackClicks as string; } if (additionalFields.fromName) { - //@ts-ignore - body.Messages[0].From.name = additionalFields.fromName as string; + body.From!.Name = additionalFields.fromName as string; } if (additionalFields.templateLanguage) { - //@ts-ignore - body.Messages[0].From.TemplateLanguage = additionalFields.templateLanguage as boolean; + body.TemplateLanguage = additionalFields.templateLanguage as boolean; } if (additionalFields.priority) { - //@ts-ignore - body.Messages[0].Priority = additionalFields.priority as number; + body.Priority = additionalFields.priority as number; } - responseData = await mailjetApiRequest.call(this, 'POST', '/v3.1/send', body); + responseData = await mailjetApiRequest.call(this, 'POST', '/v3.1/send', { Messages: [body] }); responseData = responseData.Messages; } @@ -189,73 +205,66 @@ export class Mailjet implements INodeType { const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; const toEmail = (this.getNodeParameter('toEmail', i) as string).split(',') as string[]; - const body: IDataObject = { - Messages: [ - { - From: { - email: fromEmail, - }, - Subject: subject, - to: [], - Cc: [], - Bcc: [], - Variables: {}, - TemplateID: templateId, - }, - ], - //SandboxMode: true, + const body: IMessage = { + From: { + Email: fromEmail, + }, + Subject: subject, + To: [], + Cc: [], + Bcc: [], + Variables: {}, + TemplateID: templateId, }; + for (const email of toEmail) { - //@ts-ignore - body.Messages[0].to.push({ - email, + body.To!.push({ + Email: email, }); } if (variables) { for (const variable of variables) { - //@ts-ignore - body.Messages[0].Variables[variable.name] = variable.value; + body.Variables![variable.name as string] = variable.value; } } if (additionalFields.bccEmail) { const bccEmail = (additionalFields.bccEmail as string).split(',') as string[]; for (const email of bccEmail) { - //@ts-ignore - body.Messages[0].Bcc.push({ - email, + body.Bcc!.push({ + Email: email, }); } } if (additionalFields.ccEmail) { const ccEmail = (additionalFields.ccEmail as string).split(',') as string[]; for (const email of ccEmail) { - //@ts-ignore - body.Messages[0].Cc.push({ - email, + body.Cc!.push({ + Email: email, }); } } + if (additionalFields.replyTo) { + const replyTo = additionalFields.replyTo as string; + body['ReplyTo'] = { + Email: replyTo, + }; + } if (additionalFields.trackOpens) { - //@ts-ignore - body.Messages[0].TrackOpens = additionalFields.trackOpens as string; + body.TrackOpens = additionalFields.trackOpens as string; } if (additionalFields.trackClicks) { - //@ts-ignore - body.Messages[0].TrackClicks = additionalFields.trackClicks as string; + body.TrackClicks = additionalFields.trackClicks as string; } if (additionalFields.fromName) { - //@ts-ignore - body.Messages[0].From.name = additionalFields.fromName as string; + body.From!.Name = additionalFields.fromName as string; } if (additionalFields.templateLanguage) { - //@ts-ignore - body.Messages[0].From.TemplateLanguage = additionalFields.templateLanguage as boolean; + body.TemplateLanguage = additionalFields.templateLanguage as boolean; } if (additionalFields.priority) { - //@ts-ignore - body.Messages[0].Priority = additionalFields.priority as number; + body.Priority = additionalFields.priority as number; } - responseData = await mailjetApiRequest.call(this, 'POST', '/v3.1/send', body); + responseData = await mailjetApiRequest.call(this, 'POST', '/v3.1/send', { Messages: [body] }); responseData = responseData.Messages; } } diff --git a/packages/nodes-base/nodes/Mailjet/MailjetTrigger.node.ts b/packages/nodes-base/nodes/Mailjet/MailjetTrigger.node.ts index f25b39b0b7..8e71b0833a 100644 --- a/packages/nodes-base/nodes/Mailjet/MailjetTrigger.node.ts +++ b/packages/nodes-base/nodes/Mailjet/MailjetTrigger.node.ts @@ -18,7 +18,7 @@ export class MailjetTrigger implements INodeType { description: INodeTypeDescription = { displayName: 'Mailjet Trigger', name: 'mailjetTrigger', - icon: 'file:mailjet.png', + icon: 'file:mailjet.svg', group: ['trigger'], version: 1, description: 'Handle Mailjet events via webhooks', diff --git a/packages/nodes-base/nodes/Mailjet/mailjet.png b/packages/nodes-base/nodes/Mailjet/mailjet.png deleted file mode 100644 index 88c3f71cc9..0000000000 Binary files a/packages/nodes-base/nodes/Mailjet/mailjet.png and /dev/null differ diff --git a/packages/nodes-base/nodes/Mailjet/mailjet.svg b/packages/nodes-base/nodes/Mailjet/mailjet.svg new file mode 100644 index 0000000000..0d9badd5ca --- /dev/null +++ b/packages/nodes-base/nodes/Mailjet/mailjet.svg @@ -0,0 +1 @@ + \ No newline at end of file