Feature/mailchimp (#1017)

*  Add Campaign Resource with get all and send operation

*  Add Campaign Resource with get all and send operation

* 🚧 Add Get and Delete operation

*  Add Campaign resource to the mailchimp node

*  Improvements to #1015

*  Small improvement

Co-authored-by: Harshil <ghagrawal17@gmail.com>
This commit is contained in:
Jan 2020-10-08 09:36:32 +02:00 committed by GitHub
commit 98486902fb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 439 additions and 1 deletions

View file

@ -49,6 +49,7 @@ export async function mailchimpApiRequest(this: IHookFunctions | IExecuteFunctio
const datacenter = (credentials.apiKey as string).split('-').pop(); const datacenter = (credentials.apiKey as string).split('-').pop();
options.url = `https://${datacenter}.${host}${endpoint}`; options.url = `https://${datacenter}.${host}${endpoint}`;
return await this.helpers.request!(options); return await this.helpers.request!(options);
} else { } else {
const credentials = this.getCredentials('mailchimpOAuth2Api') as IDataObject; const credentials = this.getCredentials('mailchimpOAuth2Api') as IDataObject;
@ -110,3 +111,63 @@ function getMetadata(this: IHookFunctions | IExecuteFunctions | IExecuteSingleFu
}; };
return this.helpers.request!(options); 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',
];

View file

@ -13,6 +13,7 @@ import {
} from 'n8n-workflow'; } from 'n8n-workflow';
import { import {
campaignFieldsMetadata,
mailchimpApiRequest, mailchimpApiRequest,
mailchimpApiRequestAllItems, mailchimpApiRequestAllItems,
validateJSON, validateJSON,
@ -113,6 +114,10 @@ export class Mailchimp implements INodeType {
name: 'resource', name: 'resource',
type: 'options', type: 'options',
options: [ options: [
{
name: 'Campaign',
value: 'campaign'
},
{ {
name: 'List Group', name: 'List Group',
value: 'listGroup', value: 'listGroup',
@ -221,6 +226,54 @@ export class Mailchimp implements INodeType {
default: 'getAll', default: 'getAll',
description: 'The operation to perform.', 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 */ /* member:create */
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
@ -1500,6 +1553,219 @@ export class Mailchimp implements INodeType {
default: 500, default: 500,
description: 'How many results to return.', 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; return returnData;
}, },
// Get all the available campaigns to display them to users so that they can select them easily
async getCampaigns(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]> {
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<INodePropertyOptions[]> {
const returnData: INodePropertyOptions[] = [];
for (const campaignFields of campaignFieldsMetadata) {
returnData.push({
name: campaignFields,
value: campaignFields,
});
}
return returnData;
}
},
}; };
async execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> { async execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {
@ -1884,6 +2177,90 @@ export class Mailchimp implements INodeType {
responseData = { success: true }; 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)) { if (Array.isArray(responseData)) {
returnData.push.apply(returnData, responseData as IDataObject[]); returnData.push.apply(returnData, responseData as IDataObject[]);