From 1428895d536f97824fbe4d932ed877be49106138 Mon Sep 17 00:00:00 2001 From: Ricardo Espinoza Date: Tue, 28 Jan 2020 13:51:49 -0500 Subject: [PATCH 1/2] :sparkles: Uplead node --- .../credentials/UpleadApi.credentials.ts | 17 +++ .../nodes/Uplead/CompanyDesciption.ts | 65 ++++++++++ .../nodes/Uplead/GenericFunctions.ts | 32 +++++ .../nodes/Uplead/PersonDescription.ts | 99 ++++++++++++++ .../nodes-base/nodes/Uplead/Uplead.node.ts | 121 ++++++++++++++++++ packages/nodes-base/nodes/Uplead/uplead.png | Bin 0 -> 4398 bytes packages/nodes-base/package.json | 2 + 7 files changed, 336 insertions(+) create mode 100644 packages/nodes-base/credentials/UpleadApi.credentials.ts create mode 100644 packages/nodes-base/nodes/Uplead/CompanyDesciption.ts create mode 100644 packages/nodes-base/nodes/Uplead/GenericFunctions.ts create mode 100644 packages/nodes-base/nodes/Uplead/PersonDescription.ts create mode 100644 packages/nodes-base/nodes/Uplead/Uplead.node.ts create mode 100644 packages/nodes-base/nodes/Uplead/uplead.png diff --git a/packages/nodes-base/credentials/UpleadApi.credentials.ts b/packages/nodes-base/credentials/UpleadApi.credentials.ts new file mode 100644 index 0000000000..18c4ca9e38 --- /dev/null +++ b/packages/nodes-base/credentials/UpleadApi.credentials.ts @@ -0,0 +1,17 @@ +import { + ICredentialType, + NodePropertyTypes, +} from 'n8n-workflow'; + +export class UpleadApi implements ICredentialType { + name = 'upleadApi'; + displayName = 'Uplead API'; + properties = [ + { + displayName: 'API Key', + name: 'apiKey', + type: 'string' as NodePropertyTypes, + default: '', + }, + ]; +} diff --git a/packages/nodes-base/nodes/Uplead/CompanyDesciption.ts b/packages/nodes-base/nodes/Uplead/CompanyDesciption.ts new file mode 100644 index 0000000000..39ca13e01a --- /dev/null +++ b/packages/nodes-base/nodes/Uplead/CompanyDesciption.ts @@ -0,0 +1,65 @@ +import { INodeProperties } from 'n8n-workflow'; + +export const companyOperations = [ + { + displayName: 'Operation', + name: 'operation', + type: 'options', + displayOptions: { + show: { + resource: [ + 'company', + ], + }, + }, + options: [ + { + name: 'Enrich', + value: 'enrich', + }, + ], + default: 'enrich', + description: 'The operation to perform.', + }, +] as INodeProperties[]; + +export const companyFields = [ + +/* -------------------------------------------------------------------------- */ +/* company:enrich */ +/* -------------------------------------------------------------------------- */ + { + displayName: 'Company', + name: 'company', + type: 'string', + default: '', + displayOptions: { + show: { + resource: [ + 'company', + ], + operation: [ + 'enrich', + ], + }, + }, + description: 'the name of the company (e.g – amazon)', + }, + { + displayName: 'Domain', + name: 'domain', + type: 'string', + default: '', + displayOptions: { + show: { + resource: [ + 'company', + ], + operation: [ + 'enrich', + ], + }, + }, + description: 'the domain name (e.g – amazon.com)', + }, +] as INodeProperties[]; diff --git a/packages/nodes-base/nodes/Uplead/GenericFunctions.ts b/packages/nodes-base/nodes/Uplead/GenericFunctions.ts new file mode 100644 index 0000000000..ff6d7b481a --- /dev/null +++ b/packages/nodes-base/nodes/Uplead/GenericFunctions.ts @@ -0,0 +1,32 @@ +import { OptionsWithUri } from 'request'; +import { + IExecuteFunctions, + IExecuteSingleFunctions, + IHookFunctions, + ILoadOptionsFunctions, +} from 'n8n-core'; +import { IDataObject } from 'n8n-workflow'; + +export async function upleadApiRequest(this: IHookFunctions | 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('upleadApi'); + if (credentials === undefined) { + throw new Error('No credentials got returned!'); + } + let options: OptionsWithUri = { + headers: { Authorization: credentials.apiKey }, + method, + qs, + body, + uri: uri ||`https://api.uplead.com/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 (err) { + throw new Error(err); + } +} diff --git a/packages/nodes-base/nodes/Uplead/PersonDescription.ts b/packages/nodes-base/nodes/Uplead/PersonDescription.ts new file mode 100644 index 0000000000..769da626d1 --- /dev/null +++ b/packages/nodes-base/nodes/Uplead/PersonDescription.ts @@ -0,0 +1,99 @@ +import { INodeProperties } from 'n8n-workflow'; + +export const personOperations = [ + { + displayName: 'Operation', + name: 'operation', + type: 'options', + displayOptions: { + show: { + resource: [ + 'person', + ], + }, + }, + options: [ + { + name: 'Enrich', + value: 'enrich', + }, + ], + default: 'enrich', + description: 'The operation to perform.', + }, +] as INodeProperties[]; + +export const personFields = [ + +/* -------------------------------------------------------------------------- */ +/* person:enrich */ +/* -------------------------------------------------------------------------- */ + { + displayName: 'Email', + name: 'email', + type: 'string', + default: '', + displayOptions: { + show: { + resource: [ + 'person', + ], + operation: [ + 'enrich', + ], + }, + }, + description: 'email address (e.g – mbenioff@salesforce.com)', + }, + { + displayName: 'Fist Name', + name: 'firstname', + type: 'string', + default: '', + displayOptions: { + show: { + resource: [ + 'person', + ], + operation: [ + 'enrich', + ], + }, + }, + description: 'first name of the person (e.g – Marc)', + }, + { + displayName: 'Last Name', + name: 'lastname', + type: 'string', + default: '', + displayOptions: { + show: { + resource: [ + 'person', + ], + operation: [ + 'enrich', + ], + }, + }, + description: 'Last name of the person (e.g – Benioff)', + }, + { + displayName: 'Domain', + name: 'domain', + type: 'string', + default: '', + displayOptions: { + show: { + resource: [ + 'person', + ], + operation: [ + 'enrich', + ], + }, + }, + description: 'The domain name (e.g – salesforce.com)', + }, +] as INodeProperties[]; diff --git a/packages/nodes-base/nodes/Uplead/Uplead.node.ts b/packages/nodes-base/nodes/Uplead/Uplead.node.ts new file mode 100644 index 0000000000..1ac4fb79bc --- /dev/null +++ b/packages/nodes-base/nodes/Uplead/Uplead.node.ts @@ -0,0 +1,121 @@ +import { + IExecuteFunctions, +} from 'n8n-core'; +import { + IDataObject, + INodeExecutionData, + INodeType, + INodeTypeDescription, +} from 'n8n-workflow'; +import { + upleadApiRequest, +} from './GenericFunctions'; +import { + companyFields, + companyOperations, +} from './CompanyDesciption'; +import { + personOperations, + personFields, +} from './PersonDescription'; + +export class Uplead implements INodeType { + description: INodeTypeDescription = { + displayName: 'Uplead', + name: 'uplead', + icon: 'file:uplead.png', + group: ['output'], + version: 1, + subtitle: '={{$parameter["operation"] + ":" + $parameter["resource"]}}', + description: 'Consume Uplead API', + defaults: { + name: 'Uplead', + color: '#5d6f7b', + }, + inputs: ['main'], + outputs: ['main'], + credentials: [ + { + name: 'upleadApi', + required: true, + } + ], + properties: [ + { + displayName: 'Resource', + name: 'resource', + type: 'options', + options: [ + { + name: 'Company', + value: 'company', + description: 'Company API lets you lookup company data via a domain name or company name.', + }, + { + name: 'Person', + value: 'person', + description: `Person API lets you lookup a person based on an email address OR based on a domain name + first name + last name` + }, + ], + default: 'company', + description: 'Resource to consume.', + }, + ...companyOperations, + ...companyFields, + ...personOperations, + ...personFields, + ], + }; + + async execute(this: IExecuteFunctions): Promise { + const items = this.getInputData(); + const returnData: IDataObject[] = []; + const length = items.length as unknown as number; + const qs: IDataObject = {}; + let responseData; + const resource = this.getNodeParameter('resource', 0) as string; + const operation = this.getNodeParameter('operation', 0) as string; + for (let i = 0; i < length; i++) { + if (resource === 'person') { + if (operation === 'enrich') { + const email = this.getNodeParameter('email', i) as string; + const firstname = this.getNodeParameter('firstname', i) as string; + const lastname = this.getNodeParameter('lastname', i) as string; + const domain = this.getNodeParameter('domain', i) as string; + if (email) { + qs.email = email; + } + if (firstname) { + qs.first_name = firstname; + } + if (lastname) { + qs.last_name = lastname; + } + if (domain) { + qs.domain = domain; + } + responseData = await upleadApiRequest.call(this, 'GET', '/person-search', {}, qs); + } + } + if (resource === 'company') { + if (operation === 'enrich') { + const domain = this.getNodeParameter('domain', i) as string; + const company = this.getNodeParameter('company', i) as string; + if (domain) { + qs.domain = domain; + } + if (company) { + qs.company = company; + } + responseData = await upleadApiRequest.call(this, 'GET', '/company-search', {}, qs); + } + } + 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/Uplead/uplead.png b/packages/nodes-base/nodes/Uplead/uplead.png new file mode 100644 index 0000000000000000000000000000000000000000..8eb61801a7a40c18ed61a82df793ba9cd95bf999 GIT binary patch literal 4398 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 mA-+3~p!nmvP+5WQ1WYlp8ntB;l(=k^7 literal 0 HcmV?d00001 diff --git a/packages/nodes-base/package.json b/packages/nodes-base/package.json index 2c40a4d076..d0ff3791e6 100644 --- a/packages/nodes-base/package.json +++ b/packages/nodes-base/package.json @@ -85,6 +85,7 @@ "dist/credentials/TwilioApi.credentials.js", "dist/credentials/TypeformApi.credentials.js", "dist/credentials/TogglApi.credentials.js", + "dist/credentials/UpleadApi.credentials.js", "dist/credentials/VeroApi.credentials.js", "dist/credentials/WebflowApi.credentials.js", "dist/credentials/WordpressApi.credentials.js", @@ -190,6 +191,7 @@ "dist/nodes/Trello/TrelloTrigger.node.js", "dist/nodes/Twilio/Twilio.node.js", "dist/nodes/Typeform/TypeformTrigger.node.js", + "dist/nodes/Uplead/Uplead.node.js", "dist/nodes/Vero/Vero.node.js", "dist/nodes/Webflow/WebflowTrigger.node.js", "dist/nodes/Webhook.node.js", From d30f809e8d409cdfdbcb878d6344de1ab91bbbdd Mon Sep 17 00:00:00 2001 From: Jan Oberhauser Date: Tue, 28 Jan 2020 21:39:59 -0800 Subject: [PATCH 2/2] :zap: Minor improvement on Uplead-Node --- packages/nodes-base/nodes/Uplead/PersonDescription.ts | 4 ++-- packages/nodes-base/nodes/Uplead/Uplead.node.ts | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/nodes-base/nodes/Uplead/PersonDescription.ts b/packages/nodes-base/nodes/Uplead/PersonDescription.ts index 769da626d1..8e65faa64a 100644 --- a/packages/nodes-base/nodes/Uplead/PersonDescription.ts +++ b/packages/nodes-base/nodes/Uplead/PersonDescription.ts @@ -43,7 +43,7 @@ export const personFields = [ ], }, }, - description: 'email address (e.g – mbenioff@salesforce.com)', + description: 'Email address (e.g – mbenioff@salesforce.com)', }, { displayName: 'Fist Name', @@ -60,7 +60,7 @@ export const personFields = [ ], }, }, - description: 'first name of the person (e.g – Marc)', + description: 'First name of the person (e.g – Marc)', }, { displayName: 'Last Name', diff --git a/packages/nodes-base/nodes/Uplead/Uplead.node.ts b/packages/nodes-base/nodes/Uplead/Uplead.node.ts index 1ac4fb79bc..e47bdbe71c 100644 --- a/packages/nodes-base/nodes/Uplead/Uplead.node.ts +++ b/packages/nodes-base/nodes/Uplead/Uplead.node.ts @@ -110,10 +110,10 @@ export class Uplead implements INodeType { responseData = await upleadApiRequest.call(this, 'GET', '/company-search', {}, qs); } } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); + if (Array.isArray(responseData.data)) { + returnData.push.apply(returnData, responseData.data as IDataObject[]); } else { - returnData.push(responseData as IDataObject); + returnData.push(responseData.data as IDataObject); } } return [this.helpers.returnJsonArray(returnData)];