diff --git a/packages/nodes-base/nodes/Mailchimp/GenericFunctions.ts b/packages/nodes-base/nodes/Mailchimp/GenericFunctions.ts index 442e6ac011..8310ca3dda 100644 --- a/packages/nodes-base/nodes/Mailchimp/GenericFunctions.ts +++ b/packages/nodes-base/nodes/Mailchimp/GenericFunctions.ts @@ -49,6 +49,7 @@ export async function mailchimpApiRequest(this: IHookFunctions | IExecuteFunctio const datacenter = (credentials.apiKey as string).split('-').pop(); options.url = `https://${datacenter}.${host}${endpoint}`; + return await this.helpers.request!(options); } else { const credentials = this.getCredentials('mailchimpOAuth2Api') as IDataObject; @@ -110,3 +111,63 @@ function getMetadata(this: IHookFunctions | IExecuteFunctions | IExecuteSingleFu }; return this.helpers.request!(options); } + +export const campaignFieldsMetadata = [ + '*', + 'campaigns.id', + 'campaigns.web_id', + 'campaigns.type', + 'campaigns.create_time', + 'campaigns.archive_url', + 'campaigns.long_archive_url', + 'campaigns.status', + 'campaigns.emails_sent', + 'campaigns.send_time', + 'campaigns.content_type', + 'campaigns.needs_block_refresh', + 'campaigns.resendable', + 'campaigns.recipients', + 'campaigns.recipients.list_id', + 'campaigns.recipients.list_is_active', + 'campaigns.recipients.list_name', + 'campaigns.recipients.segment_text', + 'campaigns.recipients.recipient_count', + 'campaigns.settings', + 'campaigns.settings.subject_line', + 'campaigns.settings.preview_text', + 'campaigns.settings.title', + 'campaigns.settings.from_name', + 'campaigns.settings.reply_to', + 'campaigns.settings.use_conversation', + 'campaigns.settings.to_name', + 'campaigns.settings.folder_id', + 'campaigns.settings.authenticate', + 'campaigns.settings.auto_footer', + 'campaigns.settings.inline_css', + 'campaigns.settings.auto_tweet', + 'campaigns.settings.fb_comments', + 'campaigns.settings.timewarp', + 'campaigns.settings.template_id', + 'campaigns.settings.drag_and_drop', + 'campaigns.tracking', + 'campaigns.tracking.opens', + 'campaigns.tracking.html_clicks', + 'campaigns.tracking.text_clicks', + 'campaigns.tracking.goal_tracking', + 'campaigns.tracking.ecomm360', + 'campaigns.tracking.google_analytics', + 'campaigns.tracking.clicktale', + 'campaigns.report_summary', + 'campaigns.report_summary.opens', + 'campaigns.report_summary.unique_opens', + 'campaigns.report_summary.open_rate', + 'campaigns.report_summary.clicks', + 'campaigns.report_summary.subscriber_clicks', + 'campaigns.report_summary.click_rate', + 'campaigns.report_summary.click_rate.ecommerce', + 'campaigns.report_summary.click_rate.ecommerce.total_orders', + 'campaigns.report_summary.click_rate.ecommerce.total_spent', + 'campaigns.report_summary.click_rate.ecommerce.total_revenue', + 'campaigns.report_summary.delivery_status.enabled', + 'campaigns._links', +]; diff --git a/packages/nodes-base/nodes/Mailchimp/Mailchimp.node.ts b/packages/nodes-base/nodes/Mailchimp/Mailchimp.node.ts index ff5ee63645..892a06cc0d 100644 --- a/packages/nodes-base/nodes/Mailchimp/Mailchimp.node.ts +++ b/packages/nodes-base/nodes/Mailchimp/Mailchimp.node.ts @@ -13,6 +13,7 @@ import { } from 'n8n-workflow'; import { + campaignFieldsMetadata, mailchimpApiRequest, mailchimpApiRequestAllItems, validateJSON, @@ -113,6 +114,10 @@ export class Mailchimp implements INodeType { name: 'resource', type: 'options', options: [ + { + name: 'Campaign', + value: 'campaign' + }, { name: 'List Group', value: 'listGroup', @@ -221,6 +226,54 @@ export class Mailchimp implements INodeType { default: 'getAll', description: 'The operation to perform.', }, + { + displayName: 'Operation', + name: 'operation', + type:'options', + required: true, + displayOptions : { + show: { + resource: [ + 'campaign', + ], + }, + + }, + options: [ + { + name: 'Delete', + value: 'delete', + description: 'Delete a campaign' + }, + { + name: 'Get', + value: 'get', + description: 'Get a campaign' + }, + { + name: 'Get All', + value: 'getAll', + description: 'Get all the campaigns' + }, + { + name: 'Replicate', + value: 'replicate', + description: 'Replicate a campaign' + }, + { + name: 'Resend', + value: 'resend', + description: 'Creates a Resend to Non-Openers version of this campaign' + }, + { + name: 'Send', + value: 'send', + description: 'Send a campaign' + }, + ], + default: 'getAll', + description: 'The operation to perform.' + }, /* -------------------------------------------------------------------------- */ /* member:create */ /* -------------------------------------------------------------------------- */ @@ -1500,6 +1553,219 @@ export class Mailchimp implements INodeType { default: 500, description: 'How many results to return.', }, +/* -------------------------------------------------------------------------- */ +/* campaign:getAll */ +/* -------------------------------------------------------------------------- */ + { + displayName: 'Return All', + name: 'returnAll', + type: 'boolean', + displayOptions: { + show: { + resource: [ + 'campaign', + ], + operation: [ + 'getAll', + ], + }, + }, + default: false, + description: 'If all results should be returned or only up to a given limit.', + }, + { + displayName: 'Limit', + name: 'limit', + type: 'number', + displayOptions: { + show: { + resource: [ + 'campaign', + ], + operation: [ + 'getAll', + ], + returnAll: [ + false, + ], + }, + }, + typeOptions: { + minValue: 1, + maxValue: 1000, + }, + default: 10, + description: 'How many results to return.', + }, + { + displayName: 'Options', + name: 'options', + type: 'collection', + placeholder: 'Add Option', + default: {}, + displayOptions: { + show: { + resource:[ + 'campaign', + ], + operation: [ + 'getAll', + ], + }, + }, + options: [ + { + displayName: 'Before Create Time', + name: 'beforeCreateTime', + type: 'dateTime', + default: '', + description: 'Restrict the response to campaigns created before the set time.', + }, + { + displayName: 'Before Send Time', + name: 'beforeSendTime', + type: 'dateTime', + default: '', + description: 'Restrict the response to campaigns sent before the set time.', + }, + { + displayName: 'Exclude Fields', + name: 'excludeFields', + type: 'multiOptions', + typeOptions: { + loadOptionsMethod: 'getCampaignsFields', + }, + default: [], + description: 'A comma-separated list of fields to exclude.', + }, + { + displayName: 'Fields', + name: 'fields', + type: 'multiOptions', + typeOptions: { + loadOptionsMethod: 'getCampaignsFields', + }, + default: [ + 'campaigns.id', + 'campaigns.status', + 'campaigns.tracking', + 'campaigns.settings.from_name', + 'campaigns.settings.reply_to', + 'campaigns.settings.title', + ], + description: 'A comma-separated list of fields to return.', + }, + { + displayName: 'List ID', + name: 'listId', + type: 'options', + typeOptions: { + loadOptionsMethod: 'getLists', + }, + default: '', + description: 'List of lists' + }, + { + displayName: 'Since Create Time', + name: 'sinceCreateTime', + type: 'dateTime', + default: '', + description: 'Restrict the response to campaigns created after the set time.', + }, + { + displayName: 'Since Send Time', + name: 'sinceSendTime', + type: 'dateTime', + default: '', + description: 'Restrict the response to campaigns sent after the set time.', + }, + { + displayName: 'Sort Direction', + name: 'sortDirection', + type: 'options', + options: [ + { + name: 'ASC', + value: 'ASC', + }, + { + name: 'DESC', + value: 'DESC', + }, + ], + default: '', + description: 'Determines the order direction for sorted results.', + }, + { + displayName: 'Sort Field', + name: 'sortField', + type: 'options', + options: [ + { + name: 'Create Time', + value: 'create_time', + }, + { + name: 'Send Time', + value: 'send_time', + }, + ], + default: '', + description: 'Returns files sorted by the specified field.', + }, + { + displayName: 'Status', + name: 'status', + type: 'options', + options: [ + { + name: 'Save', + value: 'save', + }, + { + name: 'Sending', + value: 'sending', + }, + { + name: 'Sent', + value: 'sent', + }, + { + name: 'Schedule', + value: 'schedule', + }, + ], + default: '', + description: 'The status of the campaign.', + }, + ], + }, +/* -------------------------------------------------------------------------- */ +/* campaign:send */ +/* -------------------------------------------------------------------------- */ + { + displayName: 'Campaign ID', + name: 'campaignId', + type: 'string', + displayOptions: { + show: { + resource: [ + 'campaign' + ], + operation: [ + 'send', + 'get', + 'delete', + 'replicate', + 'resend' + ] + } + }, + required: true, + default: '', + description: 'List of Campaigns', + options:[], + }, ], }; @@ -1556,7 +1822,34 @@ export class Mailchimp implements INodeType { } return returnData; }, - } + + // Get all the available campaigns to display them to users so that they can select them easily + async getCampaigns(this: ILoadOptionsFunctions): Promise { + const returnData: INodePropertyOptions[] = []; + const campaigns = await mailchimpApiRequestAllItems.call(this, '/campaigns', 'GET', 'campaigns'); + for (const campaign of campaigns) { + const campaignName = campaign.settings.title; + const campaignId = campaign.id; + returnData.push({ + name: campaignName, + value: campaignId, + }); + } + return returnData; + }, + + // Get all the available fields to display them to users so that they can select them easily + async getCampaignsFields(this: ILoadOptionsFunctions): Promise { + const returnData: INodePropertyOptions[] = []; + for (const campaignFields of campaignFieldsMetadata) { + returnData.push({ + name: campaignFields, + value: campaignFields, + }); + } + return returnData; + } + }, }; async execute(this: IExecuteFunctions): Promise { @@ -1884,6 +2177,90 @@ export class Mailchimp implements INodeType { responseData = { success: true }; } } + if (resource === 'campaign') { + //https://mailchimp.com/developer/api/marketing/campaigns/list-campaigns/ + if (operation === 'getAll') { + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + const options = this.getNodeParameter('options', i) as IDataObject; + if (options.status) { + qs.status = options.status as string; + } + if (options.beforeCreateTime) { + qs.before_create_time = options.beforeCreateTime as string; + } + if (options.beforeSendTime) { + qs.before_send_time = options.beforeSendTime as string; + } + if (options.excludeFields) { + qs.exclude_fields = (options.exclude_fields as string[]).join(','); + } + if (options.fields) { + qs.fields = (options.fields as string[]).join(','); + if ((options.fields as string[]).includes('*')) { + qs.fields = campaignFieldsMetadata.join(','); + } + } else { + qs.fields = [ + 'campaigns.id', + 'campaigns.status', + 'campaigns.tracking', + 'campaigns.settings.from_name', + 'campaigns.settings.title', + 'campaigns.settings.reply_to', + ].join(','); + } + + if (options.listId) { + qs.list_id = options.listId as string; + } + if (options.sinceCreateTime) { + qs.since_create_time = options.sinceCreateTime as string; + } + if (options.sinceSendTime) { + qs.since_send_time = options.sinceSendTime as string; + } + if (options.sortDirection) { + qs.sort_dir = options.sortDirection as string; + } + if (options.sortField) { + qs.sort_field = options.sortField as string; + } + if (returnAll === true) { + responseData = await mailchimpApiRequestAllItems.call(this, `/campaigns`, 'GET', 'campaigns', {}, qs); + } else { + qs.count = this.getNodeParameter('limit', i) as number; + responseData = await mailchimpApiRequest.call(this, `/campaigns`, 'GET', {}, qs); + responseData = responseData.campaigns; + } + } + //https://mailchimp.com/developer/api/marketing/campaigns/send-campaign/ + if (operation === 'send') { + const campaignId = this.getNodeParameter('campaignId', i) as string; + responseData = await mailchimpApiRequest.call(this, `/campaigns/${campaignId}/actions/send`, 'POST', {}); + responseData = { success: true }; + } + //https://mailchimp.com/developer/api/marketing/campaigns/get-campaign-info/ + if (operation === 'get') { + const campaignId = this.getNodeParameter('campaignId', i) as string; + responseData = await mailchimpApiRequest.call(this, `/campaigns/${campaignId}`, 'GET', {}); + } + //https://mailchimp.com/developer/api/marketing/campaigns/delete-campaign/ + if (operation === 'delete') { + const campaignId = this.getNodeParameter('campaignId', i) as string; + responseData = await mailchimpApiRequest.call(this, `/campaigns/${campaignId}`, 'DELETE', {}); + responseData = { success: true }; + } + //https://mailchimp.com/developer/api/marketing/campaigns/replicate-campaign/ + if (operation === 'replicate') { + const campaignId = this.getNodeParameter('campaignId', i) as string; + responseData = await mailchimpApiRequest.call(this, `/campaigns/${campaignId}/actions/replicate`, 'POST', {}); + } + //https://mailchimp.com/developer/api/marketing/campaigns/resend-campaign/ + if (operation === 'resend') { + const campaignId = this.getNodeParameter('campaignId', i) as string; + responseData = await mailchimpApiRequest.call(this, `/campaigns/${campaignId}/actions/create-resend`, 'POST', {}); + } + } if (Array.isArray(responseData)) { returnData.push.apply(returnData, responseData as IDataObject[]);