diff --git a/packages/nodes-base/nodes/Hubspot/DealDescription.ts b/packages/nodes-base/nodes/Hubspot/DealDescription.ts index 2b24ba9c9d..f0f27fe82d 100644 --- a/packages/nodes-base/nodes/Hubspot/DealDescription.ts +++ b/packages/nodes-base/nodes/Hubspot/DealDescription.ts @@ -18,11 +18,36 @@ export const dealOperations = [ value: 'create', description: 'Create a deal', }, + { + name: 'Update', + value: 'update', + description: 'Update a deal', + }, { name: 'Get', value: 'get', description: 'Get a deal', }, + { + name: 'Get All', + value: 'getAll', + description: 'Get all deals', + }, + { + name: 'Delete', + value: 'delete', + description: 'Delete a deals', + }, + { + name: 'Recents Created', + value: 'getRecentsCreated', + description: 'Get recently created deals', + }, + { + name: 'Recents Modified', + value: 'getRecentsModified', + description: 'Get recently modified deals', + }, ], default: 'create', description: 'The operation to perform.', @@ -34,9 +59,8 @@ export const dealFields = [ /* -------------------------------------------------------------------------- */ /* deal:create */ /* -------------------------------------------------------------------------- */ - { - displayName: 'Stage', + displayName: 'Deal Stage', name: 'stage', type: 'options', required: true, @@ -133,4 +157,333 @@ export const dealFields = [ }, ] }, +/* -------------------------------------------------------------------------- */ +/* deal:update */ +/* -------------------------------------------------------------------------- */ +{ + displayName: 'Deal ID', + name: 'dealId', + type: 'string', + required: true, + displayOptions: { + show: { + resource: [ + 'deal', + ], + operation: [ + 'update', + ], + }, + }, + default: '', + description: 'Unique identifier for a particular deal', +}, +{ + displayName: 'Update Fields', + name: 'updateFields', + type: 'collection', + placeholder: 'Add Update Field', + default: {}, + displayOptions: { + show: { + resource: [ + 'deal', + ], + operation: [ + 'update', + ], + }, + }, + options: [ + { + displayName: 'Deal Name', + name: 'dealName', + type: 'string', + default: '', + }, + { + displayName: 'Deal Stage', + name: 'stage', + type: 'options', + required: true, + typeOptions: { + loadOptionsMethod: 'getDealStages' + }, + default: [], + description: 'The dealstage is required when creating a deal. See the CRM Pipelines API for details on managing pipelines and stages.', + }, + { + displayName: 'Deal Stage', + name: 'dealStage', + type: 'string', + default: '', + }, + { + displayName: 'Pipeline', + name: 'pipeline', + type: 'string', + default: '', + }, + { + displayName: 'Close Date', + name: 'closeDate', + type: 'dateTime', + default: '', + }, + { + displayName: 'Amount', + name: 'amount', + type: 'string', + default: '', + }, + { + displayName: 'Deal Type', + name: 'dealType', + type: 'options', + typeOptions: { + loadOptionsMethod: 'getDealTypes', + }, + default: [], + }, + ] +}, +/* -------------------------------------------------------------------------- */ +/* deal:get */ +/* -------------------------------------------------------------------------- */ +{ + displayName: 'Deal ID', + name: 'dealId', + type: 'string', + required: true, + displayOptions: { + show: { + resource: [ + 'deal', + ], + operation: [ + 'get', + ], + }, + }, + default: '', + description: 'Unique identifier for a particular deal', +}, +{ + displayName: 'Additional Fields', + name: 'additionalFields', + type: 'collection', + placeholder: 'Add Field', + default: {}, + displayOptions: { + show: { + resource: [ + 'deal', + ], + operation: [ + 'get', + ], + }, + }, + options: [ + { + displayName: 'Include Property Versions ', + name: 'includePropertyVersions', + type: 'boolean', + default: false, + description: `By default, you will only get data for the most recent version of a property in the "versions" data.
+ If you include this parameter, you will get data for all previous versions.`, + }, + ] +}, +/* -------------------------------------------------------------------------- */ +/* deal:getAll */ +/* -------------------------------------------------------------------------- */ +{ + displayName: 'Return All', + name: 'returnAll', + type: 'boolean', + displayOptions: { + show: { + resource: [ + 'deal', + ], + operation: [ + 'getAll', + ], + }, + }, + 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: [ + 'deal', + ], + operation: [ + 'getAll', + ], + returnAll: [ + false, + ], + }, + }, + typeOptions: { + minValue: 1, + maxValue: 250, + }, + default: 100, + description: 'How many results to return.', +}, +{ + displayName: 'Filters', + name: 'filters', + type: 'collection', + placeholder: 'Add Filter', + default: {}, + displayOptions: { + show: { + resource: [ + 'deal', + ], + operation: [ + 'getAll', + ], + }, + }, + options: [ + { + displayName: 'Include Associations', + name: 'includeAssociations', + type: 'boolean', + default: false, + description: `Include the IDs of the associated contacts and companies in the results
. + This will also automatically include the num_associated_contacts property.`, + }, + { + displayName: 'Properties', + name: 'properties', + type: 'string', + default: '', + description: `Used to include specific deal properties in the results.
+ By default, the results will only include Deal ID and will not include the values for any properties for your Deals.
+ 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: 'Properties With History', + name: 'propertiesWithHistory', + type: 'string', + default: '', + description: `Works similarly to properties=, but this parameter will include the history for the specified property,
+ instead of just including the current value. Use this parameter when you need the full history of changes to a property's value.`, + }, + ] +}, +/* -------------------------------------------------------------------------- */ +/* deal:delete */ +/* -------------------------------------------------------------------------- */ +{ + displayName: 'Deal ID', + name: 'dealId', + type: 'string', + required: true, + displayOptions: { + show: { + resource: [ + 'deal', + ], + operation: [ + 'delete', + ], + }, + }, + default: '', + description: 'Unique identifier for a particular deal', +}, +/* -------------------------------------------------------------------------- */ +/* deal:getRecentsCreated deal:getRecentsModified */ +/* -------------------------------------------------------------------------- */ +{ + displayName: 'Return All', + name: 'returnAll', + type: 'boolean', + displayOptions: { + show: { + resource: [ + 'deal', + ], + operation: [ + 'getRecentsCreated', + 'getRecentsModified', + ], + }, + }, + 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: [ + 'deal', + ], + operation: [ + 'getRecentsCreated', + 'getRecentsModified', + ], + returnAll: [ + false, + ], + }, + }, + typeOptions: { + minValue: 1, + maxValue: 250, + }, + default: 100, + description: 'How many results to return.', +}, +{ + displayName: 'Filters', + name: 'filters', + type: 'collection', + placeholder: 'Add Filter', + default: {}, + displayOptions: { + show: { + resource: [ + 'deal', + ], + operation: [ + 'getRecentsCreated', + 'getRecentsModified', + ], + }, + }, + options: [ + { + displayName: 'Since', + name: 'since', + type: 'dateTime', + default: '', + description: `Only return deals created after timestamp x`, + }, + { + displayName: 'Include Property Versions', + name: 'includePropertyVersions', + type: 'boolean', + default: false, + description: `By default, you will only get data for the most recent version of a property in the "versions" data.
+ If you include this parameter, you will get data for all previous versions.`, + }, + ] +}, ] as INodeProperties[]; diff --git a/packages/nodes-base/nodes/Hubspot/DealInterface.ts b/packages/nodes-base/nodes/Hubspot/DealInterface.ts index 5bc7ea47c3..92a41d6c95 100644 --- a/packages/nodes-base/nodes/Hubspot/DealInterface.ts +++ b/packages/nodes-base/nodes/Hubspot/DealInterface.ts @@ -7,6 +7,6 @@ export interface IAssociation { } export interface IDeal { - association?: IAssociation; + associations?: IAssociation; properties?: IDataObject[]; } diff --git a/packages/nodes-base/nodes/Hubspot/GenericFunctions.ts b/packages/nodes-base/nodes/Hubspot/GenericFunctions.ts index 2bb224c776..699a3d699c 100644 --- a/packages/nodes-base/nodes/Hubspot/GenericFunctions.ts +++ b/packages/nodes-base/nodes/Hubspot/GenericFunctions.ts @@ -22,7 +22,8 @@ export async function hubspotApiRequest(this: IHookFunctions | IExecuteFunctions qs: query, uri: uri || `https://api.hubapi.com${endpoint}`, body, - json: true + json: true, + useQuerystring: true, }; try { diff --git a/packages/nodes-base/nodes/Hubspot/Hubspot.node.ts b/packages/nodes-base/nodes/Hubspot/Hubspot.node.ts index 3f7a69253c..7ed33f7802 100644 --- a/packages/nodes-base/nodes/Hubspot/Hubspot.node.ts +++ b/packages/nodes-base/nodes/Hubspot/Hubspot.node.ts @@ -12,7 +12,6 @@ import { import { hubspotApiRequest, hubspotApiRequestAllItems, - validateJSON, } from './GenericFunctions'; import { dealOperations, @@ -167,6 +166,7 @@ export class Hubspot implements INodeType { if (resource === 'deal') { if (operation === 'create') { const body: IDeal = {}; + body.properties = []; const association: IAssociation = {}; const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; const stage = this.getNodeParameter('stage', i) as string; @@ -218,7 +218,7 @@ export class Hubspot implements INodeType { value: additionalFields.pipeline as string }); } - body.association = association; + body.associations = association; try { const endpoint = '/deals/v1/deal'; responseData = await hubspotApiRequest.call(this, 'POST', endpoint, body); @@ -226,6 +226,135 @@ export class Hubspot implements INodeType { throw new Error(`Hubspot Error: ${JSON.stringify(err)}`); } } + if (operation === 'update') { + const body: IDeal = {}; + body.properties = []; + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + const dealId = this.getNodeParameter('dealId', i) as string; + if (updateFields.stage) { + body.properties.push({ + name: 'dealstage', + value: updateFields.stage as string, + }); + } + if (updateFields.dealName) { + // @ts-ignore + body.properties.push({ + name: 'dealname', + value: updateFields.dealName as string + }); + } + if (updateFields.closeDate) { + // @ts-ignore + body.properties.push({ + name: 'closedate', + value: new Date(updateFields.closeDate as string).getTime() + }); + } + if (updateFields.amount) { + // @ts-ignore + body.properties.push({ + name: 'amount', + value: updateFields.amount as string + }); + } + if (updateFields.dealType) { + // @ts-ignore + body.properties.push({ + name: 'dealtype', + value: updateFields.dealType as string + }); + } + if (updateFields.pipeline) { + // @ts-ignore + body.properties.push({ + name: 'pipeline', + value: updateFields.pipeline as string + }); + } + try { + const endpoint = `/deals/v1/deal/${dealId}`; + responseData = await hubspotApiRequest.call(this, 'PUT', endpoint, body); + } catch (err) { + throw new Error(`Hubspot Error: ${JSON.stringify(err)}`); + } + } + if (operation === 'get') { + const dealId = this.getNodeParameter('dealId', i) as string; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + if (additionalFields.includePropertyVersions) { + qs.includePropertyVersions = additionalFields.includePropertyVersions as boolean; + } + try { + const endpoint = `/deals/v1/deal/${dealId}`; + responseData = await hubspotApiRequest.call(this, 'GET', endpoint); + } catch (err) { + throw new Error(`Hubspot Error: ${JSON.stringify(err)}`); + } + } + if (operation === 'getAll') { + const filters = this.getNodeParameter('filters', i) as IDataObject; + const returnAll = this.getNodeParameter('returnAll', 0) as boolean; + if (filters.includeAssociations) { + qs.includeAssociations = filters.includeAssociations as boolean; + } + if (filters.properties) { + // @ts-ignore + qs.properties = filters.properties.split(','); + } + if (filters.propertiesWithHistory) { + // @ts-ignore + qs.propertiesWithHistory = filters.propertiesWithHistory.split(','); + } + try { + const endpoint = `/deals/v1/deal/paged`; + if (returnAll) { + responseData = await hubspotApiRequestAllItems.call(this, 'deals', 'GET', endpoint, {}, qs); + } else { + qs.limit = this.getNodeParameter('limit', 0) as number; + responseData = await hubspotApiRequest.call(this, 'GET', endpoint, {}, qs); + responseData = responseData.deals; + } + } catch (err) { + throw new Error(`Hubspot Error: ${JSON.stringify(err)}`); + } + } + if (operation === 'getRecentsCreated' || operation === 'getRecentsModified') { + let endpoint; + const filters = this.getNodeParameter('filters', i) as IDataObject; + const returnAll = this.getNodeParameter('returnAll', 0) as boolean; + if (filters.since) { + qs.since = new Date(filters.since as string).getTime(); + } + if (filters.includePropertyVersions) { + qs.includePropertyVersions = filters.includePropertyVersions as boolean; + } + try { + if (operation === 'getRecentsCreated') { + endpoint = `/deals/v1/deal/recent/created`; + } else { + endpoint = `/deals/v1/deal/recent/modified`; + } + if (returnAll) { + responseData = await hubspotApiRequestAllItems.call(this, 'results', 'GET', endpoint, {}, qs); + } else { + qs.count = this.getNodeParameter('limit', 0) as number; + responseData = await hubspotApiRequest.call(this, 'GET', endpoint, {}, qs); + responseData = responseData.results; + } + } catch (err) { + throw new Error(`Hubspot Error: ${JSON.stringify(err)}`); + } + } + if (operation === 'delete') { + const dealId = this.getNodeParameter('dealId', i) as string; + try { + const endpoint = `/deals/v1/deal/${dealId}`; + responseData = await hubspotApiRequest.call(this, 'DELETE', endpoint); + } catch (err) { + throw new Error(`Hubspot Error: ${JSON.stringify(err)}`); + } + } } if (Array.isArray(responseData)) { returnData.push.apply(returnData, responseData as IDataObject[]);