This commit is contained in:
Ricardo Espinoza 2019-11-14 18:44:07 -05:00
parent a3594ae7a2
commit 451c87d8a9
3 changed files with 458 additions and 7 deletions

View file

@ -3,7 +3,7 @@ import {
NodePropertyTypes,
} from 'n8n-workflow';
export class Mailchimp implements ICredentialType {
export class MailchimpApi implements ICredentialType {
name = 'mailchimpApi';
displayName = 'Mailchimp API';
properties = [

View file

@ -41,3 +41,13 @@ export async function mailchimpApiRequest(this: IHookFunctions | IExecuteFunctio
throw error.response.body;
}
}
export function validateJSON(json: string | undefined): any { // tslint:disable-line:no-any
let result;
try {
result = JSON.parse(json!);
} catch (exception) {
result = '';
}
return result;
}

View file

@ -11,7 +11,38 @@ import {
} from 'n8n-workflow';
import {
mailchimpApiRequest,
validateJSON
} from './GenericFunctions';
import * as moment from 'moment';
enum Status {
subscribe = 'subscribe',
unsubscribed = 'unsubscribe',
cleaned = 'cleaned',
pending = 'pending',
transactional = 'transactional'
}
interface ILocation {
latitude?: number;
longitude?: number;
}
interface ICreateMemberBody {
listId: string;
email_address: string;
email_type?: string;
status?: Status;
language?: string;
vip?: boolean;
location?: ILocation;
ips_signup?: string;
timestamp_signup?: string;
ip_opt?: string;
timestamp_opt?: string;
tags?: string[];
merge_fields?: IDataObject;
}
export class Mailchimp implements INodeType {
@ -67,19 +98,352 @@ export class Mailchimp implements INodeType {
{
name: 'Create',
value: 'create',
description: 'Create a new member',
description: 'Create a new member on list',
},
],
default: '',
description: 'The operation to perform.',
},
{
displayName: 'List',
name: 'list',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getLists',
},
displayOptions: {
show: {
resource: [
'member'
],
operation: [
'create',
],
},
},
default: '',
options: [],
required: true,
description: 'List of lists'
},
{
displayName: 'Email',
name: 'email',
type: 'string',
required: true,
displayOptions: {
show: {
resource: [
'member',
],
operation: [
'create',
],
},
},
default: '',
description: 'Email address for a subscriber.',
},
{
displayName: 'Status',
name: 'status',
type: 'options',
required: true,
displayOptions: {
show: {
resource: [
'member',
],
operation: [
'create',
],
},
},
options: [
{
name: 'Subscribed',
value: 'subscribed',
description: '',
},
{
name: 'Unsubscribed',
value: 'unsubscribed',
description: '',
},
{
name: 'Cleaned',
value: 'cleaned',
description: '',
},
{
name: 'Pending',
value: 'pending',
description: '',
},
{
name: 'Transactional',
value: 'transactional',
description: '',
},
],
default: '',
description: `Subscriber's current status.`,
},
{
displayName: 'JSON Parameters',
name: 'jsonParameters',
type: 'boolean',
default: false,
description: '',
displayOptions: {
show: {
resource:[
'member'
],
operation: [
'create',
],
},
},
},
{
displayName: 'Options',
name: 'options',
type: 'collection',
placeholder: 'Add Option',
default: {},
displayOptions: {
show: {
resource:[
'member'
],
operation: [
'create',
],
},
},
options: [
{
displayName: 'Email Type',
name: 'emailType',
type: 'options',
options: [
{
name: 'Email',
value: 'email',
description: '',
},
{
name: 'Text',
value: 'text',
description: '',
},
],
default: '',
description: 'Type of email this member asked to get',
},
{
displayName: 'Signup IP',
name: 'ipSignup',
type: 'string',
default: '',
description: 'IP address the subscriber signed up from.',
},
{
displayName: 'Opt-in IP',
name: 'ipOptIn',
type: 'string',
default: '',
description: 'The IP address the subscriber used to confirm their opt-in status.',
},
{
displayName: 'Signup Timestamp',
name: 'timestampSignup',
type: 'dateTime',
default: '',
description: 'The date and time the subscriber signed up for the list in ISO 8601 format.',
},
{
displayName: 'Language',
name: 'language',
type: 'string',
default: '',
description: `If set/detected, the subscriber's language.`,
},
{
displayName: 'Vip',
name: 'vip',
type: 'boolean',
default: false,
description: `Vip status for subscribers`,
},
{
displayName: 'Opt-in Timestamp',
name: 'timestampOpt',
type: 'dateTime',
default: '',
description: `The date and time the subscribe confirmed their opt-in status in ISO 8601 format.`,
},
{
displayName: 'Tags',
name: 'tags',
type: 'string',
default: '',
description: `The tags that are associated with a member separeted by ,.`,
},
]
},
{
displayName: 'Location',
name: 'locationFieldsUi',
type: 'fixedCollection',
placeholder: 'Add Location',
default: false,
description: `Subscriber location information.n`,
displayOptions: {
show: {
resource:[
'member'
],
operation: [
'create',
],
jsonParameters: [
false,
],
},
},
options: [
{
name: 'locationFieldsValues',
displayName: 'Location',
values: [
{
displayName: 'Latitude',
name: 'latitude',
type: 'string',
required: true,
description: 'The location latitude.',
default: ''
},
{
displayName: 'Longitude',
name: 'longitude',
type: 'string',
required: true,
description: 'The location longitude.',
default: ''
},
],
}
],
},
{
displayName: 'Merge Fields',
name: 'mergeFieldsUi',
placeholder: 'Add Merge Fields',
type: 'fixedCollection',
default: '',
typeOptions: {
multipleValues: true,
},
displayOptions: {
show: {
resource:[
'member'
],
operation: [
'create',
],
jsonParameters: [
false,
],
},
},
description: 'An individual merge var and value for a member.',
options: [
{
name: 'mergeFieldsValues',
displayName: 'Field',
typeOptions: {
multipleValueButtonText: 'Add Field'
},
values: [
{
displayName: 'Merge Field Name',
name: 'name',
type: 'string',
required: true,
description: 'The tag used in Mailchimp campaigns and for the /members endpoint.',
default: ''
},
{
displayName: 'Merge Field Value',
name: 'value',
required: true,
type: 'string',
default: '',
description: 'The name of the merge field.',
},
],
},
],
},
{
displayName: 'Merge Fields',
name: 'mergeFieldsJson',
type: 'json',
typeOptions: {
alwaysOpenEditWindow: true
},
default: '',
description: '',
displayOptions: {
show: {
resource:[
'member'
],
operation: [
'create',
],
jsonParameters: [
true
],
},
},
},
{
displayName: 'Location',
name: 'locationJson',
type: 'json',
typeOptions: {
alwaysOpenEditWindow: true
},
default: '',
description: '',
displayOptions: {
show: {
resource:[
'member'
],
operation: [
'create',
],
jsonParameters: [
true
],
},
},
},
]
};
methods = {
loadOptions: {
// Get all the available projects to display them to user so that he can
// Get all the available lists to display them to user so that he can
// select them easily
async getLists(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]> {
const returnData: INodePropertyOptions[] = [];
@ -99,19 +463,96 @@ export class Mailchimp implements INodeType {
value: listId,
});
}
return returnData;
},
}
};
async executeSingle(this: IExecuteSingleFunctions): Promise<INodeExecutionData> {
let response = {};
const resource = this.getNodeParameter('resource') as string;
const opeation = this.getNodeParameter('operation') as string;
const operation = this.getNodeParameter('operation') as string;
if (resource === 'member') {
if (operation === 'create') {
const listId = this.getNodeParameter('list') as string;
const email = this.getNodeParameter('email') as string;
const status = this.getNodeParameter('status') as Status;
const options = this.getNodeParameter('options') as IDataObject;
const jsonActive = this.getNodeParameter('jsonParameters') as IDataObject;
const body: ICreateMemberBody = {
listId,
email_address: email,
status
};
if (options.emailType) {
body.email_type = options.emailType as string;
}
if (options.languaje) {
body.language = options.language as string;
}
if (options.vip) {
body.vip = options.vip as boolean;
}
if (options.ipSignup) {
body.ips_signup = options.ipSignup as string;
}
if (options.ipOptIn) {
body.ip_opt = options.ipOptIn as string;
}
if (options.timestampOpt) {
body.timestamp_opt = moment(options.timestampOpt as string).format('YYYY-MM-DD HH:MM:SS') as string;
}
if (options.timestampSignup) {
body.timestamp_signup = moment(options.timestampSignup as string).format('YYYY-MM-DD HH:MM:SS') as string;
}
if (options.tags) {
// @ts-ignore
body.tags = options.tags.split(',') as string[];
}
if (!jsonActive) {
const locationValues = (this.getNodeParameter('locationFieldsUi') as IDataObject).locationFieldsValues as IDataObject;
if (locationValues) {
const location: ILocation = {};
for (const key of Object.keys(locationValues)) {
if (key === 'latitude') {
location.latitude = parseInt(locationValues[key] as string, 10) as number;
} else if (key === 'longitude') {
location.longitude = parseInt(locationValues[key] as string, 10) as number;
}
}
body.location = location;
}
const mergeFieldsValues = (this.getNodeParameter('mergeFieldsUi') as IDataObject).mergeFieldsValues as IDataObject[];
if (mergeFieldsValues) {
const mergeFields = {};
for (let i = 0; i < mergeFieldsValues.length; i++) {
// @ts-ignore
mergeFields[mergeFieldsValues[i].name] = mergeFieldsValues[i].value;
}
body.merge_fields = mergeFields;
}
} else {
const locationJson = validateJSON(this.getNodeParameter('locationJson') as string);
const mergeFieldsJson = validateJSON(this.getNodeParameter('mergeFieldsJson') as string);
if (locationJson) {
body.location = locationJson;
}
if (mergeFieldsJson) {
body.merge_fields = mergeFieldsJson;
}
}
try {
response = await mailchimpApiRequest.call(this, `/lists/${listId}/members`, 'POST', body);
} catch (err) {
throw new Error(`Mailchimp Error: ${JSON.stringify(err)}`);
}
}
}
return {
json: {}
json: response
};
}
}