diff --git a/packages/nodes-base/nodes/Salesforce/FlowDescription.ts b/packages/nodes-base/nodes/Salesforce/FlowDescription.ts new file mode 100644 index 0000000000..5e822d6e76 --- /dev/null +++ b/packages/nodes-base/nodes/Salesforce/FlowDescription.ts @@ -0,0 +1,184 @@ +import { + INodeProperties, +} from 'n8n-workflow'; + +export const flowOperations = [ + { + displayName: 'Operation', + name: 'operation', + type: 'options', + displayOptions: { + show: { + resource: [ + 'flow', + ], + }, + }, + options: [ + { + name: 'Get All', + value: 'getAll', + description: 'Get all flows', + }, + { + name: 'Invoke', + value: 'invoke', + description: 'Invoke a flow', + }, + ], + default: 'invoke', + description: 'The operation to perform.', + }, +] as INodeProperties[]; + +export const flowFields = [ + +/* -------------------------------------------------------------------------- */ +/* flow:getAll */ +/* -------------------------------------------------------------------------- */ + { + displayName: 'Return All', + name: 'returnAll', + type: 'boolean', + displayOptions: { + show: { + operation: [ + 'getAll', + ], + resource: [ + 'flow', + ], + }, + }, + default: false, + description: 'If all results should be returned or only up to a given limit.', + }, + { + displayName: 'Limit', + name: 'limit', + type: 'number', + displayOptions: { + show: { + operation: [ + 'getAll', + ], + resource: [ + 'flow', + ], + returnAll: [ + false, + ], + }, + }, + typeOptions: { + minValue: 1, + maxValue: 500, + }, + default: 100, + description: 'How many results to return.', + }, +/* -------------------------------------------------------------------------- */ +/* flow:invoke */ +/* -------------------------------------------------------------------------- */ + { + displayName: 'API Name', + name: 'apiName', + type: 'string', + default: '', + required: true, + displayOptions: { + show: { + resource: [ + 'flow', + ], + operation: [ + 'invoke' + ], + }, + }, + description: 'Required. API name of the flow.', + }, + { + displayName: 'JSON Parameters', + name: 'jsonParameters', + type: 'boolean', + default: false, + displayOptions: { + show: { + resource: [ + 'flow', + ], + operation: [ + 'invoke' + ], + }, + }, + description: 'If the input variables should be set via the value-key pair UI or JSON/RAW.', + }, + { + displayName: 'Variables', + name: 'variablesJson', + type: 'json', + displayOptions: { + show: { + resource: [ + 'flow', + ], + operation: [ + 'invoke' + ], + jsonParameters: [ + true, + ], + }, + }, + default: '', + description: 'Input variables as JSON object', + }, + { + displayName: 'Variables', + name: 'variablesUi', + placeholder: 'Add Variable', + type: 'fixedCollection', + typeOptions: { + multipleValues: true, + }, + displayOptions: { + show: { + resource: [ + 'flow', + ], + operation: [ + 'invoke' + ], + jsonParameters: [ + false, + ], + }, + }, + description: 'The input variable to send.', + default: {}, + options: [ + { + displayName: 'Variable', + name: 'variablesValues', + values: [ + { + displayName: 'Name', + name: 'name', + type: 'string', + default: '', + description: 'Name of the input variable.', + }, + { + displayName: 'Value', + name: 'value', + type: 'string', + default: '', + description: 'Value of the input variable.', + }, + ] + }, + ], + }, +] as INodeProperties[]; diff --git a/packages/nodes-base/nodes/Salesforce/Salesforce.node.ts b/packages/nodes-base/nodes/Salesforce/Salesforce.node.ts index 1fafc216d3..8f6873f6ef 100644 --- a/packages/nodes-base/nodes/Salesforce/Salesforce.node.ts +++ b/packages/nodes-base/nodes/Salesforce/Salesforce.node.ts @@ -52,6 +52,11 @@ import { IContact, } from './ContactInterface'; +import { + flowFields, + flowOperations, +} from './FlowDescription'; + import { salesforceApiRequest, salesforceApiRequestAllItems, @@ -144,6 +149,11 @@ export class Salesforce implements INodeType { value: 'contact', description: 'Represents a contact, which is an individual associated with an account.', }, + { + name: 'Flow', + value: 'flow', + description: 'Represents an autolaunched flow.', + }, { name: 'Lead', value: 'lead', @@ -184,6 +194,8 @@ export class Salesforce implements INodeType { ...attachmentFields, ...userOperations, ...userFields, + ...flowOperations, + ...flowFields, ], }; @@ -1944,6 +1956,42 @@ export class Salesforce implements INodeType { } } } + if (resource === 'flow') { + //https://developer.salesforce.com/docs/atlas.en-us.api_action.meta/api_action/actions_obj_flow.htm + if (operation === 'invoke') { + const apiName = this.getNodeParameter('apiName', i) as string; + const jsonParameters = this.getNodeParameter('jsonParameters', i) as boolean; + let variables = {}; + if (jsonParameters) { + variables = this.getNodeParameter('variablesJson', i); + } else { + // Input variables are defined in UI + const setInputVariable = this.getNodeParameter('variablesUi', i, {}) as IDataObject; + if (setInputVariable!.variablesValues !== undefined) { + for (const inputVariableData of setInputVariable!.variablesValues as IDataObject[]) { + // @ts-ignore + variables[inputVariableData!.name as string] = inputVariableData!.value; + } + } + } + const body = { + inputs: [ + variables, + ], + }; + responseData = await salesforceApiRequest.call(this, 'POST', `/actions/custom/flow/${apiName}`, body); + } + //https://developer.salesforce.com/docs/atlas.en-us.api_action.meta/api_action/actions_obj_flow.htm + if (operation === 'getAll') { + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + responseData = await salesforceApiRequest.call(this, 'GET', '/actions/custom/flow'); + responseData = responseData.actions; + if (returnAll === false) { + const limit = this.getNodeParameter('limit', i) as number; + responseData = responseData.splice(0, limit); + } + } + } if (Array.isArray(responseData)) { returnData.push.apply(returnData, responseData as IDataObject[]); } else {