From 83eaaf1e33663f9b110bed03e2008449e7230e21 Mon Sep 17 00:00:00 2001 From: Ricardo Espinoza Date: Tue, 17 Dec 2019 15:33:28 -0500 Subject: [PATCH] :sparkles: Vero node done --- .../credentials/VeroApi.credentials.ts | 18 + .../nodes-base/nodes/Vero/EventDescripion.ts | 245 ++++++++++++ .../nodes-base/nodes/Vero/GenericFunctions.ts | 50 +++ .../nodes-base/nodes/Vero/UserDescription.ts | 376 ++++++++++++++++++ packages/nodes-base/nodes/Vero/Vero.node.ts | 232 +++++++++++ packages/nodes-base/nodes/Vero/vero.png | Bin 0 -> 4069 bytes packages/nodes-base/package.json | 4 +- 7 files changed, 924 insertions(+), 1 deletion(-) create mode 100644 packages/nodes-base/credentials/VeroApi.credentials.ts create mode 100644 packages/nodes-base/nodes/Vero/EventDescripion.ts create mode 100644 packages/nodes-base/nodes/Vero/GenericFunctions.ts create mode 100644 packages/nodes-base/nodes/Vero/UserDescription.ts create mode 100644 packages/nodes-base/nodes/Vero/Vero.node.ts create mode 100644 packages/nodes-base/nodes/Vero/vero.png diff --git a/packages/nodes-base/credentials/VeroApi.credentials.ts b/packages/nodes-base/credentials/VeroApi.credentials.ts new file mode 100644 index 0000000000..340224fc44 --- /dev/null +++ b/packages/nodes-base/credentials/VeroApi.credentials.ts @@ -0,0 +1,18 @@ +import { + ICredentialType, + NodePropertyTypes, +} from 'n8n-workflow'; + + +export class VeroApi implements ICredentialType { + name = 'veroApi'; + displayName = 'Vero API'; + properties = [ + { + displayName: 'Auth Token', + name: 'authToken', + type: 'string' as NodePropertyTypes, + default: '', + }, + ]; +} diff --git a/packages/nodes-base/nodes/Vero/EventDescripion.ts b/packages/nodes-base/nodes/Vero/EventDescripion.ts new file mode 100644 index 0000000000..8df87fd072 --- /dev/null +++ b/packages/nodes-base/nodes/Vero/EventDescripion.ts @@ -0,0 +1,245 @@ +import { INodeProperties } from 'n8n-workflow'; + +export const eventOperations = [ + { + displayName: 'Operation', + name: 'operation', + type: 'options', + displayOptions: { + show: { + resource: [ + 'event', + ], + }, + }, + options: [ + { + name: 'Track', + value: 'track', + description: `This endpoint tracks an event for a specific customer. + If the customer profile doesn’t exist, Vero will create it.`, + }, + ], + default: 'track', + description: 'The operation to perform.', + }, +] as INodeProperties[]; + +export const eventFields = [ + +/* -------------------------------------------------------------------------- */ +/* event:track */ +/* -------------------------------------------------------------------------- */ + + { + displayName: 'ID', + name: 'id', + type: 'string', + required: true, + default: '', + displayOptions: { + show: { + resource: [ + 'event', + ], + operation: [ + 'track', + ] + }, + }, + description: 'The unique identifier of the customer', + }, + { + displayName: 'Email', + name: 'email', + type: 'string', + default: '', + required: true, + displayOptions: { + show: { + resource: [ + 'event', + ], + operation: [ + 'track', + ] + }, + }, + description: 'Email', + }, + { + displayName: 'Event Name', + name: 'eventName', + type: 'string', + default: '', + required: true, + displayOptions: { + show: { + resource: [ + 'event', + ], + operation: [ + 'track', + ] + }, + }, + description: 'The name of the event tracked.', + }, + { + displayName: 'JSON Parameters', + name: 'jsonParameters', + type: 'boolean', + default: false, + description: '', + displayOptions: { + show: { + resource: [ + 'event', + ], + operation: [ + 'track', + ] + }, + } + }, + { + displayName: 'Data', + name: 'dataAttributesUi', + placeholder: 'Add Data', + description: 'key value pairs that represent any properties you want to track with this event', + type: 'fixedCollection', + typeOptions: { + multipleValues: true, + }, + default: {}, + displayOptions: { + show: { + resource: [ + 'event', + ], + operation: [ + 'track', + ], + jsonParameters: [ + false + ], + }, + }, + options: [ + { + name: 'dataAttributesValues', + displayName: 'Data', + values: [ + { + displayName: 'Key', + name: 'key', + type: 'string', + default: '', + description: 'Name of the property to set.', + }, + { + displayName: 'Value', + name: 'value', + type: 'string', + default: '', + description: 'Value of the property to set.', + }, + ] + }, + ], + }, + { + displayName: 'Extra', + name: 'extraAttributesUi', + placeholder: 'Add Extra', + description: 'Key value pairs that represent reserved, Vero-specific operators. Refer to the note on “deduplication” below.', + type: 'fixedCollection', + typeOptions: { + multipleValues: true, + }, + default: {}, + displayOptions: { + show: { + resource: [ + 'event', + ], + operation: [ + 'track', + ], + jsonParameters: [ + false + ], + }, + }, + options: [ + { + name: 'extraAttributesValues', + displayName: 'Extra', + values: [ + { + displayName: 'Key', + name: 'key', + type: 'string', + default: '', + description: 'Name of the property to set.', + }, + { + displayName: 'Value', + name: 'value', + type: 'string', + default: '', + description: 'Value of the property to set.', + }, + ] + }, + ], + }, + { + displayName: 'Data', + name: 'dataAttributesJson', + type: 'json', + default: '', + required: false, + typeOptions: { + alwaysOpenEditWindow: true, + }, + description: 'key value pairs that represent the custom user properties you want to update', + displayOptions: { + show: { + resource: [ + 'event', + ], + operation: [ + 'track', + ], + jsonParameters: [ + true, + ], + }, + }, + }, + { + displayName: 'Extra', + name: 'extraAttributesJson', + type: 'json', + default: '', + required: false, + typeOptions: { + alwaysOpenEditWindow: true, + }, + description: 'Key value pairs that represent reserved, Vero-specific operators. Refer to the note on “deduplication” below.', + displayOptions: { + show: { + resource: [ + 'event', + ], + operation: [ + 'track', + ], + jsonParameters: [ + true, + ], + }, + }, + }, +] as INodeProperties[]; diff --git a/packages/nodes-base/nodes/Vero/GenericFunctions.ts b/packages/nodes-base/nodes/Vero/GenericFunctions.ts new file mode 100644 index 0000000000..2e5053fb7e --- /dev/null +++ b/packages/nodes-base/nodes/Vero/GenericFunctions.ts @@ -0,0 +1,50 @@ +import { OptionsWithUri } from 'request'; +import { + IExecuteFunctions, + ILoadOptionsFunctions, + IExecuteSingleFunctions, +} from 'n8n-core'; +import { IDataObject } from 'n8n-workflow'; + +export async function veroApiRequest(this: IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions, method: string, resource: string, body: any = {}, qs: IDataObject = {}, uri?: string, option: IDataObject = {}): Promise { // tslint:disable-line:no-any + const credentials = this.getCredentials('veroApi'); + if (credentials === undefined) { + throw new Error('No credentials got returned!'); + } + + let options: OptionsWithUri = { + method, + qs, + body, + form: { + auth_token: credentials.authToken, + ...body, + }, + uri: uri ||`https://api.getvero.com/api/v2${resource}`, + json: true + }; + options = Object.assign({}, options, option); + if (Object.keys(options.body).length === 0) { + delete options.body; + } + try { + return await this.helpers.request!(options); + } catch (error) { + let errorMessage = error.message; + if (error.response.body) { + errorMessage = error.response.body.message || error.response.body.Message || error.message; + } + + throw new Error(errorMessage); + } +} + +export function validateJSON(json: string | undefined): any { // tslint:disable-line:no-any + let result; + try { + result = JSON.parse(json!); + } catch (exception) { + result = undefined; + } + return result; +} diff --git a/packages/nodes-base/nodes/Vero/UserDescription.ts b/packages/nodes-base/nodes/Vero/UserDescription.ts new file mode 100644 index 0000000000..f90cb49a8c --- /dev/null +++ b/packages/nodes-base/nodes/Vero/UserDescription.ts @@ -0,0 +1,376 @@ +import { INodeProperties } from 'n8n-workflow'; + +export const userOperations = [ + { + displayName: 'Operation', + name: 'operation', + type: 'options', + displayOptions: { + show: { + resource: [ + 'user', + ], + }, + }, + options: [ + { + name: 'Create/Update', + value: 'create', + description: `Creates a new user profile if the user doesn’t exist yet. + Otherwise, the user profile is updated based on the properties provided.`, + }, + { + name: 'Alias', + value: 'alias', + description: 'Changes a user’s identifier.', + }, + { + name: 'Unsubscribe', + value: 'unsubscribe', + description: 'Unsubscribes a single user.', + }, + { + name: 'Re-subscribe', + value: 'resubscribe', + description: 'Resubscribe a single user.', + }, + { + name: 'Delete', + value: 'delete', + description: 'Delete a single user.', + }, + { + name: 'Add Tags', + value: 'addTags', + description: 'Adds a tag to a user’s profile.', + }, + { + name: 'Remove Tags', + value: 'removeTags', + description: 'Removes a tag from a user’s profile.', + }, + ], + default: 'create', + description: 'The operation to perform.', + }, +] as INodeProperties[]; + +export const userFields = [ + +/* -------------------------------------------------------------------------- */ +/* user:create */ +/* -------------------------------------------------------------------------- */ + + { + displayName: 'ID', + name: 'id', + type: 'string', + required: true, + default: '', + displayOptions: { + show: { + resource: [ + 'user', + ], + operation: [ + 'create', + ] + }, + }, + description: 'The unique identifier of the customer', + }, + { + displayName: 'JSON Parameters', + name: 'jsonParameters', + type: 'boolean', + default: false, + description: '', + displayOptions: { + show: { + resource: [ + 'user', + ], + operation: [ + 'create', + ] + }, + } + }, + { + displayName: 'Additional Fields', + name: 'additionalFields', + type: 'collection', + placeholder: 'Add Field', + default: {}, + displayOptions: { + show: { + resource: [ + 'user', + ], + operation: [ + 'create', + ], + }, + }, + options: [ + { + displayName: 'Email', + name: 'email', + type: 'string', + default: '', + description: 'The table to create the row in.', + }, + ] + }, + { + displayName: 'Data', + name: 'dataAttributesUi', + placeholder: 'Add Data', + description: 'key value pairs that represent the custom user properties you want to update', + type: 'fixedCollection', + typeOptions: { + multipleValues: true, + }, + default: {}, + displayOptions: { + show: { + resource: [ + 'user', + ], + operation: [ + 'create', + ], + jsonParameters: [ + false + ], + }, + }, + options: [ + { + name: 'dataAttributesValues', + displayName: 'Data', + values: [ + { + displayName: 'Key', + name: 'key', + type: 'string', + default: '', + description: 'Name of the property to set.', + }, + { + displayName: 'Value', + name: 'value', + type: 'string', + default: '', + description: 'Value of the property to set.', + }, + ] + }, + ], + }, + { + displayName: 'Data', + name: 'dataAttributesJson', + type: 'json', + default: '', + required: false, + typeOptions: { + alwaysOpenEditWindow: true, + }, + description: 'key value pairs that represent the custom user properties you want to update', + displayOptions: { + show: { + resource: [ + 'user', + ], + operation: [ + 'create', + ], + jsonParameters: [ + true, + ], + }, + }, + }, + +/* -------------------------------------------------------------------------- */ +/* user:alias */ +/* -------------------------------------------------------------------------- */ + { + displayName: 'ID', + name: 'id', + type: 'string', + required: true, + default: '', + displayOptions: { + show: { + resource: [ + 'user', + ], + operation: [ + 'alias', + ] + }, + }, + description: 'The old unique identifier of the user', + }, + { + displayName: 'New ID', + name: 'newId', + type: 'string', + required: true, + default: '', + displayOptions: { + show: { + resource: [ + 'user', + ], + operation: [ + 'alias', + ] + }, + }, + description: 'The new unique identifier of the user', + }, +/* -------------------------------------------------------------------------- */ +/* user:unsubscribe */ +/* -------------------------------------------------------------------------- */ + { + displayName: 'ID', + name: 'id', + type: 'string', + required: true, + default: '', + displayOptions: { + show: { + resource: [ + 'user', + ], + operation: [ + 'unsubscribe', + ] + }, + }, + description: 'The unique identifier of the user', + }, +/* -------------------------------------------------------------------------- */ +/* user:resubscribe */ +/* -------------------------------------------------------------------------- */ + { + displayName: 'ID', + name: 'id', + type: 'string', + required: true, + default: '', + displayOptions: { + show: { + resource: [ + 'user', + ], + operation: [ + 'resubscribe', + ] + }, + }, + description: 'The unique identifier of the user', + }, +/* -------------------------------------------------------------------------- */ +/* user:delete */ +/* -------------------------------------------------------------------------- */ + { + displayName: 'ID', + name: 'id', + type: 'string', + required: true, + default: '', + displayOptions: { + show: { + resource: [ + 'user', + ], + operation: [ + 'delete', + ] + }, + }, + description: 'The unique identifier of the user', + }, +/* -------------------------------------------------------------------------- */ +/* user:addTags */ +/* -------------------------------------------------------------------------- */ + { + displayName: 'ID', + name: 'id', + type: 'string', + required: true, + default: '', + displayOptions: { + show: { + resource: [ + 'user', + ], + operation: [ + 'addTags', + ] + }, + }, + description: 'The unique identifier of the user', + }, + { + displayName: 'Tags', + name: 'tags', + type: 'string', + required: true, + default: '', + displayOptions: { + show: { + resource: [ + 'user', + ], + operation: [ + 'addTags', + ] + }, + }, + description: 'Tags to add separated by ,', + }, +/* -------------------------------------------------------------------------- */ +/* user:removeTags */ +/* -------------------------------------------------------------------------- */ + { + displayName: 'ID', + name: 'id', + type: 'string', + required: true, + default: '', + displayOptions: { + show: { + resource: [ + 'user', + ], + operation: [ + 'removeTags', + ] + }, + }, + description: 'The unique identifier of the user', + }, + { + displayName: 'Tags', + name: 'tags', + type: 'string', + required: true, + default: '', + displayOptions: { + show: { + resource: [ + 'user', + ], + operation: [ + 'removeTags', + ] + }, + }, + description: 'Tags to remove separated by ,', + }, +] as INodeProperties[]; diff --git a/packages/nodes-base/nodes/Vero/Vero.node.ts b/packages/nodes-base/nodes/Vero/Vero.node.ts new file mode 100644 index 0000000000..d17fbef375 --- /dev/null +++ b/packages/nodes-base/nodes/Vero/Vero.node.ts @@ -0,0 +1,232 @@ +import { + IExecuteFunctions, +} from 'n8n-core'; +import { + IDataObject, + INodeTypeDescription, + INodeExecutionData, + INodeType, +} from 'n8n-workflow'; +import { + veroApiRequest, + validateJSON, +} from './GenericFunctions'; +import { + userOperations, + userFields, +} from './UserDescription'; +import { + eventOperations, + eventFields +} from './EventDescripion'; + +export class Vero implements INodeType { + description: INodeTypeDescription = { + displayName: 'Vero', + name: 'Vero', + icon: 'file:vero.png', + group: ['output'], + version: 1, + subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}', + description: 'Consume Vero API', + defaults: { + name: 'Vero', + color: '#c02428', + }, + inputs: ['main'], + outputs: ['main'], + credentials: [ + { + name: 'veroApi', + required: true, + } + ], + properties: [ + { + displayName: 'Resource', + name: 'resource', + type: 'options', + options: [ + { + name: 'User', + value: 'user', + description: `Lets you create, update and manage the subscription status of your users.`, + }, + { + name: 'Event', + value: 'event', + description: `Lets you track events based on actions your customers take in real time.`, + }, + ], + default: 'user', + description: 'Resource to consume.', + }, + ...userOperations, + ...eventOperations, + ...userFields, + ...eventFields, + ], + }; + + async execute(this: IExecuteFunctions): Promise { + const items = this.getInputData(); + const returnData: IDataObject[] = []; + const length = items.length as unknown as number; + let responseData; + for (let i = 0; i < length; i++) { + const resource = this.getNodeParameter('resource', 0) as string; + const operation = this.getNodeParameter('operation', 0) as string; + //https://developers.getvero.com/?bash#users + if (resource === 'user') { + //https://developers.getvero.com/?bash#users-identify + if (operation === 'create') { + const id = this.getNodeParameter('id', i) as string; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const jsonActive = this.getNodeParameter('jsonParameters', i) as boolean; + const body = { + id, + }; + if (additionalFields.email) { + // @ts-ignore + body.email = additionalFields.email as string; + } + if (!jsonActive) { + const dataAttributesValues = (this.getNodeParameter('dataAttributesUi', i) as IDataObject).dataAttributesValues as IDataObject[]; + if (dataAttributesValues) { + const dataAttributes = {}; + for (let i = 0; i < dataAttributesValues.length; i++) { + // @ts-ignore + dataAttributes[dataAttributesValues[i].key] = dataAttributesValues[i].value; + // @ts-ignore + body.data = dataAttributes; + } + } + } else { + const dataAttributesJson = validateJSON(this.getNodeParameter('dataAttributesJson', i) as string); + if (dataAttributesJson) { + // @ts-ignore + body.data = dataAttributesJson; + } + } + try { + responseData = await veroApiRequest.call(this, 'POST', '/users/track', body); + } catch (err) { + throw new Error(`Vero Error: ${err}`); + } + } + //https://developers.getvero.com/?bash#users-alias + if (operation === 'alias') { + const id = this.getNodeParameter('id', i) as string; + const newId = this.getNodeParameter('newId', i) as string; + const body = { + id, + new_id: newId, + }; + try { + responseData = await veroApiRequest.call(this, 'PUT', '/users/reidentify', body); + } catch (err) { + throw new Error(`Vero Error: ${err}`); + } + } + //https://developers.getvero.com/?bash#users-unsubscribe + //https://developers.getvero.com/?bash#users-resubscribe + //https://developers.getvero.com/?bash#users-delete + if (operation === 'unsubscribe' || + operation === 'resubscribe' || + operation === 'delete') { + const id = this.getNodeParameter('id', i) as string; + const body = { + id, + }; + try { + responseData = await veroApiRequest.call(this, 'POST', `/users/${operation}`, body); + } catch (err) { + throw new Error(`Vero Error: ${err}`); + } + } + //https://developers.getvero.com/?bash#tags-add + //https://developers.getvero.com/?bash#tags-remove + if (operation === 'addTags' || + operation === 'removeTags') { + const id = this.getNodeParameter('id', i) as string; + const tags = (this.getNodeParameter('tags', i) as string).split(',') as string[]; + const body = { + id, + }; + if (operation === 'addTags') { + // @ts-ignore + body.add = JSON.stringify(tags); + } + if (operation === 'removeTags') { + // @ts-ignore + body.remove = JSON.stringify(tags); + } + try { + responseData = await veroApiRequest.call(this, 'PUT', '/users/tags/edit', body); + } catch (err) { + throw new Error(`Vero Error: ${err}`); + } + } + } + //https://developers.getvero.com/?bash#events + if (resource === 'event') { + //https://developers.getvero.com/?bash#events-track + if (operation === 'track') { + const id = this.getNodeParameter('id', i) as string; + const email = this.getNodeParameter('email', i) as string; + const eventName = this.getNodeParameter('eventName', i) as string; + const jsonActive = this.getNodeParameter('jsonParameters', i) as boolean; + const body = { + identity: { id, email }, + event_name: eventName, + email, + }; + if (!jsonActive) { + const dataAttributesValues = (this.getNodeParameter('dataAttributesUi', i) as IDataObject).dataAttributesValues as IDataObject[]; + if (dataAttributesValues) { + const dataAttributes = {}; + for (let i = 0; i < dataAttributesValues.length; i++) { + // @ts-ignore + dataAttributes[dataAttributesValues[i].key] = dataAttributesValues[i].value; + // @ts-ignore + body.data = JSON.stringify(dataAttributes); + } + } + const extraAttributesValues = (this.getNodeParameter('extraAttributesUi', i) as IDataObject).extraAttributesValues as IDataObject[]; + if (extraAttributesValues) { + const extraAttributes = {}; + for (let i = 0; i < extraAttributesValues.length; i++) { + // @ts-ignore + extraAttributes[extraAttributesValues[i].key] = extraAttributesValues[i].value; + // @ts-ignore + body.extras = JSON.stringify(extraAttributes); + } + } + } else { + const dataAttributesJson = validateJSON(this.getNodeParameter('dataAttributesJson', i) as string); + if (dataAttributesJson) { + // @ts-ignore + body.data = JSON.stringify(dataAttributesJson); + } + const extraAttributesJson = validateJSON(this.getNodeParameter('extraAttributesJson', i) as string); + if (extraAttributesJson) { + // @ts-ignore + body.extras = JSON.stringify(extraAttributesJson); + } + } + try { + responseData = await veroApiRequest.call(this, 'POST', '/events/track', body); + } catch (err) { + throw new Error(`Vero Error: ${err}`); + } + } + } + if (Array.isArray(responseData)) { + returnData.push.apply(returnData, responseData as IDataObject[]); + } else { + returnData.push(responseData as IDataObject); + } + } + return [this.helpers.returnJsonArray(returnData)]; + } +} diff --git a/packages/nodes-base/nodes/Vero/vero.png b/packages/nodes-base/nodes/Vero/vero.png new file mode 100644 index 0000000000000000000000000000000000000000..bddebcf31b8e6aeed4176cad5ebe224829778423 GIT binary patch literal 4069 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 Obh?^IjWTun;Qs)EuV)$n literal 0 HcmV?d00001 diff --git a/packages/nodes-base/package.json b/packages/nodes-base/package.json index 5afa6b431c..f10dc78186 100644 --- a/packages/nodes-base/package.json +++ b/packages/nodes-base/package.json @@ -72,7 +72,8 @@ "dist/credentials/TypeformApi.credentials.js", "dist/credentials/MandrillApi.credentials.js", "dist/credentials/TodoistApi.credentials.js", - "dist/credentials/TypeformApi.credentials.js" + "dist/credentials/TypeformApi.credentials.js", + "dist/credentials/VeroApi.credentials.js" ], "nodes": [ "dist/nodes/ActiveCampaign/ActiveCampaign.node.js", @@ -153,6 +154,7 @@ "dist/nodes/Trello/TrelloTrigger.node.js", "dist/nodes/Twilio/Twilio.node.js", "dist/nodes/Typeform/TypeformTrigger.node.js", + "dist/nodes/Vero/Vero.node.js", "dist/nodes/WriteBinaryFile.node.js", "dist/nodes/Webhook.node.js", "dist/nodes/Xml.node.js",