From c630028531b90abdc4fb18854b2c1eccd16a63d5 Mon Sep 17 00:00:00 2001 From: Ricardo Espinoza Date: Sat, 15 Feb 2020 19:23:22 -0500 Subject: [PATCH 1/2] :sparkles: Added lead resource --- .../credentials/ZohoOAuth2Api.credentials.ts | 2 +- .../nodes-base/nodes/Zoho/GenericFunctions.ts | 10 +- .../nodes-base/nodes/Zoho/LeadDescription.ts | 637 ++++++++++++++++-- .../nodes-base/nodes/Zoho/LeadInterface.ts | 37 + .../nodes-base/nodes/Zoho/ZohoCrm.node.ts | 363 +++++++++- 5 files changed, 984 insertions(+), 65 deletions(-) create mode 100644 packages/nodes-base/nodes/Zoho/LeadInterface.ts diff --git a/packages/nodes-base/credentials/ZohoOAuth2Api.credentials.ts b/packages/nodes-base/credentials/ZohoOAuth2Api.credentials.ts index 801b164ffd..12a83493a4 100644 --- a/packages/nodes-base/credentials/ZohoOAuth2Api.credentials.ts +++ b/packages/nodes-base/credentials/ZohoOAuth2Api.credentials.ts @@ -62,7 +62,7 @@ export class ZohoOAuth2Api implements ICredentialType { displayName: 'Scope', name: 'scope', type: 'hidden' as NodePropertyTypes, - default: 'ZohoCRM.modules.ALL', + default: 'ZohoCRM.modules.ALL,ZohoCRM.settings.all,ZohoCRM.users.all', }, { displayName: 'Auth URI Query Parameters', diff --git a/packages/nodes-base/nodes/Zoho/GenericFunctions.ts b/packages/nodes-base/nodes/Zoho/GenericFunctions.ts index 04fe204858..3d20a3ec02 100644 --- a/packages/nodes-base/nodes/Zoho/GenericFunctions.ts +++ b/packages/nodes-base/nodes/Zoho/GenericFunctions.ts @@ -7,6 +7,7 @@ import { import { IDataObject } from 'n8n-workflow'; +import { queryResult } from 'pg-promise'; export async function zohoApiRequest(this: IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions, method: string, resource: string, body: any = {}, qs: IDataObject = {}, uri?: string, option: IDataObject = {}): Promise { // tslint:disable-line:no-any const options: OptionsWithUri = { @@ -41,14 +42,17 @@ export async function zohoApiRequestAllItems(this: IExecuteFunctions | ILoadOpti let responseData; let uri: string | undefined; + query.per_page = 200; + query.page = 0; do { responseData = await zohoApiRequest.call(this, method, endpoint, body, query, uri); - uri = responseData.nextRecordsUrl; + uri = responseData.info.more_records; returnData.push.apply(returnData, responseData[propertyName]); + query.page++; } while ( - responseData.nextRecordsUrl !== undefined && - responseData.nextRecordsUrl !== null + responseData.info.more_records !== undefined && + responseData.info.more_records === true ); return returnData; diff --git a/packages/nodes-base/nodes/Zoho/LeadDescription.ts b/packages/nodes-base/nodes/Zoho/LeadDescription.ts index 198abbe472..577fee4aec 100644 --- a/packages/nodes-base/nodes/Zoho/LeadDescription.ts +++ b/packages/nodes-base/nodes/Zoho/LeadDescription.ts @@ -28,10 +28,15 @@ export const leadOperations = [ value: 'getAll', description: 'Get data of all leads', }, + { + name: 'Get Fields', + value: 'getFields', + description: `Get the fields' metadata`, + }, { name: 'Update', value: 'update', - description: 'Update new lead', + description: 'Update a lead', }, { name: 'Delete', @@ -49,7 +54,6 @@ export const leadFields = [ /* -------------------------------------------------------------------------- */ /* lead:create */ /* -------------------------------------------------------------------------- */ - { displayName: 'Last Name', name: 'lastName', @@ -86,86 +90,617 @@ export const leadFields = [ }, options: [ { - displayName: 'Avatar', - name: 'avatar', - type: 'string', - default: '', - description: 'An avatar image URL. note: the image url needs to be https.', + displayName: 'Annual Revenue', + name: 'annualRevenue', + type: 'number', + typeOptions: { + numberPrecision: 2, + }, + default: 0, }, { - displayName: 'Name', - name: 'name', + displayName: 'Company', + name: 'company', type: 'string', default: '', - description: 'Name of the user', + }, + { + displayName: 'Description', + name: 'description', + type: 'string', + default: '', + }, + { + displayName: 'Email', + name: 'email', + type: 'string', + default: '', + }, + { + displayName: 'Email Opt Out', + name: 'emailOptOut', + type: 'boolean', + default: false, + }, + { + displayName: 'Fax', + name: 'fax', + type: 'string', + default: '', + }, + { + displayName: 'First Name', + name: 'firstName', + type: 'string', + default: '', + }, + { + displayName: 'Industry', + name: 'industry', + type: 'options', + typeOptions: { + loadOptionsMethod: 'getIndustries', + }, + default: '', + }, + { + displayName: 'Is Record Duplicate', + name: 'isRecordDuplicate', + type: 'boolean', + default: false, + }, + { + displayName: 'Lead Source', + name: 'leadSource', + type: 'options', + typeOptions: { + loadOptionsMethod: 'getLeadSources', + }, + default: '', + }, + { + displayName: 'Lead Status', + name: 'leadStatus', + type: 'options', + typeOptions: { + loadOptionsMethod: 'getLeadStatuses' + }, + default: '', + }, + { + displayName: 'Mobile', + name: 'mobile', + type: 'string', + default: '', + }, + { + displayName: 'No. of Employees', + name: 'numberOfEmployees', + type: 'number', + default: 1, + }, + { + displayName: 'Owner', + name: 'owner', + type: 'options', + default: '', + typeOptions: { + loadOptionsMethod: 'getUsers', + }, }, { displayName: 'Phone', name: 'phone', type: 'string', default: '', - description: 'The phone number of the user', }, { - displayName: 'Unsubscribed From Emails', - name: 'unsubscribedFromEmails', - type: 'boolean', - default: false, - description: 'Whether the Lead is unsubscribed from emails', - }, - { - displayName: 'Update Last Request At', - name: 'updateLastRequestAt', - type: 'boolean', - default: false, - description: 'A boolean value, which if true, instructs Intercom to update the
users last_request_at value to the current API service time in
UTC. default value if not sent is false.', - }, - { - displayName: 'Companies', - name: 'companies', - type: 'multiOptions', - typeOptions: { - loadOptionsMethod: 'getCompanies', - }, - default: [], - description: 'Identifies the companies this user belongs to.', - }, - { - displayName: 'UTM Source', - name: 'utmSource', + displayName: 'Salutation', + name: 'salutation', type: 'string', default: '', - description: 'An avatar image URL. note: the image url needs to be https.', }, { - displayName: 'UTM Medium', - name: 'utmMedium', + displayName: 'Secondary Email', + name: 'secondaryEmail', type: 'string', default: '', - description: 'Identifies what type of link was used', }, { - displayName: 'UTM Campaign', - name: 'utmCampaign', + displayName: 'Skype ID', + name: 'SkypeId', type: 'string', default: '', - description: 'Identifies a specific product promotion or strategic campaign', }, { - displayName: 'UTM Term', - name: 'utmTerm', + displayName: 'Title', + name: 'title', type: 'string', default: '', - description: 'Identifies search terms', }, { - displayName: 'UTM Content', - name: 'utmContent', + displayName: 'Twitter', + name: 'twitter', + type: 'string', + default: '', + }, + { + displayName: 'Website', + name: 'website', type: 'string', default: '', - description: 'Identifies what specifically was clicked to bring the user to the site', }, ] }, - + { + displayName: 'Address', + name: 'addressUi', + type: 'fixedCollection', + default: {}, + placeholder: 'Add Address', + typeOptions: { + multipleValues: false, + }, + required: false, + displayOptions: { + show: { + resource: [ + 'lead', + ], + operation: [ + 'create', + ], + }, + }, + options: [ + { + name: 'addressValues', + displayName: 'Address', + values: [ + { + displayName: 'Street', + name: 'street', + type: 'string', + default: '', + }, + { + displayName: 'City', + name: 'city', + type: 'string', + default: '', + }, + { + displayName: 'State', + name: 'state', + type: 'string', + default: '', + }, + { + displayName: 'Country', + name: 'country', + type: 'string', + default: '', + }, + { + displayName: 'Zip Code', + name: 'zipCode', + type: 'string', + default: '', + }, + ], + } + ], + }, +/* -------------------------------------------------------------------------- */ +/* lead:update */ +/* -------------------------------------------------------------------------- */ + { + displayName: 'Lead ID', + name: 'leadId', + type: 'string', + default: '', + required: true, + displayOptions: { + show: { + resource: [ + 'lead', + ], + operation: [ + 'update', + ], + }, + }, + }, + { + displayName: 'Additional Fields', + name: 'additionalFields', + type: 'collection', + placeholder: 'Add Field', + default: {}, + displayOptions: { + show: { + operation: [ + 'update', + ], + resource: [ + 'lead', + ], + }, + }, + options: [ + { + displayName: 'Annual Revenue', + name: 'annualRevenue', + type: 'number', + typeOptions: { + numberPrecision: 2, + }, + default: 0, + }, + { + displayName: 'Company', + name: 'company', + type: 'string', + default: '', + }, + { + displayName: 'Description', + name: 'description', + type: 'string', + default: '', + }, + { + displayName: 'Email', + name: 'email', + type: 'string', + default: '', + }, + { + displayName: 'Email Opt Out', + name: 'emailOptOut', + type: 'boolean', + default: false, + }, + { + displayName: 'Fax', + name: 'fax', + type: 'string', + default: '', + }, + { + displayName: 'First Name', + name: 'firstName', + type: 'string', + default: '', + }, + { + displayName: 'Industry', + name: 'industry', + type: 'options', + typeOptions: { + loadOptionsMethod: 'getIndustries', + }, + default: '', + }, + { + displayName: 'Is Record Duplicate', + name: 'isRecordDuplicate', + type: 'boolean', + default: false, + }, + { + displayName: 'Last Name', + name: 'lastName', + type: 'string', + default: '', + description: `User's last name`, + }, + { + displayName: 'Lead Source', + name: 'leadSource', + type: 'options', + typeOptions: { + loadOptionsMethod: 'getLeadSources', + }, + default: '', + }, + { + displayName: 'Lead Status', + name: 'leadStatus', + type: 'options', + typeOptions: { + loadOptionsMethod: 'getLeadStatuses' + }, + default: '', + }, + { + displayName: 'Mobile', + name: 'mobile', + type: 'string', + default: '', + }, + { + displayName: 'No. of Employees', + name: 'numberOfEmployees', + type: 'number', + default: 1, + }, + { + displayName: 'Owner', + name: 'owner', + type: 'options', + default: '', + typeOptions: { + loadOptionsMethod: 'getUsers', + }, + }, + { + displayName: 'Phone', + name: 'phone', + type: 'string', + default: '', + }, + { + displayName: 'Salutation', + name: 'salutation', + type: 'string', + default: '', + }, + { + displayName: 'Secondary Email', + name: 'secondaryEmail', + type: 'string', + default: '', + }, + { + displayName: 'Skype ID', + name: 'SkypeId', + type: 'string', + default: '', + }, + { + displayName: 'Title', + name: 'title', + type: 'string', + default: '', + }, + { + displayName: 'Twitter', + name: 'twitter', + type: 'string', + default: '', + }, + { + displayName: 'Website', + name: 'website', + type: 'string', + default: '', + }, + ] + }, + { + displayName: 'Address', + name: 'addressUi', + type: 'fixedCollection', + default: {}, + placeholder: 'Add Address', + typeOptions: { + multipleValues: false, + }, + required: false, + displayOptions: { + show: { + resource: [ + 'lead', + ], + operation: [ + 'update', + ], + }, + }, + options: [ + { + name: 'addressValues', + displayName: 'Address', + values: [ + { + displayName: 'Street', + name: 'street', + type: 'string', + default: '', + }, + { + displayName: 'City', + name: 'city', + type: 'string', + default: '', + }, + { + displayName: 'State', + name: 'state', + type: 'string', + default: '', + }, + { + displayName: 'Country', + name: 'country', + type: 'string', + default: '', + }, + { + displayName: 'Zip Code', + name: 'zipCode', + type: 'string', + default: '', + }, + ], + } + ], + }, +/* -------------------------------------------------------------------------- */ +/* lead:get */ +/* -------------------------------------------------------------------------- */ + { + displayName: 'Lead ID', + name: 'leadId', + type: 'string', + default: '', + required: true, + displayOptions: { + show: { + resource: [ + 'lead', + ], + operation: [ + 'get', + ], + }, + }, + }, +/* -------------------------------------------------------------------------- */ +/* lead:getAll */ +/* -------------------------------------------------------------------------- */ + { + displayName: 'Return All', + name: 'returnAll', + type: 'boolean', + displayOptions: { + show: { + resource: [ + 'lead', + ], + 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: [ + 'lead', + ], + operation: [ + 'getAll', + ], + returnAll: [ + false, + ], + }, + }, + typeOptions: { + minValue: 1, + maxValue: 200, + }, + default: 100, + description: 'How many results to return.', + }, + { + displayName: 'Options', + name: 'options', + type: 'collection', + placeholder: 'Add Option', + default: {}, + displayOptions: { + show: { + resource: [ + 'lead', + ], + operation: [ + 'getAll', + ], + }, + }, + options: [ + { + displayName: 'Approved', + name: 'approved', + type: 'boolean', + default: true, + description: 'To get the list of approved records. Default value is true.', + }, + { + displayName: 'Converted', + name: 'converted', + type: 'boolean', + default: false, + description: 'To get the list of converted records. Default value is false', + }, + { + displayName: 'Fields', + name: 'fields', + type: 'multiOptions', + typeOptions: { + loadOptionsMethod: 'getLeadFields', + }, + default: [], + }, + { + displayName: 'Include Child', + name: 'includeChild', + type: 'boolean', + default: false, + description: 'To include records from the child territories. True includes child territory records', + }, + { + displayName: 'Sort Order', + name: 'sortOrder', + type: 'options', + options: [ + { + name: 'ASC', + value: 'asc', + }, + { + name: 'DESC', + value: 'desc', + }, + ], + default: 'desc', + description: 'Order sort attribute ascending or descending.', + }, + { + displayName: 'Sort By', + name: 'sortBy', + type: 'multiOptions', + typeOptions: { + loadOptionsMethod: 'getLeadFields', + }, + default: [], + }, + { + displayName: 'Territory ID', + name: 'territoryId', + type: 'string', + default: '', + description: 'To get the list of records based on the territory ', + }, + ] + }, +/* -------------------------------------------------------------------------- */ +/* lead:delete */ +/* -------------------------------------------------------------------------- */ + { + displayName: 'Lead ID', + name: 'leadId', + type: 'string', + default: '', + required: true, + displayOptions: { + show: { + resource: [ + 'lead', + ], + operation: [ + 'delete', + ], + }, + }, + }, ] as INodeProperties[]; diff --git a/packages/nodes-base/nodes/Zoho/LeadInterface.ts b/packages/nodes-base/nodes/Zoho/LeadInterface.ts new file mode 100644 index 0000000000..957f816cb6 --- /dev/null +++ b/packages/nodes-base/nodes/Zoho/LeadInterface.ts @@ -0,0 +1,37 @@ +export interface ILead { + Annual_Revenue?: number; + City?: string; + Company?: string; + Country?: string; + Description?: string; + Designation?: string; + Email?: string; + Email_Opt_Out?: boolean; + Fax?: string; + First_Name?: string; + Industry?: string; + Is_Record_Duplicate?: boolean; + Last_Name?: string; + Lead_Owner?: string; + Lead_Source?: string; + Lead_Status?: string; + Mobile?: string; + No_of_Employees?: number; + Phone?: string; + Salutation?: string; + Secondary_Email?: string; + Skype_ID?: string; + State?: string; + Street?: string; + Twitter?: string; + Website?: string; + Zip_Code?: string; +} + +export interface IAddress { + street?: string; + city?: string; + state?: string; + country?: string; + zipCode?: string; +} diff --git a/packages/nodes-base/nodes/Zoho/ZohoCrm.node.ts b/packages/nodes-base/nodes/Zoho/ZohoCrm.node.ts index f1d397c2dc..20a04295e0 100644 --- a/packages/nodes-base/nodes/Zoho/ZohoCrm.node.ts +++ b/packages/nodes-base/nodes/Zoho/ZohoCrm.node.ts @@ -7,6 +7,8 @@ import { INodeExecutionData, INodeTypeDescription, INodeType, + ILoadOptionsFunctions, + INodePropertyOptions, } from 'n8n-workflow'; import { @@ -19,6 +21,11 @@ import { leadFields, } from './LeadDescription'; +import { + ILead, + IAddress, +} from './LeadInterface'; + export class ZohoCrm implements INodeType { description: INodeTypeDescription = { displayName: 'Zoho CRM', @@ -59,34 +66,370 @@ export class ZohoCrm implements INodeType { ], }; + methods = { + loadOptions: { + // Get all the available users to display them to user so that he can + // select them easily + async getUsers(this: ILoadOptionsFunctions): Promise { + const returnData: INodePropertyOptions[] = []; + const { users } = await zohoApiRequest.call(this, 'GET', '/users', {}, { type: 'AllUsers' }); + for (const user of users) { + const userName = `${user.first_name} ${user.last_name}`; + const userId = user.profile.id; + returnData.push({ + name: userName, + value: userId, + }); + } + return returnData; + }, + // Get all the available accounts to display them to user so that he can + // select them easily + async getAccounts(this: ILoadOptionsFunctions): Promise { + const returnData: INodePropertyOptions[] = []; + const qs: IDataObject = {}; + qs.sort_by = 'Created_Time'; + qs.sort_order = 'desc'; + const { data } = await zohoApiRequest.call(this, 'GET', '/accounts', {}, qs); + for (const account of data) { + const accountName = account.Account_Name + const accountId = account.id; + returnData.push({ + name: accountName, + value: accountId, + }); + } + return returnData; + }, + // Get all the available lead statuses to display them to user so that he can + // select them easily + async getLeadStatuses(this: ILoadOptionsFunctions): Promise { + const returnData: INodePropertyOptions[] = []; + const qs: IDataObject = {}; + qs.module = 'leads'; + const { fields } = await zohoApiRequest.call(this, 'GET', '/settings/fields', {}, qs); + for (const field of fields) { + if (field.api_name === 'Lead_Status') { + for (const value of field.pick_list_values) { + const valueName = value.display_value + const valueId = value.actual_value; + returnData.push({ + name: valueName, + value: valueId, + }); + return returnData; + } + } + } + return returnData; + }, + // Get all the available lead sources to display them to user so that he can + // select them easily + async getLeadSources(this: ILoadOptionsFunctions): Promise { + const returnData: INodePropertyOptions[] = []; + const qs: IDataObject = {}; + qs.module = 'leads'; + const { fields } = await zohoApiRequest.call(this, 'GET', '/settings/fields', {}, qs); + for (const field of fields) { + if (field.api_name === 'Lead_Source') { + for (const value of field.pick_list_values) { + const valueName = value.display_value + const valueId = value.actual_value; + returnData.push({ + name: valueName, + value: valueId, + }); + return returnData; + } + } + } + return returnData; + }, + // Get all the available industries to display them to user so that he can + // select them easily + async getIndustries(this: ILoadOptionsFunctions): Promise { + const returnData: INodePropertyOptions[] = []; + const qs: IDataObject = {}; + qs.module = 'leads'; + const { fields } = await zohoApiRequest.call(this, 'GET', '/settings/fields', {}, qs); + for (const field of fields) { + if (field.api_name === 'Industry') { + for (const value of field.pick_list_values) { + const valueName = value.display_value + const valueId = value.actual_value; + returnData.push({ + name: valueName, + value: valueId, + }); + return returnData; + } + } + } + return returnData; + }, + // Get all the available lead fields to display them to user so that he can + // select them easily + async getLeadFields(this: ILoadOptionsFunctions): Promise { + const returnData: INodePropertyOptions[] = []; + const qs: IDataObject = {}; + qs.module = 'leads'; + const { fields } = await zohoApiRequest.call(this, 'GET', '/settings/fields', {}, qs); + for (const field of fields) { + returnData.push({ + name: field.field_label, + value: field.api_name, + }); + } + return returnData; + }, + }, + }; + 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; for (let i = 0; i < length; i++) { const resource = this.getNodeParameter('resource', 0) as string; const operation = this.getNodeParameter('operation', 0) as string; if (resource === 'lead') { + //https://www.zoho.com/crm/developer/docs/api/insert-records.html if (operation === 'create') { const lastName = this.getNodeParameter('lastName', i) as string; const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const body = { + const body: ILead = { Last_Name: lastName, }; - // if (additionalFields.email) { - // // @ts-ignore - // body.email = additionalFields.email as string; - // } + if (additionalFields.owner) { + body.Lead_Owner = additionalFields.owner as string; + } + if (additionalFields.company) { + body.Company = additionalFields.company as string; + } + if (additionalFields.firstName) { + body.First_Name = additionalFields.firstName as string; + } + if (additionalFields.email) { + body.Email = additionalFields.email as string; + } + if (additionalFields.title) { + body.Designation = additionalFields.title as string; + } + if (additionalFields.phone) { + body.Phone = additionalFields.phone as string; + } + if (additionalFields.mobile) { + body.Mobile = additionalFields.mobile as string; + } + if (additionalFields.leadStatus) { + body.Lead_Status = additionalFields.leadStatus as string; + } + if (additionalFields.fax) { + body.Fax = additionalFields.fax as string; + } + if (additionalFields.website) { + body.Website = additionalFields.website as string; + } + if (additionalFields.leadSource) { + body.Lead_Source = additionalFields.leadSource as string; + } + if (additionalFields.industry) { + body.Industry = additionalFields.industry as string; + } + if (additionalFields.numberOfEmployees) { + body.No_of_Employees = additionalFields.numberOfEmployees as number; + } + if (additionalFields.annualRevenue) { + body.Annual_Revenue = additionalFields.annualRevenue as number; + } + if (additionalFields.emailOptOut) { + body.Email_Opt_Out = additionalFields.emailOptOut as boolean; + } + if (additionalFields.skypeId) { + body.Skype_ID = additionalFields.skypeId as string; + } + if (additionalFields.salutation) { + body.Salutation = additionalFields.salutation as string; + } + if (additionalFields.secondaryEmail) { + body.Secondary_Email = additionalFields.secondaryEmail as string; + } + if (additionalFields.twitter) { + body.Twitter = additionalFields.twitter as string; + } + if (additionalFields.isRecordDuplicate) { + body.Is_Record_Duplicate = additionalFields.isRecordDuplicate as boolean; + } + if (additionalFields.description) { + body.Description = additionalFields.description as string; + } + const address = (this.getNodeParameter('addressUi', i) as IDataObject).addressValues as IAddress; + if (address) { + if (address.country) { + body.Country = address.country as string; + } + if (address.city) { + body.City = address.city as string; + } + if (address.state) { + body.State = address.state as string; + } + if (address.street) { + body.Street = address.street as string; + } + if (address.zipCode) { + body.Zip_Code = address.zipCode as string; + } + } responseData = await zohoApiRequest.call(this, 'POST', '/leads', body); responseData = responseData.data; - } else { - throw new Error(`The operation "${operation}" is not known!`); } - } else { - throw new Error(`The resource "${resource}" is not known!`); + //https://www.zoho.com/crm/developer/docs/api/update-specific-record.html + if (operation === 'update') { + const leadId = this.getNodeParameter('leadId', i) as string; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const body: ILead = {}; + if (additionalFields.lastName) { + body.Last_Name = additionalFields.lastName as string; + } + if (additionalFields.owner) { + body.Lead_Owner = additionalFields.owner as string; + } + if (additionalFields.company) { + body.Company = additionalFields.company as string; + } + if (additionalFields.firstName) { + body.First_Name = additionalFields.firstName as string; + } + if (additionalFields.email) { + body.Email = additionalFields.email as string; + } + if (additionalFields.title) { + body.Designation = additionalFields.title as string; + } + if (additionalFields.phone) { + body.Phone = additionalFields.phone as string; + } + if (additionalFields.mobile) { + body.Mobile = additionalFields.mobile as string; + } + if (additionalFields.leadStatus) { + body.Lead_Status = additionalFields.leadStatus as string; + } + if (additionalFields.fax) { + body.Fax = additionalFields.fax as string; + } + if (additionalFields.website) { + body.Website = additionalFields.website as string; + } + if (additionalFields.leadSource) { + body.Lead_Source = additionalFields.leadSource as string; + } + if (additionalFields.industry) { + body.Industry = additionalFields.industry as string; + } + if (additionalFields.numberOfEmployees) { + body.No_of_Employees = additionalFields.numberOfEmployees as number; + } + if (additionalFields.annualRevenue) { + body.Annual_Revenue = additionalFields.annualRevenue as number; + } + if (additionalFields.emailOptOut) { + body.Email_Opt_Out = additionalFields.emailOptOut as boolean; + } + if (additionalFields.skypeId) { + body.Skype_ID = additionalFields.skypeId as string; + } + if (additionalFields.salutation) { + body.Salutation = additionalFields.salutation as string; + } + if (additionalFields.secondaryEmail) { + body.Secondary_Email = additionalFields.secondaryEmail as string; + } + if (additionalFields.twitter) { + body.Twitter = additionalFields.twitter as string; + } + if (additionalFields.isRecordDuplicate) { + body.Is_Record_Duplicate = additionalFields.isRecordDuplicate as boolean; + } + if (additionalFields.description) { + body.Description = additionalFields.description as string; + } + const address = (this.getNodeParameter('addressUi', i) as IDataObject).addressValues as IAddress; + if (address) { + if (address.country) { + body.Country = address.country as string; + } + if (address.city) { + body.City = address.city as string; + } + if (address.state) { + body.State = address.state as string; + } + if (address.street) { + body.Street = address.street as string; + } + if (address.zipCode) { + body.Zip_Code = address.zipCode as string; + } + } + responseData = await zohoApiRequest.call(this, 'PUT', `/leads/${leadId}`, body); + responseData = responseData.data; + } + //https://www.zoho.com/crm/developer/docs/api/update-specific-record.html + if (operation === 'get') { + const leadId = this.getNodeParameter('leadId', i) as string; + responseData = await zohoApiRequest.call(this, 'GET', `/leads/${leadId}`); + responseData = responseData.data; + } + //https://www.zoho.com/crm/developer/docs/api/get-records.html + if (operation === 'getAll') { + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + const options = this.getNodeParameter('options', i) as IDataObject; + if (options.fields) { + qs.fields = (options.fields as string[]).join(','); + } + if (options.approved) { + qs.approved = options.approved as boolean; + } + if (options.converted) { + qs.converted = options.converted as boolean; + } + if (options.includeChild) { + qs.include_child = options.includeChild as boolean; + } + if (options.sortOrder) { + qs.sort_order = options.sortOrder as string; + } + if (options.sortBy) { + qs.sort_by = options.sortBy as string; + } + if (options.territoryId) { + qs.territory_id = options.territoryId as string; + } + if (returnAll) { + responseData = await zohoApiRequestAllItems.call(this, 'data', 'GET', '/leads', {}, qs); + } else { + qs.per_page = this.getNodeParameter('limit', i) as number; + responseData = await zohoApiRequest.call(this, 'GET', '/leads', {}, qs); + responseData = responseData.data; + } + } + //https://www.zoho.com/crm/developer/docs/api/delete-specific-record.html + if (operation === 'delete') { + const leadId = this.getNodeParameter('leadId', i) as string; + responseData = await zohoApiRequest.call(this, 'DELETE', `/leads/${leadId}`); + responseData = responseData.data; + } + //https://www.zoho.com/crm/developer/docs/api/field-meta.html + if (operation === 'getFields') { + qs.module = 'leads'; + responseData = await zohoApiRequest.call(this, 'GET', '/settings/fields', {}, qs); + responseData = responseData.fields; + } } - if (Array.isArray(responseData)) { returnData.push.apply(returnData, responseData as IDataObject[]); } else if (responseData !== undefined) { From b3a9eb08c1aabace44d3beea46d53f9e1cc2a8a9 Mon Sep 17 00:00:00 2001 From: Ricardo Espinoza Date: Sat, 15 Feb 2020 19:25:14 -0500 Subject: [PATCH 2/2] :zap: small fix --- packages/nodes-base/nodes/Zoho/GenericFunctions.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/nodes-base/nodes/Zoho/GenericFunctions.ts b/packages/nodes-base/nodes/Zoho/GenericFunctions.ts index 3d20a3ec02..4deea5f6f5 100644 --- a/packages/nodes-base/nodes/Zoho/GenericFunctions.ts +++ b/packages/nodes-base/nodes/Zoho/GenericFunctions.ts @@ -7,7 +7,6 @@ import { import { IDataObject } from 'n8n-workflow'; -import { queryResult } from 'pg-promise'; export async function zohoApiRequest(this: IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions, method: string, resource: string, body: any = {}, qs: IDataObject = {}, uri?: string, option: IDataObject = {}): Promise { // tslint:disable-line:no-any const options: OptionsWithUri = {