mirror of
https://github.com/n8n-io/n8n.git
synced 2025-02-02 07:01:30 -08:00
⚡ Allow to automatically encode custom values with Pipedrive update
This commit is contained in:
parent
45a21d5ce1
commit
60165d5fe2
|
@ -12,12 +12,18 @@ import { OptionsWithUri } from 'request';
|
||||||
|
|
||||||
export interface ICustomInterface {
|
export interface ICustomInterface {
|
||||||
name: string;
|
name: string;
|
||||||
|
key: string;
|
||||||
options?: Array<{
|
options?: Array<{
|
||||||
id: number;
|
id: number;
|
||||||
label: string;
|
label: string;
|
||||||
}>;
|
}>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface ICustomProperties {
|
||||||
|
[key: string]: ICustomInterface;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Make an API request to Pipedrive
|
* Make an API request to Pipedrive
|
||||||
*
|
*
|
||||||
|
@ -141,15 +147,14 @@ export async function pipedriveApiRequestAllItems(this: IHookFunctions | IExecut
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts names and values of custom properties to their actual values
|
* Gets the custom properties from Pipedrive
|
||||||
*
|
*
|
||||||
* @export
|
* @export
|
||||||
* @param {(IHookFunctions | IExecuteFunctions)} this
|
* @param {(IHookFunctions | IExecuteFunctions)} this
|
||||||
* @param {string} resource
|
* @param {string} resource
|
||||||
* @param {IDataObject[]} items
|
* @returns {Promise<ICustomProperties>}
|
||||||
* @returns {Promise<IDataObject[]>}
|
|
||||||
*/
|
*/
|
||||||
export async function pipedriveResolveCustomProperties(this: IHookFunctions | IExecuteFunctions, resource: string, items: IDataObject[]): Promise<void> {
|
export async function pipedriveGetCustomProperties(this: IHookFunctions | IExecuteFunctions, resource: string): Promise<ICustomProperties> {
|
||||||
|
|
||||||
const endpoints: { [key: string]: string } = {
|
const endpoints: { [key: string]: string } = {
|
||||||
'activity': '/activityFields',
|
'activity': '/activityFields',
|
||||||
|
@ -170,37 +175,83 @@ export async function pipedriveResolveCustomProperties(this: IHookFunctions | IE
|
||||||
// Get the custom properties and their values
|
// Get the custom properties and their values
|
||||||
const responseData = await pipedriveApiRequest.call(this, requestMethod, endpoints[resource], body, qs);
|
const responseData = await pipedriveApiRequest.call(this, requestMethod, endpoints[resource], body, qs);
|
||||||
|
|
||||||
const customProperties: {
|
const customProperties: ICustomProperties = {};
|
||||||
[key: string]: ICustomInterface;
|
|
||||||
} = {};
|
|
||||||
|
|
||||||
for (const customPropertyData of responseData.data) {
|
for (const customPropertyData of responseData.data) {
|
||||||
customProperties[customPropertyData.key] = customPropertyData;
|
customProperties[customPropertyData.key] = customPropertyData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return customProperties;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts names and values of custom properties from their actual values to the
|
||||||
|
* Pipedrive internal ones
|
||||||
|
*
|
||||||
|
* @export
|
||||||
|
* @param {ICustomProperties} customProperties
|
||||||
|
* @param {IDataObject} item
|
||||||
|
*/
|
||||||
|
export function pipedriveEncodeCustomProperties(customProperties: ICustomProperties, item: IDataObject): void {
|
||||||
let customPropertyData;
|
let customPropertyData;
|
||||||
|
|
||||||
for (const item of items) {
|
for (const key of Object.keys(item)) {
|
||||||
// Itterate over all keys and replace the custom ones
|
customPropertyData = Object.values(customProperties).find(customPropertyData => customPropertyData.name === key);
|
||||||
for (const key of Object.keys(item)) {
|
|
||||||
if (customProperties[key] !== undefined) {
|
|
||||||
// Is a custom property
|
|
||||||
customPropertyData = customProperties[key];
|
|
||||||
|
|
||||||
// Check if also the value has to be resolved or just the key
|
if (customPropertyData !== undefined) {
|
||||||
if (item[key] !== null && item[key] !== undefined && customPropertyData.options !== undefined && Array.isArray(customPropertyData.options)) {
|
// Is a custom property
|
||||||
// Has an option key so get the actual option-value
|
|
||||||
const propertyOption = customPropertyData.options.find(option => option.id.toString() === item[key]!.toString());
|
|
||||||
|
|
||||||
if (propertyOption !== undefined) {
|
// Check if also the value has to be resolved or just the key
|
||||||
item[customPropertyData.name as string] = propertyOption.label;
|
if (item[key] !== null && item[key] !== undefined && customPropertyData.options !== undefined && Array.isArray(customPropertyData.options)) {
|
||||||
delete item[key];
|
// Has an option key so get the actual option-value
|
||||||
}
|
const propertyOption = customPropertyData.options.find(option => option.label.toString() === item[key]!.toString());
|
||||||
} else {
|
|
||||||
// Does already represent the actual value or is null
|
if (propertyOption !== undefined) {
|
||||||
item[customPropertyData.name as string] = item[key];
|
item[customPropertyData.key as string] = propertyOption.id;
|
||||||
delete item[key];
|
delete item[key];
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// Does already represent the actual value or is null
|
||||||
|
item[customPropertyData.key as string] = item[key];
|
||||||
|
delete item[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts names and values of custom properties to their actual values
|
||||||
|
*
|
||||||
|
* @export
|
||||||
|
* @param {ICustomProperties} customProperties
|
||||||
|
* @param {IDataObject} item
|
||||||
|
*/
|
||||||
|
export function pipedriveResolveCustomProperties(customProperties: ICustomProperties, item: IDataObject): void {
|
||||||
|
let customPropertyData;
|
||||||
|
|
||||||
|
// Itterate over all keys and replace the custom ones
|
||||||
|
for (const key of Object.keys(item)) {
|
||||||
|
if (customProperties[key] !== undefined) {
|
||||||
|
// Is a custom property
|
||||||
|
customPropertyData = customProperties[key];
|
||||||
|
|
||||||
|
// Check if also the value has to be resolved or just the key
|
||||||
|
if (item[key] !== null && item[key] !== undefined && customPropertyData.options !== undefined && Array.isArray(customPropertyData.options)) {
|
||||||
|
// Has an option key so get the actual option-value
|
||||||
|
const propertyOption = customPropertyData.options.find(option => option.id.toString() === item[key]!.toString());
|
||||||
|
|
||||||
|
if (propertyOption !== undefined) {
|
||||||
|
item[customPropertyData.name as string] = propertyOption.label;
|
||||||
|
delete item[key];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Does already represent the actual value or is null
|
||||||
|
item[customPropertyData.name as string] = item[key];
|
||||||
|
delete item[key];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,8 +10,11 @@ import {
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
ICustomProperties,
|
||||||
pipedriveApiRequest,
|
pipedriveApiRequest,
|
||||||
pipedriveApiRequestAllItems,
|
pipedriveApiRequestAllItems,
|
||||||
|
pipedriveEncodeCustomProperties,
|
||||||
|
pipedriveGetCustomProperties,
|
||||||
pipedriveResolveCustomProperties,
|
pipedriveResolveCustomProperties,
|
||||||
} from './GenericFunctions';
|
} from './GenericFunctions';
|
||||||
|
|
||||||
|
@ -1960,6 +1963,27 @@ export class Pipedrive implements INodeType {
|
||||||
default: false,
|
default: false,
|
||||||
description: 'By default do custom properties get returned only as ID instead of their actual name. Also option fields contain only the ID instead of their actual value. If this option gets set they get automatically resolved.',
|
description: 'By default do custom properties get returned only as ID instead of their actual name. Also option fields contain only the ID instead of their actual value. If this option gets set they get automatically resolved.',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Encode Properties',
|
||||||
|
name: 'encodeProperties',
|
||||||
|
type: 'boolean',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'activity',
|
||||||
|
'deal',
|
||||||
|
'organization',
|
||||||
|
'person',
|
||||||
|
'product',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'update',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
default: false,
|
||||||
|
description: 'By default do custom properties have to be set as ID instead of their actual name. Also option fields have to be set as ID instead of their actual value. If this option gets set they get automatically encoded.',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
displayName: 'Return All',
|
displayName: 'Return All',
|
||||||
name: 'returnAll',
|
name: 'returnAll',
|
||||||
|
@ -2020,6 +2044,23 @@ export class Pipedrive implements INodeType {
|
||||||
const resource = this.getNodeParameter('resource', 0) as string;
|
const resource = this.getNodeParameter('resource', 0) as string;
|
||||||
const operation = this.getNodeParameter('operation', 0) as string;
|
const operation = this.getNodeParameter('operation', 0) as string;
|
||||||
|
|
||||||
|
let customProperties: ICustomProperties | undefined;
|
||||||
|
if (['get', 'getAll', 'update'].includes(operation) && ['activity', 'deal', 'organization', 'person', 'product'].includes(resource)) {
|
||||||
|
// Request the custom properties once in the beginning to not query it multiple
|
||||||
|
// times if multiple items get updated
|
||||||
|
|
||||||
|
let getCustomProperties = false;
|
||||||
|
if (['update'].includes(operation)) {
|
||||||
|
getCustomProperties = this.getNodeParameter('encodeProperties', 0, false) as boolean;
|
||||||
|
} else {
|
||||||
|
getCustomProperties = this.getNodeParameter('resolveProperties', 0, false) as boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (getCustomProperties === true) {
|
||||||
|
customProperties = await pipedriveGetCustomProperties.call(this, resource);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (let i = 0; i < items.length; i++) {
|
for (let i = 0; i < items.length; i++) {
|
||||||
|
|
||||||
requestMethod = 'GET';
|
requestMethod = 'GET';
|
||||||
|
@ -2415,6 +2456,11 @@ export class Pipedrive implements INodeType {
|
||||||
if (returnAll === true) {
|
if (returnAll === true) {
|
||||||
responseData = await pipedriveApiRequestAllItems.call(this, requestMethod, endpoint, body, qs);
|
responseData = await pipedriveApiRequestAllItems.call(this, requestMethod, endpoint, body, qs);
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
if (customProperties !== undefined) {
|
||||||
|
pipedriveEncodeCustomProperties(customProperties!, body);
|
||||||
|
}
|
||||||
|
|
||||||
responseData = await pipedriveApiRequest.call(this, requestMethod, endpoint, body, qs, formData, downloadFile);
|
responseData = await pipedriveApiRequest.call(this, requestMethod, endpoint, body, qs, formData, downloadFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2445,11 +2491,9 @@ export class Pipedrive implements INodeType {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (['get', 'getAll'].includes(operation) && ['activity', 'deal', 'organization', 'person', 'product'].includes(resource)) {
|
if (customProperties !== undefined) {
|
||||||
const resolveProperties = this.getNodeParameter('resolveProperties', 0) as boolean;
|
for (const item of returnData) {
|
||||||
|
await pipedriveResolveCustomProperties(customProperties, item);
|
||||||
if (resolveProperties === true) {
|
|
||||||
await pipedriveResolveCustomProperties.call(this, resource, returnData);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue