Add salesforce custom objects and custom fields (#1061)

This commit is contained in:
Ricardo Espinoza 2020-10-16 04:27:09 -04:00 committed by GitHub
parent b40dec3e4a
commit 86d5681517
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 1011 additions and 11 deletions

View file

@ -1,4 +1,6 @@
import { INodeProperties } from 'n8n-workflow';
import {
INodeProperties,
} from 'n8n-workflow';
export const accountOperations = [
{
@ -149,6 +151,42 @@ export const accountFields = [
default: '',
description: 'Street address for the billing address of this account.',
},
{
displayName: 'Custom Fields',
name: 'customFieldsUi',
placeholder: 'Add Custom Field',
type: 'fixedCollection',
typeOptions: {
multipleValues: true,
},
description: 'Filter by custom fields ',
default: {},
options: [
{
name: 'customFieldsValues',
displayName: 'Custom Field',
values: [
{
displayName: 'Field ID',
name: 'fieldId',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getLeadCustomFields',
},
default: '',
description: 'The ID of the field to add custom field to.',
},
{
displayName: 'Value',
name: 'value',
type: 'string',
default: '',
description: 'The value to set on custom field.',
},
],
},
],
},
{
displayName: 'Description',
name: 'description',
@ -367,6 +405,42 @@ export const accountFields = [
default: '',
description: 'Street address for the billing address of this account.',
},
{
displayName: 'Custom Fields',
name: 'customFieldsUi',
placeholder: 'Add Custom Field',
type: 'fixedCollection',
typeOptions: {
multipleValues: true,
},
description: 'Filter by custom fields ',
default: {},
options: [
{
name: 'customFieldsValues',
displayName: 'Custom Field',
values: [
{
displayName: 'Field ID',
name: 'fieldId',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getLeadCustomFields',
},
default: '',
description: 'The ID of the field to add custom field to.',
},
{
displayName: 'Value',
name: 'value',
type: 'string',
default: '',
description: 'The value to set on custom field.',
},
],
},
],
},
{
displayName: 'Description',
name: 'description',

View file

@ -1,4 +1,6 @@
import { INodeProperties } from 'n8n-workflow';
import {
INodeProperties,
} from 'n8n-workflow';
export const contactOperations = [
{
@ -62,7 +64,7 @@ export const contactOperations = [
export const contactFields = [
/* -------------------------------------------------------------------------- */
/* contact:create */
/* contact:create */
/* -------------------------------------------------------------------------- */
{
displayName: 'Last Name',
@ -130,6 +132,42 @@ export const contactFields = [
default: '',
description: 'The birth date of the contact.',
},
{
displayName: 'Custom Fields',
name: 'customFieldsUi',
placeholder: 'Add Custom Field',
type: 'fixedCollection',
typeOptions: {
multipleValues: true,
},
description: 'Filter by custom fields ',
default: {},
options: [
{
name: 'customFieldsValues',
displayName: 'Custom Field',
values: [
{
displayName: 'Field ID',
name: 'fieldId',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getLeadCustomFields',
},
default: '',
description: 'The ID of the field to add custom field to.',
},
{
displayName: 'Value',
name: 'value',
type: 'string',
default: '',
description: 'The value to set on custom field.',
},
],
},
],
},
{
displayName: 'Department',
name: 'department',
@ -314,7 +352,7 @@ export const contactFields = [
],
},
/* -------------------------------------------------------------------------- */
/* contact:update */
/* contact:update */
/* -------------------------------------------------------------------------- */
{
displayName: 'Contact ID',
@ -382,6 +420,42 @@ export const contactFields = [
default: '',
description: 'The birth date of the contact.',
},
{
displayName: 'Custom Fields',
name: 'customFieldsUi',
placeholder: 'Add Custom Field',
type: 'fixedCollection',
typeOptions: {
multipleValues: true,
},
description: 'Filter by custom fields ',
default: {},
options: [
{
name: 'customFieldsValues',
displayName: 'Custom Field',
values: [
{
displayName: 'Field ID',
name: 'fieldId',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getLeadCustomFields',
},
default: '',
description: 'The ID of the field to add custom field to.',
},
{
displayName: 'Value',
name: 'value',
type: 'string',
default: '',
description: 'The value to set on custom field.',
},
],
},
],
},
{
displayName: 'Department',
name: 'department',

View file

@ -0,0 +1,396 @@
import {
INodeProperties,
} from 'n8n-workflow';
export const customObjectOperations = [
{
displayName: 'Operation',
name: 'operation',
type: 'options',
displayOptions: {
show: {
resource: [
'customObject',
],
},
},
options: [
{
name: 'Create',
value: 'create',
description: 'Create a custom object record',
},
{
name: 'Get',
value: 'get',
description: 'Get a custom object record',
},
{
name: 'Get All',
value: 'getAll',
description: 'Get all custom object records',
},
{
name: 'Delete',
value: 'delete',
description: 'Delete a custom object record',
},
{
name: 'Update',
value: 'update',
description: 'Update a custom object record',
},
],
default: 'create',
description: 'The operation to perform.',
},
] as INodeProperties[];
export const customObjectFields = [
/* -------------------------------------------------------------------------- */
/* customObject:create */
/* -------------------------------------------------------------------------- */
{
displayName: 'Custom Object',
name: 'customObject',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getCustomObjects',
},
required: true,
default: '',
displayOptions: {
show: {
resource: [
'customObject',
],
operation: [
'create',
],
},
},
description: 'Name of the custom object',
},
{
displayName: 'Fields',
name: 'customFieldsUi',
placeholder: 'Add Field',
type: 'fixedCollection',
typeOptions: {
multipleValues: true,
},
displayOptions: {
show: {
resource: [
'customObject',
],
operation: [
'create',
],
},
},
description: 'Filter by custom fields ',
default: {},
options: [
{
name: 'customFieldsValues',
displayName: 'Custom Field',
values: [
{
displayName: 'Field ID',
name: 'fieldId',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getCustomObjectFields',
loadOptionsDependsOn: [
'customObject',
],
},
default: '',
description: 'The ID of the field.',
},
{
displayName: 'Value',
name: 'value',
type: 'string',
default: '',
description: 'The value to set on custom field.',
},
],
},
],
},
/* -------------------------------------------------------------------------- */
/* customObject:update */
/* -------------------------------------------------------------------------- */
{
displayName: 'Custom Object',
name: 'customObject',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getCustomObjects',
},
required: true,
default: '',
displayOptions: {
show: {
resource: [
'customObject',
],
operation: [
'update',
],
},
},
description: 'Name of the custom object',
},
{
displayName: 'Record ID',
name: 'recordId',
type: 'string',
required: true,
default: '',
displayOptions: {
show: {
resource: [
'customObject',
],
operation: [
'update',
],
},
},
description: 'Record id to be updated',
},
{
displayName: 'Fields',
name: 'customFieldsUi',
placeholder: 'Add Field',
type: 'fixedCollection',
typeOptions: {
multipleValues: true,
},
description: 'Filter by custom fields ',
default: {},
displayOptions: {
show: {
resource: [
'customObject',
],
operation: [
'update',
],
},
},
options: [
{
name: 'customFieldsValues',
displayName: 'Custom Field',
values: [
{
displayName: 'Field ID',
name: 'fieldId',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getCustomObjectFields',
loadOptionsDependsOn: [
'customObject',
],
},
default: '',
description: 'The ID of the field.',
},
{
displayName: 'Value',
name: 'value',
type: 'string',
default: '',
description: 'The value to set on custom field.',
},
],
},
],
},
/* -------------------------------------------------------------------------- */
/* customObject:get */
/* -------------------------------------------------------------------------- */
{
displayName: 'Custom Object',
name: 'customObject',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getCustomObjects',
},
required: true,
default: '',
displayOptions: {
show: {
resource: [
'customObject',
],
operation: [
'get',
],
},
},
description: 'Name of the custom object',
},
{
displayName: 'Record ID',
name: 'recordId',
type: 'string',
required: true,
default: '',
displayOptions: {
show: {
resource: [
'customObject',
],
operation: [
'get',
],
},
},
description: 'Record id to be retrieved',
},
/* -------------------------------------------------------------------------- */
/* customObject:delete */
/* -------------------------------------------------------------------------- */
{
displayName: 'Custom Object',
name: 'customObject',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getCustomObjects',
},
required: true,
default: '',
displayOptions: {
show: {
resource: [
'customObject',
],
operation: [
'delete',
],
},
},
description: 'Name of the custom object',
},
{
displayName: 'Record ID',
name: 'recordId',
type: 'string',
required: true,
default: '',
displayOptions: {
show: {
resource: [
'customObject',
],
operation: [
'delete',
],
},
},
description: 'Record id to be deleted',
},
/* -------------------------------------------------------------------------- */
/* customObject:getAll */
/* -------------------------------------------------------------------------- */
{
displayName: 'Custom Object',
name: 'customObject',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getCustomObjects',
},
required: true,
default: '',
displayOptions: {
show: {
resource: [
'customObject',
],
operation: [
'getAll',
],
},
},
description: 'Name of the custom object',
},
{
displayName: 'Return All',
name: 'returnAll',
type: 'boolean',
displayOptions: {
show: {
resource: [
'customObject',
],
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: [
'customObject',
],
operation: [
'getAll',
],
returnAll: [
false,
],
},
},
typeOptions: {
minValue: 1,
maxValue: 100,
},
default: 50,
description: 'How many results to return.',
},
{
displayName: 'Options',
name: 'options',
type: 'collection',
placeholder: 'Add Field',
default: {},
displayOptions: {
show: {
resource: [
'customObject',
],
operation: [
'getAll',
],
},
},
options: [
{
displayName: 'Fields',
name: 'fields',
type: 'multiOptions',
typeOptions: {
loadOptionsMethod: 'getCustomObjectFields',
loadOptionsDependsOn: [
'customObject',
],
},
default: '',
description: 'Fields to include separated by ,',
},
],
},
] as INodeProperties[];

View file

@ -17,7 +17,7 @@ export async function salesforceApiRequest(this: IExecuteFunctions | IExecuteSin
const subdomain = ((credentials!.accessTokenUrl as string).match(/https:\/\/(.+).salesforce\.com/) || [])[1];
const options: OptionsWithUri = {
method,
body: method === "GET" ? undefined : body,
body: method === 'GET' ? undefined : body,
qs,
uri: `https://${subdomain}.salesforce.com/services/data/v39.0${uri || endpoint}`,
json: true

View file

@ -1,4 +1,6 @@
import { INodeProperties } from 'n8n-workflow';
import {
INodeProperties,
} from 'n8n-workflow';
export const leadOperations = [
{
@ -77,7 +79,7 @@ export const leadFields = [
],
operation: [
'create',
]
],
},
},
description: 'Company of the lead. If person account record types have been enabled, and if the value of Company is null, the lead converts to a person account.',
@ -95,7 +97,7 @@ export const leadFields = [
],
operation: [
'create',
]
],
},
},
description: 'Required. Last name of the lead. Limited to 80 characters.',
@ -135,6 +137,42 @@ export const leadFields = [
default: '',
description: 'City for the address of the lead.',
},
{
displayName: 'Custom Fields',
name: 'customFieldsUi',
placeholder: 'Add Custom Field',
type: 'fixedCollection',
typeOptions: {
multipleValues: true,
},
description: 'Filter by custom fields ',
default: {},
options: [
{
name: 'customFieldsValues',
displayName: 'Custom Field',
values: [
{
displayName: 'Field ID',
name: 'fieldId',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getLeadCustomFields',
},
default: '',
description: 'The ID of the field to add custom field to.',
},
{
displayName: 'Value',
name: 'value',
type: 'string',
default: '',
description: 'The value to set on custom field.',
},
],
},
],
},
{
displayName: 'Description',
name: 'description',
@ -342,6 +380,42 @@ export const leadFields = [
default: '',
description: 'Company of the lead. If person account record types have been enabled, and if the value of Company is null, the lead converts to a person account.',
},
{
displayName: 'Custom Fields',
name: 'customFieldsUi',
placeholder: 'Add Custom Field',
type: 'fixedCollection',
typeOptions: {
multipleValues: true,
},
description: 'Filter by custom fields ',
default: {},
options: [
{
name: 'customFieldsValues',
displayName: 'Custom Field',
values: [
{
displayName: 'Field ID',
name: 'fieldId',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getLeadCustomFields',
},
default: '',
description: 'The ID of the field to add custom field to.',
},
{
displayName: 'Value',
name: 'value',
type: 'string',
default: '',
description: 'The value to set on custom field.',
},
],
},
],
},
{
displayName: 'Description',
name: 'description',

View file

@ -1,4 +1,6 @@
import { INodeProperties } from 'n8n-workflow';
import {
INodeProperties,
} from 'n8n-workflow';
export const opportunityOperations = [
{
@ -163,6 +165,42 @@ export const opportunityFields = [
default: '',
description: 'Id of the campaign that needs to be fetched',
},
{
displayName: 'Custom Fields',
name: 'customFieldsUi',
placeholder: 'Add Custom Field',
type: 'fixedCollection',
typeOptions: {
multipleValues: true,
},
description: 'Filter by custom fields ',
default: {},
options: [
{
name: 'customFieldsValues',
displayName: 'Custom Field',
values: [
{
displayName: 'Field ID',
name: 'fieldId',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getLeadCustomFields',
},
default: '',
description: 'The ID of the field to add custom field to.',
},
{
displayName: 'Value',
name: 'value',
type: 'string',
default: '',
description: 'The value to set on custom field.',
},
],
},
],
},
{
displayName: 'Description',
name: 'description',
@ -322,6 +360,42 @@ export const opportunityFields = [
default: '',
description: 'Required. Date when the opportunity is expected to close.',
},
{
displayName: 'Custom Fields',
name: 'customFieldsUi',
placeholder: 'Add Custom Field',
type: 'fixedCollection',
typeOptions: {
multipleValues: true,
},
description: 'Filter by custom fields ',
default: {},
options: [
{
name: 'customFieldsValues',
displayName: 'Custom Field',
values: [
{
displayName: 'Field ID',
name: 'fieldId',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getLeadCustomFields',
},
default: '',
description: 'The ID of the field to add custom field to.',
},
{
displayName: 'Value',
name: 'value',
type: 'string',
default: '',
description: 'The value to set on custom field.',
},
],
},
],
},
{
displayName: 'Description',
name: 'description',

View file

@ -52,6 +52,11 @@ import {
IContact,
} from './ContactInterface';
import {
customObjectFields,
customObjectOperations,
} from './CustomObjectDescription';
import {
flowFields,
flowOperations,
@ -149,6 +154,11 @@ export class Salesforce implements INodeType {
value: 'contact',
description: 'Represents a contact, which is an individual associated with an account.',
},
{
name: 'Custom Object',
value: 'customObject',
description: 'Represents a custom object.',
},
{
name: 'Flow',
value: 'flow',
@ -157,7 +167,7 @@ export class Salesforce implements INodeType {
{
name: 'Lead',
value: 'lead',
description: 'Represents a prospect or potential .',
description: 'Represents a prospect or potential.',
},
{
name: 'Opportunity',
@ -182,6 +192,8 @@ export class Salesforce implements INodeType {
...leadFields,
...contactOperations,
...contactFields,
...customObjectOperations,
...customObjectFields,
...opportunityOperations,
...opportunityFields,
...accountOperations,
@ -243,6 +255,13 @@ export class Salesforce implements INodeType {
const returnData: INodePropertyOptions[] = [];
// TODO: find a way to filter this object to get just the lead sources instead of the whole object
const { fields } = await salesforceApiRequest.call(this, 'GET', '/sobjects/lead/describe');
for (const aja of fields as IDataObject[]) {
if (aja.custom === true) {
console.log(aja);
}
}
for (const field of fields) {
if (field.name === 'LeadSource') {
for (const pickValue of field.picklistValues) {
@ -257,6 +276,25 @@ export class Salesforce implements INodeType {
}
return returnData;
},
// Get all the lead custom fields to display them to user so that he can
// select them easily
async getLeadCustomFields(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]> {
const returnData: INodePropertyOptions[] = [];
// TODO: find a way to filter this object to get just the lead sources instead of the whole object
const { fields } = await salesforceApiRequest.call(this, 'GET', '/sobjects/lead/describe');
for (const field of fields) {
if (field.custom === true) {
const fieldName = field.label;
const fieldId = field.name;
returnData.push({
name: fieldName,
value: fieldId,
});
}
}
return returnData;
},
// Get all the accounts to display them to user so that he can
// select them easily
async getAccounts(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]> {
@ -573,6 +611,43 @@ export class Salesforce implements INodeType {
}
return returnData;
},
// Get all the custom objects recurrence instances to display them to user so that he can
// select them easily
async getCustomObjects(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]> {
const returnData: INodePropertyOptions[] = [];
// TODO: find a way to filter this object to get just the lead sources instead of the whole object
const { sobjects: objects } = await salesforceApiRequest.call(this, 'GET', '/sobjects');
for (const object of objects) {
if (object.custom === true) {
const objectName = object.label;
const objectId = object.name;
returnData.push({
name: objectName,
value: objectId,
});
}
}
return returnData;
},
// Get all the custom objects fields recurrence instances to display them to user so that he can
// select them easily
async getCustomObjectFields(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]> {
const returnData: INodePropertyOptions[] = [];
// TODO: find a way to filter this object to get just the lead sources instead of the whole object
const customObject = this.getCurrentNodeParameter('customObject') as string;
const { fields } = await salesforceApiRequest.call(this, 'GET', `/sobjects/${customObject}/describe`);
for (const field of fields) {
const fieldName = field.label;
const fieldId = field.name;
returnData.push({
name: fieldName,
value: fieldId,
});
}
return returnData;
},
},
};
@ -658,6 +733,16 @@ export class Salesforce implements INodeType {
if (additionalFields.numberOfEmployees !== undefined) {
body.NumberOfEmployees = additionalFields.numberOfEmployees as number;
}
if (additionalFields.customFieldsUi) {
const customFields = (additionalFields.customFieldsUi as IDataObject).customFieldsValues as IDataObject[];
if (customFields) {
for (const customField of customFields) {
//@ts-ignore
body[customField.fieldId] = customField.value;
}
}
}
responseData = await salesforceApiRequest.call(this, 'POST', '/sobjects/lead', body);
}
//https://developer.salesforce.com/docs/api-explorer/sobject/Lead/patch-lead-id
@ -737,6 +822,15 @@ export class Salesforce implements INodeType {
if (updateFields.numberOfEmployees !== undefined) {
body.NumberOfEmployees = updateFields.numberOfEmployees as number;
}
if (updateFields.customFieldsUi) {
const customFields = (updateFields.customFieldsUi as IDataObject).customFieldsValues as IDataObject[];
if (customFields) {
for (const customField of customFields) {
//@ts-ignore
body[customField.fieldId] = customField.value;
}
}
}
responseData = await salesforceApiRequest.call(this, 'PATCH', `/sobjects/lead/${leadId}`, body);
}
//https://developer.salesforce.com/docs/api-explorer/sobject/Lead/get-lead-id
@ -912,6 +1006,15 @@ export class Salesforce implements INodeType {
if (additionalFields.emailBouncedReason !== undefined) {
body.EmailBouncedReason = additionalFields.emailBouncedReason as string;
}
if (additionalFields.customFieldsUi) {
const customFields = (additionalFields.customFieldsUi as IDataObject).customFieldsValues as IDataObject[];
if (customFields) {
for (const customField of customFields) {
//@ts-ignore
body[customField.fieldId] = customField.value;
}
}
}
responseData = await salesforceApiRequest.call(this, 'POST', '/sobjects/contact', body);
}
//https://developer.salesforce.com/docs/api-explorer/sobject/Contact/patch-contact-id
@ -1012,6 +1115,15 @@ export class Salesforce implements INodeType {
if (updateFields.emailBouncedReason !== undefined) {
body.EmailBouncedReason = updateFields.emailBouncedReason as string;
}
if (updateFields.customFieldsUi) {
const customFields = (updateFields.customFieldsUi as IDataObject).customFieldsValues as IDataObject[];
if (customFields) {
for (const customField of customFields) {
//@ts-ignore
body[customField.fieldId] = customField.value;
}
}
}
responseData = await salesforceApiRequest.call(this, 'PATCH', `/sobjects/contact/${contactId}`, body);
}
//https://developer.salesforce.com/docs/api-explorer/sobject/Contact/get-contact-id
@ -1089,6 +1201,74 @@ export class Salesforce implements INodeType {
responseData = await salesforceApiRequest.call(this, 'POST', '/sobjects/note', body);
}
}
if (resource === 'customObject') {
if (operation === 'create') {
const customObject = this.getNodeParameter('customObject', i) as string;
const customFieldsUi = this.getNodeParameter('customFieldsUi', i) as IDataObject;
const body: IDataObject = {};
if (customFieldsUi) {
const customFields = (customFieldsUi as IDataObject).customFieldsValues as IDataObject[];
if (customFields) {
for (const customField of customFields) {
//@ts-ignore
body[customField.fieldId] = customField.value;
}
}
}
responseData = await salesforceApiRequest.call(this, 'POST', `/sobjects/${customObject}`, body);
}
if (operation === 'update') {
const recordId = this.getNodeParameter('recordId', i) as string;
const customObject = this.getNodeParameter('customObject', i) as string;
const customFieldsUi = this.getNodeParameter('customFieldsUi', i) as IDataObject;
const body: IDataObject = {};
if (customFieldsUi) {
const customFields = (customFieldsUi as IDataObject).customFieldsValues as IDataObject[];
if (customFields) {
for (const customField of customFields) {
//@ts-ignore
body[customField.fieldId] = customField.value;
}
}
}
responseData = await salesforceApiRequest.call(this, 'PATCH', `/sobjects/${customObject}/${recordId}`, body);
}
if (operation === 'get') {
const customObject = this.getNodeParameter('customObject', i) as string;
const recordId = this.getNodeParameter('recordId', i) as string;
responseData = await salesforceApiRequest.call(this, 'GET', `/sobjects/${customObject}/${recordId}`);
}
if (operation === 'getAll') {
const customObject = this.getNodeParameter('customObject', i) as string;
const returnAll = this.getNodeParameter('returnAll', i) as boolean;
const options = this.getNodeParameter('options', i) as IDataObject;
let fields = ['id'];
if (options.fields) {
fields = options.fields as string[];
}
try {
if (returnAll) {
qs.q = `SELECT ${fields.join(',')} FROM ${customObject}`;
responseData = await salesforceApiRequestAllItems.call(this, 'records', 'GET', '/query', {}, qs);
} else {
const limit = this.getNodeParameter('limit', i) as number;
qs.q = `SELECT ${fields.join(',')} FROM ${customObject} Limit ${limit}`;
responseData = await salesforceApiRequestAllItems.call(this, 'records', 'GET', '/query', {}, qs);
}
} catch(err) {
throw new Error(`Salesforce Error: ${err}`);
}
}
if (operation === 'delete') {
const customObject = this.getNodeParameter('customObject', i) as string;
const recordId = this.getNodeParameter('recordId', i) as string;
try {
responseData = await salesforceApiRequest.call(this, 'DELETE', `/sobjects/${customObject}/${recordId}`);
} catch(err) {
throw new Error(`Salesforce Error: ${err}`);
}
}
}
if (resource === 'opportunity') {
//https://developer.salesforce.com/docs/api-explorer/sobject/Opportunity/post-opportunity
if (operation === 'create') {
@ -1134,6 +1314,15 @@ export class Salesforce implements INodeType {
if (additionalFields.forecastCategoryName !== undefined) {
body.ForecastCategoryName = additionalFields.forecastCategoryName as string;
}
if (additionalFields.customFieldsUi) {
const customFields = (additionalFields.customFieldsUi as IDataObject).customFieldsValues as IDataObject[];
if (customFields) {
for (const customField of customFields) {
//@ts-ignore
body[customField.fieldId] = customField.value;
}
}
}
responseData = await salesforceApiRequest.call(this, 'POST', '/sobjects/opportunity', body);
}
//https://developer.salesforce.com/docs/api-explorer/sobject/Opportunity/post-opportunity
@ -1183,6 +1372,15 @@ export class Salesforce implements INodeType {
if (updateFields.forecastCategoryName !== undefined) {
body.ForecastCategoryName = updateFields.forecastCategoryName as string;
}
if (updateFields.customFieldsUi) {
const customFields = (updateFields.customFieldsUi as IDataObject).customFieldsValues as IDataObject[];
if (customFields) {
for (const customField of customFields) {
//@ts-ignore
body[customField.fieldId] = customField.value;
}
}
}
responseData = await salesforceApiRequest.call(this, 'PATCH', `/sobjects/opportunity/${opportunityId}`, body);
}
//https://developer.salesforce.com/docs/api-explorer/sobject/Opportunity/get-opportunity-id
@ -1326,6 +1524,15 @@ export class Salesforce implements INodeType {
if (additionalFields.shippingPostalCode !== undefined) {
body.ShippingPostalCode = additionalFields.shippingPostalCode as string;
}
if (additionalFields.customFieldsUi) {
const customFields = (additionalFields.customFieldsUi as IDataObject).customFieldsValues as IDataObject[];
if (customFields) {
for (const customField of customFields) {
//@ts-ignore
body[customField.fieldId] = customField.value;
}
}
}
responseData = await salesforceApiRequest.call(this, 'POST', '/sobjects/account', body);
}
//https://developer.salesforce.com/docs/api-explorer/sobject/Account/patch-account-id
@ -1408,6 +1615,15 @@ export class Salesforce implements INodeType {
if (updateFields.shippingPostalCode !== undefined) {
body.ShippingPostalCode = updateFields.shippingPostalCode as string;
}
if (updateFields.customFieldsUi) {
const customFields = (updateFields.customFieldsUi as IDataObject).customFieldsValues as IDataObject[];
if (customFields) {
for (const customField of customFields) {
//@ts-ignore
body[customField.fieldId] = customField.value;
}
}
}
responseData = await salesforceApiRequest.call(this, 'PATCH', `/sobjects/account/${accountId}`, body);
}
//https://developer.salesforce.com/docs/api-explorer/sobject/Account/get-account-id
@ -1708,6 +1924,15 @@ export class Salesforce implements INodeType {
if (additionalFields.recurrenceRegeneratedType !== undefined) {
body.RecurrenceRegeneratedType = additionalFields.recurrenceRegeneratedType as string;
}
if (additionalFields.customFieldsUi) {
const customFields = (additionalFields.customFieldsUi as IDataObject).customFieldsValues as IDataObject[];
if (customFields) {
for (const customField of customFields) {
//@ts-ignore
body[customField.fieldId] = customField.value;
}
}
}
responseData = await salesforceApiRequest.call(this, 'POST', '/sobjects/task', body);
}
//https://developer.salesforce.com/docs/api-explorer/sobject/Task/patch-task-id
@ -1787,6 +2012,15 @@ export class Salesforce implements INodeType {
if (updateFields.recurrenceRegeneratedType !== undefined) {
body.RecurrenceRegeneratedType = updateFields.recurrenceRegeneratedType as string;
}
if (updateFields.customFieldsUi) {
const customFields = (updateFields.customFieldsUi as IDataObject).customFieldsValues as IDataObject[];
if (customFields) {
for (const customField of customFields) {
//@ts-ignore
body[customField.fieldId] = customField.value;
}
}
}
responseData = await salesforceApiRequest.call(this, 'PATCH', `/sobjects/task/${taskId}`, body);
}
//https://developer.salesforce.com/docs/api-explorer/sobject/Task/get-task-id

View file

@ -1,4 +1,6 @@
import { INodeProperties } from 'n8n-workflow';
import {
INodeProperties,
} from 'n8n-workflow';
export const taskOperations = [
{
@ -143,6 +145,42 @@ export const taskFields = [
},
description: 'The type of call being answered: Inbound, Internal, or Outbound.',
},
{
displayName: 'Custom Fields',
name: 'customFieldsUi',
placeholder: 'Add Custom Field',
type: 'fixedCollection',
typeOptions: {
multipleValues: true,
},
description: 'Filter by custom fields ',
default: {},
options: [
{
name: 'customFieldsValues',
displayName: 'Custom Field',
values: [
{
displayName: 'Field ID',
name: 'fieldId',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getLeadCustomFields',
},
default: '',
description: 'The ID of the field to add custom field to.',
},
{
displayName: 'Value',
name: 'value',
type: 'string',
default: '',
description: 'The value to set on custom field.',
},
],
},
],
},
{
displayName: 'Description',
name: 'description',
@ -458,6 +496,42 @@ export const taskFields = [
},
description: 'The type of call being answered: Inbound, Internal, or Outbound.',
},
{
displayName: 'Custom Fields',
name: 'customFieldsUi',
placeholder: 'Add Custom Field',
type: 'fixedCollection',
typeOptions: {
multipleValues: true,
},
description: 'Filter by custom fields ',
default: {},
options: [
{
name: 'customFieldsValues',
displayName: 'Custom Field',
values: [
{
displayName: 'Field ID',
name: 'fieldId',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getLeadCustomFields',
},
default: '',
description: 'The ID of the field to add custom field to.',
},
{
displayName: 'Value',
name: 'value',
type: 'string',
default: '',
description: 'The value to set on custom field.',
},
],
},
],
},
{
displayName: 'Description',
name: 'description',