From 327abd943f3e41e1d074d3ba33dce9fe2c5e237e Mon Sep 17 00:00:00 2001 From: ricardo Date: Fri, 21 Aug 2020 18:04:12 -0400 Subject: [PATCH 1/2] :zap: Add search operation to contact resource --- .../nodes/Hubspot/ContactDescription.ts | 263 ++++++++++++++++++ .../nodes-base/nodes/Hubspot/Hubspot.node.ts | 47 ++++ 2 files changed, 310 insertions(+) diff --git a/packages/nodes-base/nodes/Hubspot/ContactDescription.ts b/packages/nodes-base/nodes/Hubspot/ContactDescription.ts index 60d2be5d70..015f3d30cf 100644 --- a/packages/nodes-base/nodes/Hubspot/ContactDescription.ts +++ b/packages/nodes-base/nodes/Hubspot/ContactDescription.ts @@ -40,6 +40,11 @@ export const contactOperations = [ value: 'getRecentlyCreatedUpdated', description: 'Get recently created/updated contacts', }, + { + name: 'Search', + value: 'search', + description: 'Search contacts', + }, ], default: 'upsert', description: 'The operation to perform.', @@ -834,4 +839,262 @@ export const contactFields = [ }, ], }, + +//*-------------------------------------------------------------------------- */ +/* contact:search */ +/* -------------------------------------------------------------------------- */ + { + displayName: 'Return All', + name: 'returnAll', + type: 'boolean', + displayOptions: { + show: { + resource: [ + 'contact', + ], + operation: [ + 'search', + ], + }, + }, + default: false, + description: 'If all results should be returned or only up to a given limit.', + }, + { + displayName: 'Limit', + name: 'limit', + type: 'number', + displayOptions: { + show: { + resource: [ + 'contact', + ], + operation: [ + 'search', + ], + returnAll: [ + false, + ], + }, + }, + typeOptions: { + minValue: 1, + maxValue: 250, + }, + default: 100, + description: 'How many results to return.', + }, + { + displayName: 'Sort By', + name: 'sorts', + type: 'options', + typeOptions: { + loadOptionsMethod: 'getContactProperties', + }, + displayOptions: { + show: { + resource: [ + 'contact', + ], + operation: [ + 'search', + ], + }, + }, + default: [], + }, + { + displayName: 'Direction', + name: 'direction', + type: 'options', + options: [ + { + name: 'ASC', + value: 'ASCENDING', + }, + { + name: 'DESC', + value: 'DESCENDING', + }, + ], + displayOptions: { + show: { + resource: [ + 'contact', + ], + operation: [ + 'search', + ], + }, + }, + default: 'DESCENDING', + description: 'Defines the direction in which search results are ordered. Default value is DESC.', + }, + { + displayName: 'Filter Groups', + name: 'filterGroupsUi', + type: 'fixedCollection', + default: '', + placeholder: 'Add Filter Group', + typeOptions: { + multipleValues: true, + }, + required: false, + displayOptions: { + show: { + resource: [ + 'contact', + ], + operation: [ + 'search', + ], + }, + }, + options: [ + { + name: 'filterGroupsValues', + displayName: 'Filter Group', + values: [ + { + displayName: 'Filters', + name: 'filtersUi', + type: 'fixedCollection', + default: '', + placeholder: 'Add Filter', + typeOptions: { + multipleValues: true, + }, + required: false, + options: [ + { + name: 'filterValues', + displayName: 'Filter', + values: [ + { + displayName: 'Property Name', + name: 'propertyName', + type: 'options', + typeOptions: { + loadOptionsMethod: 'getContactProperties', + }, + default: '', + }, + { + displayName: 'Operator', + name: 'operator', + type: 'options', + options: [ + { + name: 'Equal', + value: 'EQ', + }, + { + name: 'Not Equal', + value: 'NEQ', + }, + { + name: 'Less Than', + value: 'LT', + }, + { + name: 'Less Than Or Equal', + value: 'LTE', + }, + { + name: 'Greater Than', + value: 'GT', + }, + { + name: 'Greater Than Or Equal', + value: 'GTE', + }, + { + name: 'Is Known', + value: 'HAS_PROPERTY', + }, + { + name: 'Is Unknown', + value: 'NOT_HAS_PROPERTY', + }, + { + name: 'Contains Exactly', + value: 'CONSTAIN_TOKEN', + }, + { + name: `Doesn't Contain Exactly`, + value: 'NOT_CONSTAIN_TOKEN', + }, + ], + default: 'EQ', + }, + { + displayName: 'Value', + name: 'value', + displayOptions: { + hide: { + operator: [ + 'HAS_PROPERTY', + 'NOT_HAS_PROPERTY', + ], + }, + }, + type: 'string', + default: '', + }, + ], + } + ], + description: 'Use filters to limit the results to only CRM objects with matching property values. More info here', + }, + ], + } + ], + description: `When multiple filters are provided within a filterGroup, they will be combined using a logical AND operator.
+ When multiple filterGroups are provided, they will be combined using a logical OR operator.
+ The system supports a maximum of three filterGroups with up to three filters each.
+ More info here` + }, + { + displayName: 'Additional Fields', + name: 'additionalFields', + type: 'collection', + placeholder: 'Add Field', + default: {}, + displayOptions: { + show: { + resource: [ + 'contact', + ], + operation: [ + 'search', + ], + }, + }, + options: [ + { + displayName: 'Fields', + name: 'properties', + type: 'multiOptions', + typeOptions: { + loadOptionsMethod: 'getContactProperties', + }, + default: [ + 'firstname', + 'lastname', + 'email', + ], + description: `Used to include specific company properties in the results.
+ By default, the results will only include company ID and will not include the values for any properties for your companys.
+ Including this parameter will include the data for the specified property in the results.
+ You can include this parameter multiple times to request multiple properties separed by ,.`, + }, + { + displayName: 'Query', + name: 'query', + type: 'string', + default: '', + description: 'Perform a text search against all property values for an object type', + }, + ], + }, ] as INodeProperties[]; diff --git a/packages/nodes-base/nodes/Hubspot/Hubspot.node.ts b/packages/nodes-base/nodes/Hubspot/Hubspot.node.ts index 458a974837..c6cb238903 100644 --- a/packages/nodes-base/nodes/Hubspot/Hubspot.node.ts +++ b/packages/nodes-base/nodes/Hubspot/Hubspot.node.ts @@ -1166,6 +1166,53 @@ export class Hubspot implements INodeType { const endpoint = `/contacts/v1/contact/vid/${contactId}`; responseData = await hubspotApiRequest.call(this, 'DELETE', endpoint); } + //https://developers.hubspot.com/docs/api/crm/search + if (operation === 'search') { + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const returnAll = this.getNodeParameter('returnAll', 0) as boolean; + const filtersGroupsUi = this.getNodeParameter('filterGroupsUi', i) as IDataObject; + const sorts = this.getNodeParameter('sorts', i) as string; + const direction = this.getNodeParameter('direction', i) as string; + + const body: IDataObject = { + sorts: [ + { + propertyName: sorts, + direction, + }, + ], + }; + + if (filtersGroupsUi) { + const filterGroupValues = (filtersGroupsUi as IDataObject).filterGroupsValues as IDataObject[]; + if (filterGroupValues) { + body.filterGroups = []; + for (const filterGroupValue of filterGroupValues) { + if (filterGroupValue.filtersUi) { + const filterValues = (filterGroupValue.filtersUi as IDataObject).filterValues as IDataObject[]; + if (filterValues) { + //@ts-ignore + body.filterGroups.push({ filters: filterValues }); + } + } + } + } + } + + Object.assign(body, additionalFields); + + const endpoint = '/crm/v3/objects/contacts/search'; + + if (returnAll) { + + responseData = await hubspotApiRequestAllItems.call(this, 'results', 'POST', endpoint, body, qs); + + } else { + qs.count = this.getNodeParameter('limit', 0) as number; + responseData = await hubspotApiRequest.call(this, 'POST', endpoint, body, qs); + responseData = responseData.results; + } + } } //https://developers.hubspot.com/docs/methods/companies/companies-overview if (resource === 'company') { From ad67d020c062b0a6cc42b8d4ba0b6c7c0d0f4751 Mon Sep 17 00:00:00 2001 From: Jan Oberhauser Date: Tue, 25 Aug 2020 09:52:00 +0200 Subject: [PATCH 2/2] :zap: Small improvements to Hubspot-Node --- .../nodes/Hubspot/ContactDescription.ts | 72 +++++++------------ .../nodes-base/nodes/Hubspot/Hubspot.node.ts | 6 +- 2 files changed, 29 insertions(+), 49 deletions(-) diff --git a/packages/nodes-base/nodes/Hubspot/ContactDescription.ts b/packages/nodes-base/nodes/Hubspot/ContactDescription.ts index 015f3d30cf..7cd7670597 100644 --- a/packages/nodes-base/nodes/Hubspot/ContactDescription.ts +++ b/packages/nodes-base/nodes/Hubspot/ContactDescription.ts @@ -884,52 +884,6 @@ export const contactFields = [ default: 100, description: 'How many results to return.', }, - { - displayName: 'Sort By', - name: 'sorts', - type: 'options', - typeOptions: { - loadOptionsMethod: 'getContactProperties', - }, - displayOptions: { - show: { - resource: [ - 'contact', - ], - operation: [ - 'search', - ], - }, - }, - default: [], - }, - { - displayName: 'Direction', - name: 'direction', - type: 'options', - options: [ - { - name: 'ASC', - value: 'ASCENDING', - }, - { - name: 'DESC', - value: 'DESCENDING', - }, - ], - displayOptions: { - show: { - resource: [ - 'contact', - ], - operation: [ - 'search', - ], - }, - }, - default: 'DESCENDING', - description: 'Defines the direction in which search results are ordered. Default value is DESC.', - }, { displayName: 'Filter Groups', name: 'filterGroupsUi', @@ -1071,6 +1025,23 @@ export const contactFields = [ }, }, options: [ + { + displayName: 'Direction', + name: 'direction', + type: 'options', + options: [ + { + name: 'ASC', + value: 'ASCENDING', + }, + { + name: 'DESC', + value: 'DESCENDING', + }, + ], + default: 'DESCENDING', + description: 'Defines the direction in which search results are ordered. Default value is DESC.', + }, { displayName: 'Fields', name: 'properties', @@ -1095,6 +1066,15 @@ export const contactFields = [ default: '', description: 'Perform a text search against all property values for an object type', }, + { + displayName: 'Sort By', + name: 'sortBy', + type: 'options', + typeOptions: { + loadOptionsMethod: 'getContactProperties', + }, + default: 'createdate', + }, ], }, ] as INodeProperties[]; diff --git a/packages/nodes-base/nodes/Hubspot/Hubspot.node.ts b/packages/nodes-base/nodes/Hubspot/Hubspot.node.ts index c6cb238903..cf53fdd3b4 100644 --- a/packages/nodes-base/nodes/Hubspot/Hubspot.node.ts +++ b/packages/nodes-base/nodes/Hubspot/Hubspot.node.ts @@ -1171,13 +1171,13 @@ export class Hubspot implements INodeType { const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; const returnAll = this.getNodeParameter('returnAll', 0) as boolean; const filtersGroupsUi = this.getNodeParameter('filterGroupsUi', i) as IDataObject; - const sorts = this.getNodeParameter('sorts', i) as string; - const direction = this.getNodeParameter('direction', i) as string; + const sortBy = additionalFields.sortBy || 'createdate'; + const direction = additionalFields.direction || 'DESCENDING'; const body: IDataObject = { sorts: [ { - propertyName: sorts, + propertyName: sortBy, direction, }, ],