diff --git a/packages/nodes-base/nodes/Hubspot/DealDescription.ts b/packages/nodes-base/nodes/Hubspot/DealDescription.ts index d37b398962..2b24ba9c9d 100644 --- a/packages/nodes-base/nodes/Hubspot/DealDescription.ts +++ b/packages/nodes-base/nodes/Hubspot/DealDescription.ts @@ -36,8 +36,8 @@ export const dealFields = [ /* -------------------------------------------------------------------------- */ { - displayName: 'Stages', - name: 'stages', + displayName: 'Stage', + name: 'stage', type: 'options', required: true, typeOptions: { @@ -107,8 +107,11 @@ export const dealFields = [ { displayName: 'Deal Type', name: 'dealType', - type: 'string', - default: '', + type: 'options', + typeOptions: { + loadOptionsMethod: 'getDealTypes', + }, + default: [], }, { displayName: 'Associated Company', diff --git a/packages/nodes-base/nodes/Hubspot/DealInterface.ts b/packages/nodes-base/nodes/Hubspot/DealInterface.ts new file mode 100644 index 0000000000..5bc7ea47c3 --- /dev/null +++ b/packages/nodes-base/nodes/Hubspot/DealInterface.ts @@ -0,0 +1,12 @@ +import { IDataObject } from "n8n-workflow"; + + +export interface IAssociation { + associatedCompanyIds?: number[]; + associatedVids?: number[]; +} + +export interface IDeal { + association?: IAssociation; + properties?: IDataObject[]; +} diff --git a/packages/nodes-base/nodes/Hubspot/GenericFunctions.ts b/packages/nodes-base/nodes/Hubspot/GenericFunctions.ts index 8cc245ffd6..2bb224c776 100644 --- a/packages/nodes-base/nodes/Hubspot/GenericFunctions.ts +++ b/packages/nodes-base/nodes/Hubspot/GenericFunctions.ts @@ -10,7 +10,6 @@ import { import { IDataObject, } from 'n8n-workflow'; -import { response } from 'express'; export async function hubspotApiRequest(this: IHookFunctions | IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions, method: string, endpoint: string, body: any = {}, query: IDataObject = {}, uri?: string): Promise { // tslint:disable-line:no-any const credentials = this.getCredentials('hubspotApi'); diff --git a/packages/nodes-base/nodes/Hubspot/Hubspot.node.ts b/packages/nodes-base/nodes/Hubspot/Hubspot.node.ts index d978d9038d..3f7a69253c 100644 --- a/packages/nodes-base/nodes/Hubspot/Hubspot.node.ts +++ b/packages/nodes-base/nodes/Hubspot/Hubspot.node.ts @@ -18,6 +18,7 @@ import { dealOperations, dealFields, } from '../Hubspot/DealDescription'; +import { IDeal, IAssociation } from './DealInterface'; export class Hubspot implements INodeType { description: INodeTypeDescription = { @@ -72,7 +73,6 @@ export class Hubspot implements INodeType { const endpoint = '/crm-pipelines/v1/pipelines/deals'; stages = await hubspotApiRequest.call(this, 'GET', endpoint, {}); stages = stages.results[0].stages; - console.log(stages) } catch (err) { throw new Error(`Hubspot Error: ${err}`); } @@ -129,109 +129,110 @@ export class Hubspot implements INodeType { }); } return returnData; - } + }, + + // Get all the deal types to display them to user so that he can + // select them easily + async getDealTypes(this: ILoadOptionsFunctions): Promise { + const returnData: INodePropertyOptions[] = []; + let dealTypes; + try { + const endpoint = '/properties/v1/deals/properties/named/dealtype'; + dealTypes = await hubspotApiRequest.call(this, 'GET', endpoint); + } catch (err) { + throw new Error(`Hubspot Error: ${err}`); + } + for (const dealType of dealTypes.options) { + const dealTypeName = dealType.label ; + const dealTypeId = dealType.value; + returnData.push({ + name: dealTypeName, + value: dealTypeId, + }); + } + return returnData; + }, } }; async execute(this: IExecuteFunctions): Promise { - // const items = this.getInputData(); - // const returnData: IDataObject[] = []; - // const length = items.length as unknown as number; - // let responseData; - // const qs: IDataObject = {}; - - // 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 === 'payout') { - // if (operation === 'create') { - // const body: IPaymentBatch = {}; - // const header: ISenderBatchHeader = {}; - // const jsonActive = this.getNodeParameter('jsonParameters', i) as boolean; - // const senderBatchId = this.getNodeParameter('senderBatchId', i) as string; - // const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - // header.sender_batch_id = senderBatchId; - // if (additionalFields.emailSubject) { - // header.email_subject = additionalFields.emailSubject as string; - // } - // if (additionalFields.emailMessage) { - // header.email_message = additionalFields.emailMessage as string; - // } - // if (additionalFields.note) { - // header.note = additionalFields.note as string; - // } - // body.sender_batch_header = header; - // if (!jsonActive) { - // const payoutItems: IItem[] = []; - // const itemsValues = (this.getNodeParameter('itemsUi', i) as IDataObject).itemsValues as IDataObject[]; - // if (itemsValues && itemsValues.length > 0) { - // itemsValues.forEach(o => { - // const payoutItem: IItem = {}; - // const amount: IAmount = {}; - // amount.currency = o.currency as string; - // amount.value = parseFloat(o.amount as string); - // payoutItem.amount = amount; - // payoutItem.note = o.note as string || ''; - // payoutItem.receiver = o.receiverValue as string; - // payoutItem.recipient_type = o.recipientType as RecipientType; - // payoutItem.recipient_wallet = o.recipientWallet as RecipientWallet; - // payoutItem.sender_item_id = o.senderItemId as string || ''; - // payoutItems.push(payoutItem); - // }); - // body.items = payoutItems; - // } else { - // throw new Error('You must have at least one item.'); - // } - // } else { - // const itemsJson = validateJSON(this.getNodeParameter('itemsJson', i) as string); - // body.items = itemsJson; - // } - // try { - // responseData = await payPalApiRequest.call(this, '/payments/payouts', 'POST', body); - // } catch (err) { - // throw new Error(`PayPal Error: ${JSON.stringify(err)}`); - // } - // } - // if (operation === 'get') { - // const payoutBatchId = this.getNodeParameter('payoutBatchId', i) as string; - // const returnAll = this.getNodeParameter('returnAll', 0) as boolean; - // try { - // if (returnAll === true) { - // responseData = await payPalApiRequestAllItems.call(this, 'items', `/payments/payouts/${payoutBatchId}`, 'GET', {}, qs); - // } else { - // qs.page_size = this.getNodeParameter('limit', i) as number; - // responseData = await payPalApiRequest.call(this, `/payments/payouts/${payoutBatchId}`, 'GET', {}, qs); - // responseData = responseData.items; - // } - // } catch (err) { - // throw new Error(`PayPal Error: ${JSON.stringify(err)}`); - // } - // } - // } else if (resource === 'payoutItem') { - // if (operation === 'get') { - // const payoutItemId = this.getNodeParameter('payoutItemId', i) as string; - // try { - // responseData = await payPalApiRequest.call(this,`/payments/payouts-item/${payoutItemId}`, 'GET', {}, qs); - // } catch (err) { - // throw new Error(`PayPal Error: ${JSON.stringify(err)}`); - // } - // } - // if (operation === 'cancel') { - // const payoutItemId = this.getNodeParameter('payoutItemId', i) as string; - // try { - // responseData = await payPalApiRequest.call(this,`/payments/payouts-item/${payoutItemId}/cancel`, 'POST', {}, qs); - // } catch (err) { - // throw new Error(`PayPal Error: ${JSON.stringify(err)}`); - // } - // } - // } - // if (Array.isArray(responseData)) { - // returnData.push.apply(returnData, responseData as IDataObject[]); - // } else { - // returnData.push(responseData as IDataObject); - // } - // } - return [this.helpers.returnJsonArray({})]; + const items = this.getInputData(); + const returnData: IDataObject[] = []; + const length = items.length as unknown as number; + let responseData; + const qs: IDataObject = {}; + 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 === 'deal') { + if (operation === 'create') { + const body: IDeal = {}; + const association: IAssociation = {}; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const stage = this.getNodeParameter('stage', i) as string; + if (stage) { + // @ts-ignore + body.properties.push({ + name: 'dealstage', + value: stage + }); + } + if (additionalFields.associatedCompany) { + association.associatedCompanyIds = additionalFields.associatedCompany as number[]; + } + if (additionalFields.associatedVids) { + association.associatedVids = additionalFields.associatedVids as number[]; + } + if (additionalFields.dealName) { + // @ts-ignore + body.properties.push({ + name: 'dealname', + value: additionalFields.dealName as string + }); + } + if (additionalFields.closeDate) { + // @ts-ignore + body.properties.push({ + name: 'closedate', + value: new Date(additionalFields.closeDate as string).getTime() + }); + } + if (additionalFields.amount) { + // @ts-ignore + body.properties.push({ + name: 'amount', + value: additionalFields.amount as string + }); + } + if (additionalFields.dealType) { + // @ts-ignore + body.properties.push({ + name: 'dealtype', + value: additionalFields.dealType as string + }); + } + if (additionalFields.pipeline) { + // @ts-ignore + body.properties.push({ + name: 'pipeline', + value: additionalFields.pipeline as string + }); + } + body.association = association; + try { + const endpoint = '/deals/v1/deal'; + responseData = await hubspotApiRequest.call(this, 'POST', endpoint, body); + } catch (err) { + throw new Error(`Hubspot Error: ${JSON.stringify(err)}`); + } + } + } + if (Array.isArray(responseData)) { + returnData.push.apply(returnData, responseData as IDataObject[]); + } else { + returnData.push(responseData as IDataObject); + } + } + return [this.helpers.returnJsonArray(returnData)]; } }