hunter node

This commit is contained in:
Ricardo Espinoza 2020-01-24 16:16:54 -05:00
parent 38de0af9b9
commit eab4df1afd
5 changed files with 410 additions and 0 deletions

View file

@ -0,0 +1,17 @@
import {
ICredentialType,
NodePropertyTypes,
} from 'n8n-workflow';
export class HunterApi implements ICredentialType {
name = 'hunterApi';
displayName = 'Hunter API';
properties = [
{
displayName: 'API Key',
name: 'apiKey',
type: 'string' as NodePropertyTypes,
default: '',
},
];
}

View file

@ -0,0 +1,56 @@
import { OptionsWithUri } from 'request';
import {
IExecuteFunctions,
IExecuteSingleFunctions,
IHookFunctions,
ILoadOptionsFunctions,
} from 'n8n-core';
import { IDataObject } from 'n8n-workflow';
export async function hunterApiRequest(this: IHookFunctions | IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions, method: string, resource: string, body: any = {}, qs: IDataObject = {}, uri?: string, option: IDataObject = {}): Promise<any> { // tslint:disable-line:no-any
const credentials = this.getCredentials('hunterApi');
if (credentials === undefined) {
throw new Error('No credentials got returned!');
}
qs = Object.assign({ api_key: credentials.apiKey }, qs);
let options: OptionsWithUri = {
method,
qs,
body,
uri: uri ||`https://api.hunter.io/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);
}
}
/**
* Make an API request to paginated flow endpoint
* and return all results
*/
export async function hunterApiRequestAllItems(this: IHookFunctions | IExecuteFunctions| ILoadOptionsFunctions, propertyName: string, method: string, resource: string, body: any = {}, query: IDataObject = {}): Promise<any> { // tslint:disable-line:no-any
const returnData: IDataObject[] = [];
let responseData;
query.offset = 0;
query.limit = 100;
do {
responseData = await hunterApiRequest.call(this, method, resource, body, query);
returnData.push.apply(returnData, responseData[propertyName]);
query.offset += query.limit;
} while (
responseData.meta !== undefined &&
responseData.meta.results !== undefined &&
responseData.meta.offset <= responseData.meta.results
);
return returnData;
}

View file

@ -0,0 +1,335 @@
import {
IExecuteFunctions,
} from 'n8n-core';
import {
IDataObject,
INodeTypeDescription,
INodeExecutionData,
INodeType,
} from 'n8n-workflow';
import {
hunterApiRequest,
hunterApiRequestAllItems,
} from './GenericFunctions';
export class Hunter implements INodeType {
description: INodeTypeDescription = {
displayName: 'Hunter',
name: 'hunter',
icon: 'file:hunter.png',
group: ['output'],
version: 1,
subtitle: '={{$parameter["operation"]}}',
description: 'Consume Hunter API',
defaults: {
name: 'Hunter',
color: '#ff3807',
},
inputs: ['main'],
outputs: ['main'],
credentials: [
{
name: 'hunterApi',
required: true,
}
],
properties: [
{
displayName: 'Operation',
name: 'operation',
type: 'options',
options: [
{
name: ' Domain Search',
value: 'domainSearch',
description: 'Get every email address found on the internet using a given domain name, with sources.',
},
{
name: ' Email Finder',
value: 'emailFinder',
description: 'Generates or retrieves the most likely email address from a domain name, a first name and a last name.',
},
{
name: 'Email Verifier',
value: 'emailVerifier',
description: 'Allows you to verify the deliverability of an email address.',
},
],
default: 'domainSearch',
description: 'operation to consume.',
},
{
displayName: 'Domain',
name: 'domain',
type: 'string',
displayOptions: {
show: {
operation: [
'domainSearch',
],
returnAll: [
false,
],
},
},
default: '',
required: true,
description: 'Domain name from which you want to find the email addresses. For example, "stripe.com".',
},
{
displayName: 'Return All',
name: 'returnAll',
type: 'boolean',
displayOptions: {
show: {
operation: [
'domainSearch',
],
},
},
default: false,
description: 'If all results should be returned or only up to a given limit.',
},
{
displayName: 'Limit',
name: 'limit',
type: 'number',
displayOptions: {
show: {
operation: [
'domainSearch',
],
returnAll: [
false,
],
},
},
typeOptions: {
minValue: 1,
maxValue: 100,
},
default: 50,
description: 'How many results to return.',
},
{
displayName: 'Filters',
name: 'filters',
type: 'collection',
placeholder: 'Add Filter',
default: {},
displayOptions: {
show: {
operation: [
'domainSearch',
],
},
},
options: [
{
displayName: 'Type',
name: 'type',
type: 'options',
default: '',
options: [
{
name: 'Personal',
value: 'personal',
},
{
name: 'Generic',
value: 'generic',
},
]
},
{
displayName: 'Seniority',
name: 'seniority',
type: 'multiOptions',
default: [],
options: [
{
name: 'Junior',
value: 'junior',
},
{
name: 'Senior',
value: 'senior',
},
{
name: 'Executive',
value: 'executive',
},
]
},
{
displayName: 'Department',
name: 'department',
type: 'multiOptions',
default: [],
options: [
{
name: 'Executive',
value: 'executive',
},
{
name: 'IT',
value: 'it',
},
{
name: 'Finance',
value: 'finance',
},
{
name: 'Management',
value: 'management',
},
{
name: 'Sales',
value: 'sales',
},
{
name: 'Legal',
value: 'legal',
},
{
name: 'Support',
value: 'support',
},
{
name: 'HR',
value: 'hr',
},
{
name: 'Marketing',
value: 'marketing',
},
{
name: 'Communication',
value: 'communication',
},
]
},
],
},
{
displayName: 'Domain',
name: 'domain',
type: 'string',
default: '',
displayOptions: {
show: {
operation: [
'emailFinder'
],
},
},
required: true,
description: 'Domain name from which you want to find the email addresses. For example, "stripe.com".',
},
{
displayName: 'First Name',
name: 'firstname',
type: 'string',
displayOptions: {
show: {
operation: [
'emailFinder'
],
},
},
default: '',
required: true,
description: `The person's first name. It doesn't need to be in lowercase..`,
},
{
displayName: 'Last Name',
name: 'lastname',
type: 'string',
displayOptions: {
show: {
operation: [
'emailFinder'
],
},
},
default: '',
required: true,
description: `The person's last name. It doesn't need to be in lowercase..`,
},
{
displayName: 'Email',
name: 'email',
type: 'string',
displayOptions: {
show: {
operation: [
'emailVerifier'
],
},
},
default: '',
required: true,
description: 'The email address you want to verify',
},
],
};
async execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {
const items = this.getInputData();
const returnData: IDataObject[] = [];
const length = items.length as unknown as number;
const qs: IDataObject = {};
let responseData;
for (let i = 0; i < length; i++) {
const operation = this.getNodeParameter('operation', 0) as string;
//https://hunter.io/api-documentation/v2#domain-search
if (operation === 'domainSearch') {
const returnAll = this.getNodeParameter('returnAll', i) as boolean;
const filters = this.getNodeParameter('filters', i) as IDataObject;
const domain = this.getNodeParameter('domain', i) as string;
qs.domain = domain;
if (filters.type){
qs.type = filters.type;
}
if (filters.seniority){
qs.seniority = (filters.seniority as string[]).join(',');
}
if (filters.department){
qs.department = (filters.department as string[]).join(',');
}
if (returnAll) {
responseData = await hunterApiRequestAllItems.call(this, 'data', 'GET', '/domain-search', {}, qs);
} else {
const limit = this.getNodeParameter('limit', i) as number;
qs.limit = limit;
responseData = await hunterApiRequest.call(this, 'GET', '/domain-search', {}, qs);
responseData = responseData.data;
}
}
//https://hunter.io/api-documentation/v2#email-finder
if (operation === 'emailFinder') {
const domain = this.getNodeParameter('domain', i) as string;
const firstname = this.getNodeParameter('firstname', i) as string;
const lastname = this.getNodeParameter('lastname', i) as string;
qs.first_name = firstname;
qs.last_name = lastname;
qs.domain = domain;
responseData = await hunterApiRequest.call(this, 'GET', '/email-finder', {}, qs);
responseData = responseData.data;
}
//https://hunter.io/api-documentation/v2#email-verifier
if (operation === 'emailVerifier') {
const email = this.getNodeParameter('email', i) as string;
qs.email = email;
responseData = await hunterApiRequest.call(this, 'GET', '/email-verifier', {}, qs);
responseData = responseData.data;
}
if (Array.isArray(responseData)) {
returnData.push.apply(returnData, responseData as IDataObject[]);
} else {
returnData.push(responseData as IDataObject);
}
}
return [this.helpers.returnJsonArray(returnData)];
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

View file

@ -51,6 +51,7 @@
"dist/credentials/HttpDigestAuth.credentials.js",
"dist/credentials/HttpHeaderAuth.credentials.js",
"dist/credentials/HubspotApi.credentials.js",
"dist/credentials/HunterApi.credentials.js",
"dist/credentials/Imap.credentials.js",
"dist/credentials/IntercomApi.credentials.js",
"dist/credentials/JiraSoftwareCloudApi.credentials.js",
@ -133,6 +134,7 @@
"dist/nodes/HtmlExtract/HtmlExtract.node.js",
"dist/nodes/HttpRequest.node.js",
"dist/nodes/Hubspot/Hubspot.node.js",
"dist/nodes/Hunter/Hunter.node.js",
"dist/nodes/If.node.js",
"dist/nodes/Intercom/Intercom.node.js",
"dist/nodes/Interval.node.js",