diff --git a/packages/nodes-base/credentials/ClearbitApi.credentials.ts b/packages/nodes-base/credentials/ClearbitApi.credentials.ts
new file mode 100644
index 0000000000..26432c2286
--- /dev/null
+++ b/packages/nodes-base/credentials/ClearbitApi.credentials.ts
@@ -0,0 +1,17 @@
+import {
+ ICredentialType,
+ NodePropertyTypes,
+} from 'n8n-workflow';
+
+export class ClearbitApi implements ICredentialType {
+ name = 'clearbitApi';
+ displayName = 'Clearbit API';
+ properties = [
+ {
+ displayName: 'API Key',
+ name: 'apiKey',
+ type: 'string' as NodePropertyTypes,
+ default: '',
+ },
+ ];
+}
diff --git a/packages/nodes-base/nodes/Clearbit/Clearbit.node.ts b/packages/nodes-base/nodes/Clearbit/Clearbit.node.ts
new file mode 100644
index 0000000000..e589f17621
--- /dev/null
+++ b/packages/nodes-base/nodes/Clearbit/Clearbit.node.ts
@@ -0,0 +1,154 @@
+import {
+ IExecuteFunctions,
+} from 'n8n-core';
+import {
+ IDataObject,
+ INodeExecutionData,
+ INodeType,
+ INodeTypeDescription,
+} from 'n8n-workflow';
+import {
+ clearbitApiRequest,
+} from './GenericFunctions';
+import {
+ companyFields,
+ companyOperations,
+} from './CompanyDescription';
+import {
+ personOperations,
+ personFields,
+} from './PersonDescription';
+
+export class Clearbit implements INodeType {
+ description: INodeTypeDescription = {
+ displayName: 'Clearbit',
+ name: 'clearbit',
+ icon: 'file:clearbit.png',
+ group: ['output'],
+ version: 1,
+ subtitle: '={{$parameter["operation"] + ":" + $parameter["resource"]}}',
+ description: 'Consume Clearbit API',
+ defaults: {
+ name: 'Clearbit',
+ color: '#219ef9',
+ },
+ inputs: ['main'],
+ outputs: ['main'],
+ credentials: [
+ {
+ name: 'clearbitApi',
+ required: true,
+ }
+ ],
+ properties: [
+ {
+ displayName: 'Resource',
+ name: 'resource',
+ type: 'options',
+ options: [
+ {
+ name: 'Company',
+ value: 'company',
+ description: 'The Company API allows you to look up a company by their domain',
+ },
+ {
+ name: 'Person',
+ value: 'person',
+ description: `The Person API lets you retrieve social information associated with an email address,
+ such as a person’s name, location and Twitter handle.`
+ },
+ ],
+ 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 additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject;
+ qs.email = email;
+ if (additionalFields.webhookUrl) {
+ qs.webhook_url = additionalFields.webhookUrl as string;
+ }
+ if (additionalFields.givenName) {
+ qs.given_name = additionalFields.givenName as string;
+ }
+ if (additionalFields.familyName) {
+ qs.family_name = additionalFields.familyName as string;
+ }
+ if (additionalFields.ipAddress) {
+ qs.ip_address = additionalFields.ipAddress as string;
+ }
+ if (additionalFields.location) {
+ qs.location = additionalFields.location as string;
+ }
+ if (additionalFields.company) {
+ qs.company = additionalFields.company as string;
+ }
+ if (additionalFields.companyDomain) {
+ qs.company_domain = additionalFields.companyDomain as string;
+ }
+ if (additionalFields.linkedin) {
+ qs.linkedin = additionalFields.linkedin as string;
+ }
+ if (additionalFields.twitter) {
+ qs.twitter = additionalFields.twitter as string;
+ }
+ if (additionalFields.facebook) {
+ qs.facebook = additionalFields.facebook as string;
+ }
+ responseData = await clearbitApiRequest.call(this, 'GET', resource, '/v2/people/find', {}, qs);
+ }
+ }
+ if (resource === 'company') {
+ if (operation === 'enrich') {
+ const domain = this.getNodeParameter('domain', i) as string;
+ const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject;
+ qs.domain = domain;
+ if (additionalFields.webhookUrl) {
+ qs.webhook_url = additionalFields.webhookUrl as string;
+ }
+ if (additionalFields.companyName) {
+ qs.company_name = additionalFields.companyName as string;
+ }
+ if (additionalFields.linkedin) {
+ qs.linkedin = additionalFields.linkedin as string;
+ }
+ if (additionalFields.twitter) {
+ qs.twitter = additionalFields.twitter as string;
+ }
+ if (additionalFields.facebook) {
+ qs.facebook = additionalFields.facebook as string;
+ }
+ responseData = await clearbitApiRequest.call(this, 'GET', resource, '/v2/companies/find', {}, qs);
+ }
+ if (operation === 'autocomplete') {
+ const name = this.getNodeParameter('name', i) as string;
+ qs.query = name;
+ responseData = await clearbitApiRequest.call(this, 'GET', 'autocomplete', '/v1/companies/suggest', {}, 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/Clearbit/CompanyDescription.ts b/packages/nodes-base/nodes/Clearbit/CompanyDescription.ts
new file mode 100644
index 0000000000..abd998051c
--- /dev/null
+++ b/packages/nodes-base/nodes/Clearbit/CompanyDescription.ts
@@ -0,0 +1,130 @@
+import { INodeProperties } from 'n8n-workflow';
+
+export const companyOperations = [
+ {
+ displayName: 'Operation',
+ name: 'operation',
+ type: 'options',
+ displayOptions: {
+ show: {
+ resource: [
+ 'company',
+ ],
+ },
+ },
+ options: [
+ {
+ name: 'Enrich',
+ value: 'enrich',
+ description: 'Lets you look up person and company data based on an email or domain',
+ },
+ {
+ name: 'Autocomplete',
+ value: 'autocomplete',
+ description: 'lets you auto-complete company names and retreive logo and domain',
+ },
+ ],
+ default: 'enrich',
+ description: 'The operation to perform.',
+ },
+] as INodeProperties[];
+
+export const companyFields = [
+
+/* -------------------------------------------------------------------------- */
+/* company:enrich */
+/* -------------------------------------------------------------------------- */
+ {
+ displayName: 'Domain',
+ name: 'domain',
+ type: 'string',
+ default: '',
+ required: true,
+ displayOptions: {
+ show: {
+ resource: [
+ 'company',
+ ],
+ operation: [
+ 'enrich',
+ ],
+ },
+ },
+ description: 'The domain to look up.',
+ },
+ {
+ displayName: 'Additional Fields',
+ name: 'additionalFields',
+ type: 'collection',
+ placeholder: 'Add Field',
+ default: {},
+ displayOptions: {
+ show: {
+ resource: [
+ 'company',
+ ],
+ operation: [
+ 'enrich',
+ ],
+ },
+ },
+ options: [
+ {
+ displayName: 'Webhook URL',
+ name: 'webhookUrl',
+ type: 'string',
+ default: '',
+ description: 'A webhook URL that results will be sent to.',
+ },
+ {
+ displayName: 'Company Name',
+ name: 'companyName',
+ type: 'string',
+ default: '',
+ description: 'The name of the company.',
+ },
+ {
+ displayName: 'Linkedin',
+ name: 'linkedin',
+ type: 'string',
+ default: '',
+ description: 'The LinkedIn URL for the company.',
+ },
+ {
+ displayName: 'Twitter',
+ name: 'twitter',
+ type: 'string',
+ default: '',
+ description: 'The Twitter handle for the company.',
+ },
+ {
+ displayName: 'Facebook',
+ name: 'facebook',
+ type: 'string',
+ default: '',
+ description: 'The Facebook URL for the company.',
+ },
+ ],
+ },
+/* -------------------------------------------------------------------------- */
+/* company:autocomplete */
+/* -------------------------------------------------------------------------- */
+{
+ displayName: 'Name',
+ name: 'name',
+ type: 'string',
+ default: '',
+ required: true,
+ displayOptions: {
+ show: {
+ resource: [
+ 'company',
+ ],
+ operation: [
+ 'autocomplete',
+ ],
+ },
+ },
+ description: 'Name is the partial name of the company.',
+},
+] as INodeProperties[];
diff --git a/packages/nodes-base/nodes/Clearbit/GenericFunctions.ts b/packages/nodes-base/nodes/Clearbit/GenericFunctions.ts
new file mode 100644
index 0000000000..bfe38e8991
--- /dev/null
+++ b/packages/nodes-base/nodes/Clearbit/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 clearbitApiRequest(this: IHookFunctions | IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions, method: string, api: string, resource: string, body: any = {}, qs: IDataObject = {}, uri?: string, option: IDataObject = {}): Promise { // tslint:disable-line:no-any
+ const credentials = this.getCredentials('clearbitApi');
+ if (credentials === undefined) {
+ throw new Error('No credentials got returned!');
+ }
+ let options: OptionsWithUri = {
+ headers: { Authorization: `Bearer ${credentials.apiKey}`},
+ method,
+ qs,
+ body,
+ uri: uri ||`https://${api}.clearbit.com${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/Clearbit/PersonDescription.ts b/packages/nodes-base/nodes/Clearbit/PersonDescription.ts
new file mode 100644
index 0000000000..a91fa0744e
--- /dev/null
+++ b/packages/nodes-base/nodes/Clearbit/PersonDescription.ts
@@ -0,0 +1,139 @@
+import { INodeProperties } from 'n8n-workflow';
+
+export const personOperations = [
+ {
+ displayName: 'Operation',
+ name: 'operation',
+ type: 'options',
+ displayOptions: {
+ show: {
+ resource: [
+ 'person',
+ ],
+ },
+ },
+ options: [
+ {
+ name: 'Enrich',
+ value: 'enrich',
+ description: 'Lets you look up person and company data based on an email or domain',
+ },
+ ],
+ default: 'enrich',
+ description: 'The operation to perform.',
+ },
+] as INodeProperties[];
+
+export const personFields = [
+
+/* -------------------------------------------------------------------------- */
+/* person:enrich */
+/* -------------------------------------------------------------------------- */
+ {
+ displayName: 'Email',
+ name: 'email',
+ type: 'string',
+ default: '',
+ required: true,
+ displayOptions: {
+ show: {
+ resource: [
+ 'person',
+ ],
+ operation: [
+ 'enrich',
+ ],
+ },
+ },
+ description: 'The email address to look up.',
+ },
+ {
+ displayName: 'Additional Fields',
+ name: 'additionalFields',
+ type: 'collection',
+ placeholder: 'Add Field',
+ default: {},
+ displayOptions: {
+ show: {
+ resource: [
+ 'person',
+ ],
+ operation: [
+ 'enrich',
+ ],
+ },
+ },
+ options: [
+ {
+ displayName: 'Webhook URL',
+ name: 'webhookUrl',
+ type: 'string',
+ default: '',
+ description: 'A webhook URL that results will be sent to.',
+ },
+ {
+ displayName: 'Given Name',
+ name: 'givenName',
+ type: 'string',
+ default: '',
+ description: 'First name of person.',
+ },
+ {
+ displayName: 'Family Name',
+ name: 'familyName',
+ type: 'string',
+ default: '',
+ description: 'Last name of person. If you have this, passing this is strongly recommended to improve match rates.',
+ },
+ {
+ displayName: 'IP Address',
+ name: 'ipAddress',
+ type: 'string',
+ default: '',
+ description: 'IP address of the person. If you have this, passing this is strongly recommended to improve match rates.',
+ },
+ {
+ displayName: 'Location',
+ name: 'location',
+ type: 'string',
+ default: '',
+ description: 'The city or country where the person resides.',
+ },
+ {
+ displayName: 'Company',
+ name: 'company',
+ type: 'string',
+ default: '',
+ description: 'The name of the person’s employer.',
+ },
+ {
+ displayName: 'Company Domain',
+ name: 'companyDomain',
+ type: 'string',
+ default: '',
+ description: 'The domain for the person’s employer.',
+ },
+ {
+ displayName: 'Linkedin',
+ name: 'linkedin',
+ type: 'string',
+ default: '',
+ description: 'The LinkedIn URL for the person.',
+ },
+ {
+ displayName: 'Twitter',
+ name: 'twitter',
+ type: 'string',
+ default: '',
+ description: 'The Twitter handle for the person.',
+ },
+ {
+ displayName: 'Facebook',
+ name: 'facebook',
+ type: 'string',
+ default: '',
+ description: 'The Facebook URL for the person.',
+ },
+ ],
+ },
+] as INodeProperties[];
diff --git a/packages/nodes-base/nodes/Clearbit/clearbit.png b/packages/nodes-base/nodes/Clearbit/clearbit.png
new file mode 100644
index 0000000000..69af5011c9
Binary files /dev/null and b/packages/nodes-base/nodes/Clearbit/clearbit.png differ
diff --git a/packages/nodes-base/package.json b/packages/nodes-base/package.json
index d3fe3ad092..5d52182543 100644
--- a/packages/nodes-base/package.json
+++ b/packages/nodes-base/package.json
@@ -38,6 +38,7 @@
"dist/credentials/ClickUpApi.credentials.js",
"dist/credentials/CodaApi.credentials.js",
"dist/credentials/CopperApi.credentials.js",
+ "dist/credentials/ClearbitApi.credentials.js",
"dist/credentials/DisqusApi.credentials.js",
"dist/credentials/DropboxApi.credentials.js",
"dist/credentials/EventbriteApi.credentials.js",
@@ -112,6 +113,7 @@
"dist/nodes/ClickUp/ClickUpTrigger.node.js",
"dist/nodes/Coda/Coda.node.js",
"dist/nodes/Copper/CopperTrigger.node.js",
+ "dist/nodes/Clearbit/Clearbit.node.js",
"dist/nodes/Cron.node.js",
"dist/nodes/Discord/Discord.node.js",
"dist/nodes/Disqus/Disqus.node.js",