Some improvements to Customer.io Node

This commit is contained in:
Jan Oberhauser 2020-09-02 12:32:12 +02:00
parent e5a5e1ed11
commit 512fe4ea70
7 changed files with 180 additions and 348 deletions

View file

@ -15,21 +15,21 @@ export class CustomerIoApi implements ICredentialType {
type: 'string' as NodePropertyTypes,
default: '',
description: 'Required for tracking API.',
required: true
required: true,
},
{
displayName: 'Tracking Site ID',
name: 'trackingSiteId',
type: 'string' as NodePropertyTypes,
default: '',
description: 'Required for tracking API.'
description: 'Required for tracking API.',
},
{
displayName: 'App API Key',
name: 'appApiKey',
type: 'string' as NodePropertyTypes,
default: '',
description: 'Required for App API.'
description: 'Required for App API.',
},
];
}

View file

@ -47,7 +47,7 @@ export const campaignFields = [
'campaign',
],
operation: [
'get'
'get',
]
},
},
@ -68,7 +68,7 @@ export const campaignFields = [
'campaign',
],
operation: [
'getMetrics'
'getMetrics',
]
},
},
@ -85,7 +85,7 @@ export const campaignFields = [
'campaign',
],
operation: [
'getMetrics'
'getMetrics',
]
},
},
@ -93,19 +93,19 @@ export const campaignFields = [
options: [
{
name: 'Hours',
value: 'hours'
value: 'hours',
},
{
name: 'Days',
value: 'days'
value: 'days',
},
{
name: 'Weeks',
value: 'weeks'
value: 'weeks',
},
{
name: 'Months',
value: 'months'
value: 'months',
},
]
},
@ -121,7 +121,7 @@ export const campaignFields = [
'campaign',
],
operation: [
'getMetrics'
'getMetrics',
],
},
},
@ -154,7 +154,7 @@ export const campaignFields = [
description: 'Integer specifying how many steps to return. Defaults to the maximum number of timeperiods available, or 12 when using the months period. Maximum timeperiods available are 24 hours, 45 days, 12 weeks and 120 months',
typeOptions: {
minValue: 0,
maxValue: 120
maxValue: 120,
}
},
{
@ -166,31 +166,31 @@ export const campaignFields = [
options: [
{
name: 'Empty',
value: 'empty'
value: 'empty',
},
{
name: 'Email',
value: 'email'
},
{
name: 'Webhook',
value: 'webhook'
},
{
name: 'twilio',
value: 'twilio'
},
{
name: 'Urban Airship',
value: 'urbanAirship'
},
{
name: 'Slack',
value: 'slack'
value: 'email',
},
{
name: 'Push',
value: 'push'
value: 'push',
},
{
name: 'Slack',
value: 'slack',
},
{
name: 'twilio',
value: 'twilio',
},
{
name: 'Urban Airship',
value: 'urbanAirship',
},
{
name: 'Webhook',
value: 'webhook',
},
]
},

View file

@ -14,22 +14,17 @@ export const customerOperations = [
},
options: [
{
name: 'Create',
value: 'create',
description: 'Create a customer.',
name: 'Create/Update',
value: 'upsert',
description: 'Create/Update a customer.',
},
{
name: 'Delete',
value: 'delete',
description: 'Delete a customer.',
},
{
name: 'Update',
value: 'update',
description: 'Update a customer.',
},
],
default: 'create',
default: 'upsert',
description: 'The operation to perform.',
},
] as INodeProperties[];
@ -37,30 +32,35 @@ export const customerOperations = [
export const customerFields = [
/* -------------------------------------------------------------------------- */
/* customer:create/delete */
/* customer:delete */
/* -------------------------------------------------------------------------- */
{
displayName: 'ID',
name: 'id',
type: 'number',
type: 'string',
required: true,
default: 0,
default: '',
displayOptions: {
show: {
resource: [
'customer',
],
operation: [
'create', 'delete'
'delete',
]
},
},
description: 'The unique identifier for the customer.',
},
/* -------------------------------------------------------------------------- */
/* customer:upsert */
/* -------------------------------------------------------------------------- */
{
displayName: 'Email',
name: 'email',
displayName: 'ID',
name: 'id',
type: 'string',
required: true,
default: '',
displayOptions: {
show: {
@ -68,28 +68,11 @@ export const customerFields = [
'customer',
],
operation: [
'create'
'upsert',
]
},
},
description: 'The email address of the user.',
},
{
displayName: 'Created at',
name: 'createdAt',
type: 'dateTime',
default: '',
displayOptions: {
show: {
resource: [
'customer',
],
operation: [
'create'
]
},
},
description: 'The UNIX timestamp from when the user was created.',
description: 'The unique identifier for the customer.',
},
{
displayName: 'JSON Parameters',
@ -103,7 +86,7 @@ export const customerFields = [
'customer',
],
operation: [
'create'
'upsert',
],
},
},
@ -122,7 +105,7 @@ export const customerFields = [
'customer',
],
operation: [
'create'
'upsert',
],
jsonParameters: [
true,
@ -143,7 +126,7 @@ export const customerFields = [
'customer',
],
operation: [
'create'
'upsert',
],
jsonParameters: [
false,
@ -171,7 +154,7 @@ export const customerFields = [
required: true,
default: '',
description: 'Property name.',
placeholder: 'Plan'
placeholder: 'Plan',
},
{
@ -181,127 +164,7 @@ export const customerFields = [
required: true,
default: '',
description: 'Property value.',
placeholder: 'Basic'
},
],
},
]
},
],
},
/* -------------------------------------------------------------------------- */
/* customer:update */
/* -------------------------------------------------------------------------- */
{
displayName: 'ID',
name: 'id',
type: 'number',
required: true,
default: 0,
displayOptions: {
show: {
resource: [
'customer',
],
operation: [
'update'
]
},
},
description: 'The unique identifier for the customer.',
},
{
displayName: 'JSON Parameters',
name: 'jsonParameters',
type: 'boolean',
default: false,
description: '',
displayOptions: {
show: {
resource: [
'customer',
],
operation: [
'update'
],
},
},
},
{
displayName: ' Additional Fields',
name: 'additionalFieldsJson',
type: 'json',
typeOptions: {
alwaysOpenEditWindow: true,
},
default: '',
displayOptions: {
show: {
resource: [
'customer',
],
operation: [
'update'
],
jsonParameters: [
true,
],
},
},
description: 'Object of values to set as described <a href="https://github.com/agilecrm/rest-api#1-companys---companies-api" target="_blank">here</a>.',
},
{
displayName: 'Additional Fields',
name: 'additionalFields',
type: 'collection',
placeholder: 'Add Field',
default: {},
displayOptions: {
show: {
resource: [
'customer',
],
operation: [
'update'
],
jsonParameters: [
false,
],
},
},
options: [
{
displayName: 'Custom Properties',
name: 'customProperties',
type: 'fixedCollection',
description: 'Custom Properties',
typeOptions: {
multipleValues: true,
},
options: [
{
displayName: 'Property',
name: 'customProperty',
values: [
{
displayName: 'Key',
name: 'key',
type: 'string',
required: true,
default: '',
description: 'Property name.',
placeholder: 'Plan'
},
{
displayName: 'Value',
name: 'value',
type: 'string',
required: true,
default: '',
description: 'Property value.',
placeholder: 'Basic'
placeholder: 'Basic',
},
],
},

View file

@ -6,21 +6,18 @@ import {
INodeTypeDescription,
INodeExecutionData,
INodeType,
ILoadOptionsFunctions,
INodePropertyOptions,
} from 'n8n-workflow';
import { customerIoApiRequest, validateJSON } from './GenericFunctions';
import { campaignOperations, campaignFields } from './CampaignDescription';
import { customerOperations, customerFields } from './CustomerDescription';
import { eventOperations, eventFields } from './EventDescription';
import { segmentOperations, segmentFields } from './SegmentDescription';
import { DateTime } from '../DateTime.node';
export class CustomerIo implements INodeType {
description: INodeTypeDescription = {
displayName: 'Customer.io',
name: 'customerio',
name: 'customerIo',
icon: 'file:customerio.png',
group: ['output'],
version: 1,
@ -82,11 +79,11 @@ export class CustomerIo implements INodeType {
async execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {
const returnData: IDataObject[] = [];
const items = this.getInputData();
let responseData;
const resource = this.getNodeParameter('resource', 0) as string;
const operation = this.getNodeParameter('operation', 0) as string;
const body: IDataObject = {};
let responseData;
for (let i = 0; i < items.length; i++) {
if (resource === 'campaign') {
@ -95,6 +92,7 @@ export class CustomerIo implements INodeType {
const endpoint = `/campaigns/${campaignId}`;
responseData = await customerIoApiRequest.call(this, 'GET', endpoint, body, 'beta');
responseData = responseData.campaign;
}
if (operation === 'getAll') {
@ -147,48 +145,8 @@ export class CustomerIo implements INodeType {
}
if (resource === 'customer') {
if (operation === 'create') {
const id = this.getNodeParameter('id', i) as number;
const email = this.getNodeParameter('email', i) as string;
const createdAt = this.getNodeParameter('createdAt', i) as string;
const jsonParameters = this.getNodeParameter('jsonParameters', i) as boolean;
body.email = email;
body.created_at = new Date(createdAt).getTime() / 1000;
if (jsonParameters) {
const additionalFieldsJson = this.getNodeParameter('additionalFieldsJson', i) as string;
if (additionalFieldsJson !== '') {
if (validateJSON(additionalFieldsJson) !== undefined) {
Object.assign(body, JSON.parse(additionalFieldsJson));
} else {
throw new Error('Additional fields must be a valid JSON');
}
}
} else {
const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject;
if (additionalFields.customProperties) {
const data : any = {};
//@ts-ignore
additionalFields.customProperties.customProperty.map(property => {
data[property.key] = property.value;
});
body.data = data;
}
}
const endpoint = `/customers/${id}`;
responseData = await customerIoApiRequest.call(this, 'PUT', endpoint, body, 'tracking');
}
if (operation === 'update') {
if (operation === 'upsert') {
const id = this.getNodeParameter('id', i) as number;
const jsonParameters = this.getNodeParameter('jsonParameters', i) as boolean;
@ -209,7 +167,7 @@ export class CustomerIo implements INodeType {
const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject;
if (additionalFields.customProperties) {
const data : any = {};
const data: any = {}; // tslint:disable-line:no-any
//@ts-ignore
additionalFields.customProperties.customProperty.map(property => {
data[property.key] = property.value;
@ -230,6 +188,8 @@ export class CustomerIo implements INodeType {
const endpoint = `/customers/${id}`;
responseData = await customerIoApiRequest.call(this, 'PUT', endpoint, body, 'tracking');
responseData = Object.assign({ id }, body);
}
if (operation === 'delete') {
@ -239,17 +199,21 @@ export class CustomerIo implements INodeType {
const endpoint = `/customers/${id}`;
responseData = await customerIoApiRequest.call(this, 'DELETE', endpoint, body, 'tracking');
await customerIoApiRequest.call(this, 'DELETE', endpoint, body, 'tracking');
responseData = {
success: true,
};
}
}
if (resource === 'event') {
if (operation === 'track') {
const id = this.getNodeParameter('id', i) as number;
const name = this.getNodeParameter('name', i) as string;
const customerId = this.getNodeParameter('customerId', i) as number;
const eventName = this.getNodeParameter('eventName', i) as string;
const jsonParameters = this.getNodeParameter('jsonParameters', i) as boolean;
body.name = name;
body.name = eventName;
if (jsonParameters) {
const additionalFieldsJson = this.getNodeParameter('additionalFieldsJson', i) as string;
@ -257,16 +221,14 @@ export class CustomerIo implements INodeType {
if (additionalFieldsJson !== '') {
if (validateJSON(additionalFieldsJson) !== undefined) {
Object.assign(body, JSON.parse(additionalFieldsJson));
} else {
throw new Error('Additional fields must be a valid JSON');
}
}
} else {
const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject;
const data : any = {};
const data: any = {}; // tslint:disable-line:no-any
if (additionalFields.customAttributes) {
//@ts-ignore
@ -282,16 +244,19 @@ export class CustomerIo implements INodeType {
body.data = data;
}
const endpoint = `/customers/${id}/events`;
const endpoint = `/customers/${customerId}/events`;
responseData = await customerIoApiRequest.call(this, 'POST', endpoint, body, 'tracking');
await customerIoApiRequest.call(this, 'POST', endpoint, body, 'tracking');
responseData = {
success: true,
};
}
if (operation === 'trackAnonymous') {
const name = this.getNodeParameter('name', i) as string;
const eventName = this.getNodeParameter('eventName', i) as string;
const jsonParameters = this.getNodeParameter('jsonParameters', i) as boolean;
body.name = name;
body.name = eventName;
if (jsonParameters) {
const additionalFieldsJson = this.getNodeParameter('additionalFieldsJson', i) as string;
@ -308,7 +273,7 @@ export class CustomerIo implements INodeType {
}
} else {
const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject;
const data : any = {};
const data: any = {}; // tslint:disable-line:no-any
if (additionalFields.customAttributes) {
//@ts-ignore
@ -320,31 +285,34 @@ export class CustomerIo implements INodeType {
}
const endpoint = `/events`;
responseData = await customerIoApiRequest.call(this, 'POST', endpoint, body, 'tracking');
await customerIoApiRequest.call(this, 'POST', endpoint, body, 'tracking');
responseData = {
success: true,
};
}
}
if (resource === 'segment') {
const id = this.getNodeParameter('id', i) as number;
const ids = this.getNodeParameter('ids', i) as string;
const idArray : string[] = [];
const segmentId = this.getNodeParameter('segmentId', i) as number;
const customerIds = this.getNodeParameter('customerIds', i) as string;
ids.split(',').map(id => {
idArray.push(id);
});
body.id = segmentId;
body.ids = customerIds.split(',');
body.id = id;
body.ids = idArray;
let endpoint = ``;
let endpoint = '';
if (operation === 'add') {
endpoint = `/segments/${id}/add_customers`;
endpoint = `/segments/${segmentId}/add_customers`;
} else {
endpoint = `/segments/${id}/remove_customers`;
endpoint = `/segments/${segmentId}/remove_customers`;
}
responseData = await customerIoApiRequest.call(this, 'POST', endpoint, body, 'tracking');
responseData = {
success: true,
};
}
if (Array.isArray(responseData)) {

View file

@ -35,26 +35,26 @@ export const eventFields = [
/* event:track */
/* -------------------------------------------------------------------------- */
{
displayName: 'ID',
name: 'id',
type: 'number',
displayName: 'Customer ID',
name: 'customerId',
type: 'string',
required: true,
default: 0,
default: '',
displayOptions: {
show: {
resource: [
'event',
],
operation: [
'track'
'track',
]
},
},
description: 'The unique identifier for the customer.',
},
{
displayName: 'Name',
name: 'name',
displayName: 'Event Name',
name: 'eventName',
type: 'string',
default: '',
displayOptions: {
@ -63,7 +63,7 @@ export const eventFields = [
'event',
],
operation: [
'track'
'track',
]
},
},
@ -81,7 +81,7 @@ export const eventFields = [
'event',
],
operation: [
'track'
'track',
],
},
},
@ -100,7 +100,7 @@ export const eventFields = [
'event',
],
operation: [
'track'
'track',
],
jsonParameters: [
true,
@ -121,10 +121,10 @@ export const eventFields = [
'event',
],
operation: [
'track'
'track',
],
jsonParameters: [
false
false,
]
},
},
@ -149,7 +149,7 @@ export const eventFields = [
required: true,
default: '',
description: 'Attribute name.',
placeholder: 'Price'
placeholder: 'Price',
},
{
@ -159,7 +159,7 @@ export const eventFields = [
required: true,
default: '',
description: 'Attribute value.',
placeholder: '25.50'
placeholder: '25.50',
},
],
},
@ -178,8 +178,8 @@ export const eventFields = [
/* event:track anonymous */
/* -------------------------------------------------------------------------- */
{
displayName: 'Name',
name: 'name',
displayName: 'Event Name',
name: 'eventName',
type: 'string',
required: true,
default: '',
@ -189,7 +189,7 @@ export const eventFields = [
'event',
],
operation: [
'trackAnonymous'
'trackAnonymous',
]
},
},
@ -207,7 +207,7 @@ export const eventFields = [
'event',
],
operation: [
'trackAnonymous'
'trackAnonymous',
],
},
},
@ -226,7 +226,7 @@ export const eventFields = [
'event',
],
operation: [
'trackAnonymous'
'trackAnonymous',
],
jsonParameters: [
true,
@ -247,10 +247,10 @@ export const eventFields = [
'event',
],
operation: [
'trackAnonymous'
'trackAnonymous',
],
jsonParameters: [
false
false,
]
},
},
@ -275,9 +275,8 @@ export const eventFields = [
required: true,
default: '',
description: 'Attribute name.',
placeholder: 'Price'
placeholder: 'Price',
},
{
displayName: 'Value',
name: 'value',
@ -285,7 +284,7 @@ export const eventFields = [
required: true,
default: '',
description: 'Attribute value.',
placeholder: '25.50'
placeholder: '25.50',
},
],
},

View file

@ -33,8 +33,8 @@ export const segmentFields = [
/* segment:add */
/* -------------------------------------------------------------------------- */
{
displayName: 'ID',
name: 'id',
displayName: 'Segment ID',
name: 'segmentId',
type: 'number',
required: true,
default: 0,
@ -44,15 +44,16 @@ export const segmentFields = [
'segment',
],
operation: [
'add', 'remove'
'add',
'remove',
]
},
},
description: 'The unique identifier of the segment.',
},
{
displayName: 'IDs',
name: 'ids',
displayName: 'Customer IDs',
name: 'customerIds',
type: 'string',
required: true,
default: '',
@ -62,7 +63,8 @@ export const segmentFields = [
'segment',
],
operation: [
'add', 'remove'
'add',
'remove',
]
},
},