From e2e57539d6cd24f6dfcc34334af484e1a2963c97 Mon Sep 17 00:00:00 2001 From: MedAliMarz Date: Sat, 17 Jul 2021 09:00:39 +0200 Subject: [PATCH 01/15] :bug: Change the dirty state after deleting a workflow (#1992) --- packages/editor-ui/src/components/MainSidebar.vue | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/editor-ui/src/components/MainSidebar.vue b/packages/editor-ui/src/components/MainSidebar.vue index 9a615abccc..cadabe7884 100644 --- a/packages/editor-ui/src/components/MainSidebar.vue +++ b/packages/editor-ui/src/components/MainSidebar.vue @@ -395,6 +395,7 @@ export default mixins( this.$showError(error, 'Problem deleting the workflow', 'There was a problem deleting the workflow:'); return; } + this.$store.commit('setStateDirty', false); // Reset tab title since workflow is deleted. this.$titleReset(); this.$showMessage({ From ca1bbcea5d13b0dace28f9eb0c651b9966f39100 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Ovejero?= Date: Sat, 17 Jul 2021 11:43:45 +0200 Subject: [PATCH 02/15] :sparkles: Add Elasticsearch node (#1791) * :tada: Initial node scaffolding * :zap: Implement index operations * :zap: Implement document operations * :hammer: Clean up details * :hammer: Fix casing * :hammer: Fix indentation * :zap: Minor fixes * :pencil2: Update descriptions * :fire: Remove wrong placeholder * :zap: Refactor to implement specifyIndexBy * :shirt: Appease linter * Revert ":zap: Refactor to implement specifyIndexBy" This reverts commit 02ea0d30804b14f0b489678cd4e5deeb95848883. * :fire: Remove unused file * :zap: Return source always in document:get and getAll * :zap: Rename to options in document:getAll * :zap: Rename to options in document:get * :zap: Send content as JSON * :zap: Add simplify param to document:get * :zap: Rename docvalue fields * :zap: Make document ID optional in document:index * :zap: Implement sendInputData * :shirt: Fix lintings * Add define and automap to document:index * WIP on document:update * :hammer: Adjust document:update per feedback * :fire: Remove logging * :zap: Improve Elasticsearch node Co-authored-by: Jan Oberhauser --- .../ElasticsearchApi.credentials.ts | 35 + .../nodes/Elasticsearch/Elasticsearch.node.ts | 350 ++++++++ .../nodes/Elasticsearch/GenericFunctions.ts | 58 ++ .../descriptions/DocumentDescription.ts | 771 ++++++++++++++++++ .../descriptions/IndexDescription.ts | 322 ++++++++ .../nodes/Elasticsearch/descriptions/index.ts | 2 + .../descriptions/placeholders.ts | 43 + .../nodes/Elasticsearch/elasticsearch.svg | 14 + .../nodes-base/nodes/Elasticsearch/types.d.ts | 40 + packages/nodes-base/package.json | 2 + 10 files changed, 1637 insertions(+) create mode 100644 packages/nodes-base/credentials/ElasticsearchApi.credentials.ts create mode 100644 packages/nodes-base/nodes/Elasticsearch/Elasticsearch.node.ts create mode 100644 packages/nodes-base/nodes/Elasticsearch/GenericFunctions.ts create mode 100644 packages/nodes-base/nodes/Elasticsearch/descriptions/DocumentDescription.ts create mode 100644 packages/nodes-base/nodes/Elasticsearch/descriptions/IndexDescription.ts create mode 100644 packages/nodes-base/nodes/Elasticsearch/descriptions/index.ts create mode 100644 packages/nodes-base/nodes/Elasticsearch/descriptions/placeholders.ts create mode 100644 packages/nodes-base/nodes/Elasticsearch/elasticsearch.svg create mode 100644 packages/nodes-base/nodes/Elasticsearch/types.d.ts diff --git a/packages/nodes-base/credentials/ElasticsearchApi.credentials.ts b/packages/nodes-base/credentials/ElasticsearchApi.credentials.ts new file mode 100644 index 0000000000..0ebb10ab7e --- /dev/null +++ b/packages/nodes-base/credentials/ElasticsearchApi.credentials.ts @@ -0,0 +1,35 @@ +import { + ICredentialType, + NodePropertyTypes, +} from 'n8n-workflow'; + +export class ElasticsearchApi implements ICredentialType { + name = 'elasticsearchApi'; + displayName = 'Elasticsearch API'; + documentationUrl = 'elasticsearch'; + properties = [ + { + displayName: 'Username', + name: 'username', + type: 'string' as NodePropertyTypes, + default: '', + }, + { + displayName: 'Password', + name: 'password', + type: 'string' as NodePropertyTypes, + typeOptions: { + password: true, + }, + default: '', + }, + { + displayName: 'Base URL', + name: 'baseUrl', + type: 'string' as NodePropertyTypes, + default: '', + placeholder: 'https://abc.elastic-cloud.com:9243', + description: 'Referred to as \'endpoint\' in the Elasticsearch dashboard.', + }, + ]; +} diff --git a/packages/nodes-base/nodes/Elasticsearch/Elasticsearch.node.ts b/packages/nodes-base/nodes/Elasticsearch/Elasticsearch.node.ts new file mode 100644 index 0000000000..e28ff8cb0b --- /dev/null +++ b/packages/nodes-base/nodes/Elasticsearch/Elasticsearch.node.ts @@ -0,0 +1,350 @@ +import { + IExecuteFunctions, +} from 'n8n-core'; + +import { + IDataObject, + INodeExecutionData, + INodeType, + INodeTypeDescription, +} from 'n8n-workflow'; + +import { + elasticsearchApiRequest, +} from './GenericFunctions'; + +import { + documentFields, + documentOperations, + indexFields, + indexOperations, +} from './descriptions'; + +import { + DocumentGetAllOptions, + FieldsUiValues, +} from './types'; + +import { + omit, +} from 'lodash'; + +export class Elasticsearch implements INodeType { + description: INodeTypeDescription = { + displayName: 'Elasticsearch', + name: 'elasticsearch', + icon: 'file:elasticsearch.svg', + group: ['transform'], + version: 1, + subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}', + description: 'Consume the Elasticsearch API', + defaults: { + name: 'Elasticsearch', + color: '#f3d337', + }, + inputs: ['main'], + outputs: ['main'], + credentials: [ + { + name: 'elasticsearchApi', + required: true, + }, + ], + properties: [ + { + displayName: 'Resource', + name: 'resource', + type: 'options', + options: [ + { + name: 'Document', + value: 'document', + }, + { + name: 'Index', + value: 'index', + }, + ], + default: 'document', + description: 'Resource to consume', + }, + ...documentOperations, + ...documentFields, + ...indexOperations, + ...indexFields, + ], + }; + + async execute(this: IExecuteFunctions): Promise { + const items = this.getInputData(); + const returnData: IDataObject[] = []; + + const resource = this.getNodeParameter('resource', 0) as 'document' | 'index'; + const operation = this.getNodeParameter('operation', 0) as string; + + let responseData; + + for (let i = 0; i < items.length; i++) { + + if (resource === 'document') { + + // ********************************************************************** + // document + // ********************************************************************** + + // https://www.elastic.co/guide/en/elasticsearch/reference/current/docs.html + + if (operation === 'delete') { + + // ---------------------------------------- + // document: delete + // ---------------------------------------- + + // https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-delete.html + + const indexId = this.getNodeParameter('indexId', i); + const documentId = this.getNodeParameter('documentId', i); + + const endpoint = `/${indexId}/_doc/${documentId}`; + responseData = await elasticsearchApiRequest.call(this, 'DELETE', endpoint); + + } else if (operation === 'get') { + + // ---------------------------------------- + // document: get + // ---------------------------------------- + + // https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-get.html + + const indexId = this.getNodeParameter('indexId', i); + const documentId = this.getNodeParameter('documentId', i); + + const qs = {} as IDataObject; + const options = this.getNodeParameter('options', i) as IDataObject; + + if (Object.keys(options).length) { + Object.assign(qs, options); + qs._source = true; + } + + const endpoint = `/${indexId}/_doc/${documentId}`; + responseData = await elasticsearchApiRequest.call(this, 'GET', endpoint, {}, qs); + + const simple = this.getNodeParameter('simple', i) as IDataObject; + + if (simple) { + responseData = responseData._source; + } + + } else if (operation === 'getAll') { + + // ---------------------------------------- + // document: getAll + // ---------------------------------------- + + // https://www.elastic.co/guide/en/elasticsearch/reference/current/search-search.html + + const indexId = this.getNodeParameter('indexId', i); + + const body = {} as IDataObject; + const qs = {} as IDataObject; + const options = this.getNodeParameter('options', i) as DocumentGetAllOptions; + + if (Object.keys(options).length) { + const { query, ...rest } = options; + if (query) Object.assign(body, JSON.parse(query)); + Object.assign(qs, rest); + qs._source = true; + } + + const returnAll = this.getNodeParameter('returnAll', 0); + + if (!returnAll) { + qs.size = this.getNodeParameter('limit', 0); + } + + responseData = await elasticsearchApiRequest.call(this, 'GET', `/${indexId}/_search`, body, qs); + responseData = responseData.hits.hits; + + } else if (operation === 'create') { + + // ---------------------------------------- + // document: create + // ---------------------------------------- + + // https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-index_.html + + const body: IDataObject = {}; + + const dataToSend = this.getNodeParameter('dataToSend', 0) as 'defineBelow' | 'autoMapInputData'; + + if (dataToSend === 'defineBelow') { + + const fields = this.getNodeParameter('fieldsUi.fieldValues', i, []) as FieldsUiValues; + fields.forEach(({ fieldId, fieldValue }) => body[fieldId] = fieldValue); + + } else { + + const inputData = items[i].json; + const rawInputsToIgnore = this.getNodeParameter('inputsToIgnore', i) as string; + const inputsToIgnore = rawInputsToIgnore.split(',').map(c => c.trim()); + + for (const key of Object.keys(inputData)) { + if (inputsToIgnore.includes(key)) continue; + body[key] = inputData[key]; + } + + } + + const qs = {} as IDataObject; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + + if (Object.keys(additionalFields).length) { + Object.assign(qs, omit(additionalFields, ['documentId'])); + } + + const indexId = this.getNodeParameter('indexId', i); + const { documentId } = additionalFields; + + if (documentId) { + const endpoint = `/${indexId}/_doc/${documentId}`; + responseData = await elasticsearchApiRequest.call(this, 'PUT', endpoint, body); + } else { + const endpoint = `/${indexId}/_doc`; + responseData = await elasticsearchApiRequest.call(this, 'POST', endpoint, body); + } + + } else if (operation === 'update') { + + // ---------------------------------------- + // document: update + // ---------------------------------------- + + // https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-update.html + + const body = { doc: {} } as { doc: { [key: string]: string } }; + + const dataToSend = this.getNodeParameter('dataToSend', 0) as 'defineBelow' | 'autoMapInputData'; + + if (dataToSend === 'defineBelow') { + + const fields = this.getNodeParameter('fieldsUi.fieldValues', i, []) as FieldsUiValues; + fields.forEach(({ fieldId, fieldValue }) => body.doc[fieldId] = fieldValue); + + } else { + + const inputData = items[i].json; + const rawInputsToIgnore = this.getNodeParameter('inputsToIgnore', i) as string; + const inputsToIgnore = rawInputsToIgnore.split(',').map(c => c.trim()); + + for (const key of Object.keys(inputData)) { + if (inputsToIgnore.includes(key)) continue; + body.doc[key] = inputData[key] as string; + } + + } + + const indexId = this.getNodeParameter('indexId', i); + const documentId = this.getNodeParameter('documentId', i); + + const endpoint = `/${indexId}/_update/${documentId}`; + responseData = await elasticsearchApiRequest.call(this, 'POST', endpoint, body); + + } + + } else if (resource === 'index') { + + // ********************************************************************** + // index + // ********************************************************************** + + // https://www.elastic.co/guide/en/elasticsearch/reference/current/indices.html + + if (operation === 'create') { + + // ---------------------------------------- + // index: create + // ---------------------------------------- + + // https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-create-index.html + + const indexId = this.getNodeParameter('indexId', i); + + const body = {} as IDataObject; + const qs = {} as IDataObject; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + + if (Object.keys(additionalFields).length) { + const { aliases, mappings, settings, ...rest } = additionalFields; + Object.assign(body, aliases, mappings, settings); + Object.assign(qs, rest); + } + + responseData = await elasticsearchApiRequest.call(this, 'PUT', `/${indexId}`); + responseData = { id: indexId, ...responseData }; + delete responseData.index; + + } else if (operation === 'delete') { + + // ---------------------------------------- + // index: delete + // ---------------------------------------- + + // https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-delete-index.html + + const indexId = this.getNodeParameter('indexId', i); + + responseData = await elasticsearchApiRequest.call(this, 'DELETE', `/${indexId}`); + responseData = { success: true }; + + } else if (operation === 'get') { + + // ---------------------------------------- + // index: get + // ---------------------------------------- + + // https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-get-index.html + + const indexId = this.getNodeParameter('indexId', i) as string; + + const qs = {} as IDataObject; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + + if (Object.keys(additionalFields).length) { + Object.assign(qs, additionalFields); + } + + responseData = await elasticsearchApiRequest.call(this, 'GET', `/${indexId}`, {}, qs); + responseData = { id: indexId, ...responseData[indexId] }; + + } else if (operation === 'getAll') { + + // ---------------------------------------- + // index: getAll + // ---------------------------------------- + + // https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-aliases.html + + responseData = await elasticsearchApiRequest.call(this, 'GET', '/_aliases'); + responseData = Object.keys(responseData).map(i => ({ indexId: i })); + + const returnAll = this.getNodeParameter('returnAll', i); + + if (!returnAll) { + const limit = this.getNodeParameter('limit', i) as number; + responseData = responseData.slice(0, limit); + } + + } + + } + + Array.isArray(responseData) + ? returnData.push(...responseData) + : returnData.push(responseData); + + } + + return [this.helpers.returnJsonArray(returnData)]; + } +} diff --git a/packages/nodes-base/nodes/Elasticsearch/GenericFunctions.ts b/packages/nodes-base/nodes/Elasticsearch/GenericFunctions.ts new file mode 100644 index 0000000000..9fc7a9844b --- /dev/null +++ b/packages/nodes-base/nodes/Elasticsearch/GenericFunctions.ts @@ -0,0 +1,58 @@ +import { + OptionsWithUri, +} from 'request'; + +import { + IExecuteFunctions, +} from 'n8n-core'; + +import { + IDataObject, + NodeApiError, +} from 'n8n-workflow'; + +import { + ElasticsearchApiCredentials, +} from './types'; + +export async function elasticsearchApiRequest( + this: IExecuteFunctions, + method: 'GET' | 'PUT' | 'POST' | 'DELETE', + endpoint: string, + body: IDataObject = {}, + qs: IDataObject = {}, +) { + const { + username, + password, + baseUrl, + } = this.getCredentials('elasticsearchApi') as ElasticsearchApiCredentials; + + const token = Buffer.from(`${username}:${password}`).toString('base64'); + + const options: OptionsWithUri = { + headers: { + Authorization: `Basic ${token}`, + 'Content-Type': 'application/json', + }, + method, + body, + qs, + uri: `${baseUrl}${endpoint}`, + json: true, + }; + + if (!Object.keys(body).length) { + delete options.body; + } + + if (!Object.keys(qs).length) { + delete options.qs; + } + + try { + return await this.helpers.request(options); + } catch (error) { + throw new NodeApiError(this.getNode(), error); + } +} diff --git a/packages/nodes-base/nodes/Elasticsearch/descriptions/DocumentDescription.ts b/packages/nodes-base/nodes/Elasticsearch/descriptions/DocumentDescription.ts new file mode 100644 index 0000000000..dca8122caa --- /dev/null +++ b/packages/nodes-base/nodes/Elasticsearch/descriptions/DocumentDescription.ts @@ -0,0 +1,771 @@ +import { + INodeProperties, +} from 'n8n-workflow'; + +import * as placeholders from './placeholders'; + +export const documentOperations = [ + { + displayName: 'Operation', + name: 'operation', + type: 'options', + displayOptions: { + show: { + resource: [ + 'document', + ], + }, + }, + options: [ + { + name: 'Create', + value: 'create', + description: 'Create a document', + }, + { + name: 'Delete', + value: 'delete', + description: 'Delete a document', + }, + { + name: 'Get', + value: 'get', + description: 'Get a document', + }, + { + name: 'Get All', + value: 'getAll', + description: 'Get all documents', + }, + { + name: 'Update', + value: 'update', + description: 'Update a document', + }, + ], + default: 'get', + description: 'Operation to perform', + }, +] as INodeProperties[]; + +export const documentFields = [ + // ---------------------------------------- + // document: delete + // ---------------------------------------- + { + displayName: 'Index ID', + name: 'indexId', + description: 'ID of the index containing the document to delete', + type: 'string', + required: true, + default: '', + displayOptions: { + show: { + resource: [ + 'document', + ], + operation: [ + 'delete', + ], + }, + }, + }, + { + displayName: 'Document ID', + name: 'documentId', + description: 'ID of the document to delete', + type: 'string', + required: true, + default: '', + displayOptions: { + show: { + resource: [ + 'document', + ], + operation: [ + 'delete', + ], + }, + }, + }, + + // ---------------------------------------- + // document: get + // ---------------------------------------- + { + displayName: 'Index ID', + name: 'indexId', + description: 'ID of the index containing the document to retrieve', + type: 'string', + required: true, + default: '', + displayOptions: { + show: { + resource: [ + 'document', + ], + operation: [ + 'get', + ], + }, + }, + }, + { + displayName: 'Document ID', + name: 'documentId', + description: 'ID of the document to retrieve', + type: 'string', + required: true, + default: '', + displayOptions: { + show: { + resource: [ + 'document', + ], + operation: [ + 'get', + ], + }, + }, + }, + { + displayName: 'Simple', + name: 'simple', + type: 'boolean', + default: true, + description: 'Whether to return a simplified version of the response instead of the raw data', + displayOptions: { + show: { + resource: [ + 'document', + ], + operation: [ + 'get', + ], + }, + }, + }, + { + displayName: 'Options', + name: 'options', + type: 'collection', + placeholder: 'Add Option', + default: {}, + displayOptions: { + show: { + resource: [ + 'document', + ], + operation: [ + 'get', + ], + }, + }, + options: [ + { + displayName: 'Source Excludes', + name: '_source_excludes', + description: 'Comma-separated list of source fields to exclude from the response', + type: 'string', + default: '', + }, + { + displayName: 'Source Includes', + name: '_source_includes', + description: 'Comma-separated list of source fields to include in the response', + type: 'string', + default: '', + }, + { + displayName: 'Stored Fields', + name: 'stored_fields', + description: 'If true, retrieve the document fields stored in the index rather than the document _source. Defaults to false', + type: 'boolean', + default: false, + }, + ], + }, + + // ---------------------------------------- + // document: getAll + // ---------------------------------------- + { + displayName: 'Index ID', + name: 'indexId', + description: 'ID of the index containing the documents to retrieve', + type: 'string', + required: true, + default: '', + displayOptions: { + show: { + resource: [ + 'document', + ], + operation: [ + 'getAll', + ], + }, + }, + }, + { + displayName: 'Return All', + name: 'returnAll', + type: 'boolean', + default: false, + description: 'Whether to return all results or only up to a given limit', + displayOptions: { + show: { + resource: [ + 'document', + ], + operation: [ + 'getAll', + ], + }, + }, + }, + { + displayName: 'Limit', + name: 'limit', + type: 'number', + default: 50, + description: 'How many results to return', + typeOptions: { + minValue: 1, + }, + displayOptions: { + show: { + resource: [ + 'document', + ], + operation: [ + 'getAll', + ], + returnAll: [ + false, + ], + }, + }, + }, + { + displayName: 'Options', + name: 'options', + type: 'collection', + placeholder: 'Add Option', + default: {}, + displayOptions: { + show: { + resource: [ + 'document', + ], + operation: [ + 'getAll', + ], + }, + }, + options: [ + { + displayName: 'Allow No Indices', + name: 'allow_no_indices', + description: 'If false, return an error if any of the following targets only missing/closed indices: wildcard expression, index alias, or _all value. Defaults to true', + type: 'boolean', + default: true, + }, + { + displayName: 'Allow Partial Search Results', + name: 'allow_partial_search_results', + description: 'If true, return partial results if there are shard request timeouts or shard failures.
If false, returns an error with no partial results. Defaults to true', + type: 'boolean', + default: true, + }, + { + displayName: 'Batched Reduce Size', + name: 'batched_reduce_size', + description: 'Number of shard results that should be reduced at once on the coordinating node. Defaults to 512', + type: 'number', + typeOptions: { + minValue: 2, + }, + default: 512, + }, + { + displayName: 'CCS Minimize Roundtrips', + name: 'ccs_minimize_roundtrips', + description: 'If true, network round-trips between the coordinating node and the remote clusters are minimized when executing cross-cluster search (CCS) requests. Defaults to true', + type: 'boolean', + default: true, + }, + { + displayName: 'Doc Value Fields', + name: 'docvalue_fields', + description: 'Comma-separated list of fields to return as the docvalue representation of a field for each hit', + type: 'string', + default: '', + }, + { + displayName: 'Expand Wildcards', + name: 'expand_wildcards', + description: 'Type of index that wildcard expressions can match. Defaults to open', + type: 'options', + options: [ + { + name: 'All', + value: 'all', + }, + { + name: 'Closed', + value: 'closed', + }, + { + name: 'Hidden', + value: 'hidden', + }, + { + name: 'None', + value: 'none', + }, + { + name: 'Open', + value: 'open', + }, + ], + default: 'open', + }, + { + displayName: 'Explain', + name: 'explain', + description: 'If true, return detailed information about score computation as part of a hit. Defaults to false', + type: 'boolean', + default: false, + }, + { + displayName: 'Ignore Throttled', + name: 'ignore_throttled', + description: 'If true, concrete, expanded or aliased indices are ignored when frozen. Defaults to true', + type: 'boolean', + default: true, + }, + { + displayName: 'Ignore Unavailable', + name: 'ignore_unavailable', + description: 'If true, missing or closed indices are not included in the response. Defaults to false', + type: 'boolean', + default: false, + }, + { + displayName: 'Max Concurrent Shard Requests', + name: 'max_concurrent_shard_requests', + description: 'Define the number of shard requests per node this search executes concurrently. Defaults to 5', + type: 'number', + default: 5, + }, + { + displayName: 'Pre-Filter Shard Size', + name: 'pre_filter_shard_size', + description: 'Define a threshold that enforces a pre-filter roundtrip to prefilter search shards based on query rewriting.
Only used if the number of shards the search request expands to exceeds the threshold', + type: 'number', + typeOptions: { + minValue: 1, + }, + default: 1, + }, + { + displayName: 'Query', + name: 'query', + description: 'Query in the Elasticsearch Query DSL', + type: 'json', + typeOptions: { + alwaysOpenEditWindow: true, + }, + default: '', + placeholder: placeholders.query, + }, + { + displayName: 'Request Cache', + name: 'request_cache', + description: 'If true, the caching of search results is enabled for requests where size is 0. See Elasticsearch shard request cache settings', + type: 'boolean', + default: false, + }, + { + displayName: 'Routing', + name: 'routing', + description: 'Target this primary shard', + type: 'string', + default: '', + }, + { + displayName: 'Search Type', + name: 'search_type', + description: 'How distributed term frequencies are calculated for relevance scoring. Defaults to Query then Fetch', + type: 'options', + options: [ + { + name: 'DFS Query Then Fetch', + value: 'dfs_query_then_fetch', + }, + { + name: 'Query Then Fetch', + value: 'query_then_fetch', + }, + ], + default: 'query_then_fetch', + }, + { + displayName: 'Sequence Number and Primary Term', + name: 'seq_no_primary_term', + description: 'If true, return the sequence number and primary term of the last modification of each hit. See Optimistic concurrency control', + type: 'boolean', + default: false, + }, + { + displayName: 'Sort', + name: 'sort', + description: 'Comma-separated list of field:direction pairs', + type: 'string', + default: '', + }, + { + displayName: 'Stats', + name: 'stats', + description: 'Tag of the request for logging and statistical purposes', + type: 'string', + default: '', + }, + { + displayName: 'Stored Fields', + name: 'stored_fields', + description: 'If true, retrieve the document fields stored in the index rather than the document _source. Defaults to false', + type: 'boolean', + default: false, + }, + { + displayName: 'Terminate After', + name: 'terminate_after', + description: 'Max number of documents to collect for each shard', + type: 'number', + default: 0, + }, + { + displayName: 'Timeout', + name: 'timeout', + description: 'Period to wait for active shards. Defaults to 1m (one minute). See the Elasticsearch time units reference', + type: 'string', + default: '1m', + }, + { + displayName: 'Track Scores', + name: 'track_scores', + description: 'If true, calculate and return document scores, even if the scores are not used for sorting. Defaults to false', + type: 'boolean', + default: false, + }, + { + displayName: 'Track Total Hits', + name: 'track_total_hits', + description: 'Number of hits matching the query to count accurately. Defaults to 10000', + type: 'number', + default: 10000, + }, + { + displayName: 'Version', + name: 'version', + description: 'If true, return document version as part of a hit. Defaults to false', + type: 'boolean', + default: false, + }, + ], + }, + + // ---------------------------------------- + // document: create + // ---------------------------------------- + { + displayName: 'Index ID', + name: 'indexId', + description: 'ID of the index to add the document to', + type: 'string', + required: true, + default: '', + displayOptions: { + show: { + resource: [ + 'document', + ], + operation: [ + 'create', + ], + }, + }, + }, + { + displayName: 'Data to Send', + name: 'dataToSend', + type: 'options', + options: [ + { + name: 'Define Below for Each Column', + value: 'defineBelow', + description: 'Set the value for each destination column', + }, + { + name: 'Auto-map Input Data to Columns', + value: 'autoMapInputData', + description: 'Use when node input properties match destination column names', + }, + ], + displayOptions: { + show: { + resource: [ + 'document', + ], + operation: [ + 'create', + ], + }, + }, + default: 'defineBelow', + description: 'Whether to insert the input data this node receives in the new row', + }, + { + displayName: 'Inputs to Ignore', + name: 'inputsToIgnore', + type: 'string', + displayOptions: { + show: { + resource: [ + 'document', + ], + operation: [ + 'create', + ], + dataToSend: [ + 'autoMapInputData', + ], + }, + }, + default: '', + required: false, + description: 'List of input properties to avoid sending, separated by commas. Leave empty to send all properties', + placeholder: 'Enter properties...', + }, + { + displayName: 'Fields to Send', + name: 'fieldsUi', + placeholder: 'Add Field', + type: 'fixedCollection', + typeOptions: { + multipleValueButtonText: 'Add Field to Send', + multipleValues: true, + }, + displayOptions: { + show: { + resource: [ + 'document', + ], + operation: [ + 'create', + ], + dataToSend: [ + 'defineBelow', + ], + }, + }, + default: {}, + options: [ + { + displayName: 'Field', + name: 'fieldValues', + values: [ + { + displayName: 'Field Name', + name: 'fieldId', + type: 'string', + default: '', + }, + { + displayName: 'Field Value', + name: 'fieldValue', + type: 'string', + default: '', + }, + ], + }, + ], + }, + { + displayName: 'Additional Fields', + name: 'additionalFields', + type: 'collection', + placeholder: 'Add Field', + default: {}, + displayOptions: { + show: { + resource: [ + 'document', + ], + operation: [ + 'create', + ], + }, + }, + options: [ + { + displayName: 'Document ID', + name: 'documentId', + description: 'ID of the document to create and add to the index', + type: 'string', + default: '', + }, + { + displayName: 'Routing', + name: 'routing', + description: 'Target this primary shard', + type: 'string', + default: '', + }, + { + displayName: 'Timeout', + name: 'timeout', + description: 'Period to wait for active shards. Defaults to 1m (one minute). See the Elasticsearch time units reference', + type: 'string', + default: '1m', + }, + ], + }, + + // ---------------------------------------- + // document: update + // ---------------------------------------- + { + displayName: 'Index ID', + name: 'indexId', + description: 'ID of the document to update', + type: 'string', + required: true, + default: '', + displayOptions: { + show: { + resource: [ + 'document', + ], + operation: [ + 'update', + ], + }, + }, + }, + { + displayName: 'Document ID', + name: 'documentId', + description: 'ID of the document to update', + type: 'string', + required: true, + default: '', + displayOptions: { + show: { + resource: [ + 'document', + ], + operation: [ + 'update', + ], + }, + }, + }, + { + displayName: 'Data to Send', + name: 'dataToSend', + type: 'options', + options: [ + { + name: 'Define Below for Each Column', + value: 'defineBelow', + description: 'Set the value for each destination column', + }, + { + name: 'Auto-map Input Data to Columns', + value: 'autoMapInputData', + description: 'Use when node input properties match destination column names', + }, + ], + displayOptions: { + show: { + resource: [ + 'document', + ], + operation: [ + 'update', + ], + }, + }, + default: 'defineBelow', + description: 'Whether to insert the input data this node receives in the new row', + }, + { + displayName: 'Inputs to Ignore', + name: 'inputsToIgnore', + type: 'string', + displayOptions: { + show: { + resource: [ + 'document', + ], + operation: [ + 'update', + ], + dataToSend: [ + 'autoMapInputData', + ], + }, + }, + default: '', + required: false, + description: 'List of input properties to avoid sending, separated by commas. Leave empty to send all properties', + placeholder: 'Enter properties...', + }, + { + displayName: 'Fields to Send', + name: 'fieldsUi', + placeholder: 'Add Field', + type: 'fixedCollection', + typeOptions: { + multipleValueButtonText: 'Add Field to Send', + multipleValues: true, + }, + displayOptions: { + show: { + resource: [ + 'document', + ], + operation: [ + 'update', + ], + dataToSend: [ + 'defineBelow', + ], + }, + }, + default: {}, + options: [ + { + displayName: 'Field', + name: 'fieldValues', + values: [ + { + displayName: 'Field Name', + name: 'fieldId', + type: 'string', + default: '', + }, + { + displayName: 'Field Value', + name: 'fieldValue', + type: 'string', + default: '', + }, + ], + }, + ], + }, +] as INodeProperties[]; diff --git a/packages/nodes-base/nodes/Elasticsearch/descriptions/IndexDescription.ts b/packages/nodes-base/nodes/Elasticsearch/descriptions/IndexDescription.ts new file mode 100644 index 0000000000..504b0967c1 --- /dev/null +++ b/packages/nodes-base/nodes/Elasticsearch/descriptions/IndexDescription.ts @@ -0,0 +1,322 @@ +import { + INodeProperties, +} from 'n8n-workflow'; + +import * as placeholders from './placeholders'; + +export const indexOperations = [ + { + displayName: 'Operation', + name: 'operation', + type: 'options', + displayOptions: { + show: { + resource: [ + 'index', + ], + }, + }, + options: [ + { + name: 'Create', + value: 'create', + }, + { + name: 'Delete', + value: 'delete', + }, + { + name: 'Get', + value: 'get', + }, + { + name: 'Get All', + value: 'getAll', + }, + ], + default: 'create', + description: 'Operation to perform', + }, +] as INodeProperties[]; + +export const indexFields = [ + // ---------------------------------------- + // index: create + // ---------------------------------------- + { + displayName: 'Index ID', + name: 'indexId', + description: 'ID of the index to create', + type: 'string', + required: true, + default: '', + displayOptions: { + show: { + resource: [ + 'index', + ], + operation: [ + 'create', + ], + }, + }, + }, + { + displayName: 'Additional Fields', + name: 'additionalFields', + type: 'collection', + placeholder: 'Add Field', + default: {}, + displayOptions: { + show: { + resource: [ + 'index', + ], + operation: [ + 'create', + ], + }, + }, + options: [ + { + displayName: 'Aliases', + name: 'aliases', + description: 'Index aliases which include the index, as an alias object', + type: 'json', + typeOptions: { + alwaysOpenEditWindow: true, + }, + default: '', + placeholder: placeholders.aliases, + }, + { + displayName: 'Include Type Name', + name: 'include_type_name', + description: 'If true, a mapping type is expected in the body of mappings. Defaults to false', + type: 'boolean', + default: false, + }, + { + displayName: 'Mappings', + name: 'mappings', + description: 'Mapping for fields in the index, as mapping object', + type: 'json', + typeOptions: { + alwaysOpenEditWindow: true, + }, + default: '', + placeholder: placeholders.mappings, + }, + { + displayName: 'Master Timeout', + name: 'master_timeout', + description: 'Period to wait for a connection to the master node. If no response is received before the timeout expires,
the request fails and returns an error. Defaults to 1m. See the Elasticsearch time units reference', + type: 'string', + default: '1m', + }, + { + displayName: 'Settings', + name: 'settings', + description: 'Configuration options for the index, as an index settings object', + type: 'json', + typeOptions: { + alwaysOpenEditWindow: true, + }, + default: '', + placeholder: placeholders.indexSettings, + }, + { + displayName: 'Timeout', + name: 'timeout', + description: 'Period to wait for a response. If no response is received before the timeout expires, the request
fails and returns an error. Defaults to 30s. See the Elasticsearch time units reference', + type: 'string', + default: '30s', + }, + { + displayName: 'Wait for Active Shards', + name: 'wait_for_active_shards', + description: 'The number of shard copies that must be active before proceeding with the operation. Set to all
or any positive integer up to the total number of shards in the index. Default: 1, the primary shard', + type: 'string', + default: '1', + }, + ], + }, + + // ---------------------------------------- + // index: delete + // ---------------------------------------- + { + displayName: 'Index ID', + name: 'indexId', + description: 'ID of the index to delete', + type: 'string', + required: true, + default: '', + displayOptions: { + show: { + resource: [ + 'index', + ], + operation: [ + 'delete', + ], + }, + }, + }, + + // ---------------------------------------- + // index: get + // ---------------------------------------- + { + displayName: 'Index ID', + name: 'indexId', + description: 'ID of the index to retrieve', + type: 'string', + required: true, + default: '', + displayOptions: { + show: { + resource: [ + 'index', + ], + operation: [ + 'get', + ], + }, + }, + }, + { + displayName: 'Additional Fields', + name: 'additionalFields', + type: 'collection', + placeholder: 'Add Field', + default: {}, + displayOptions: { + show: { + resource: [ + 'index', + ], + operation: [ + 'get', + ], + }, + }, + options: [ + { + displayName: 'Allow No Indices', + name: 'allow_no_indices', + description: 'If false, return an error if any of the following targets only missing/closed indices: wildcard expression, index alias, or _all value. Defaults to true', + type: 'boolean', + default: true, + }, + { + displayName: 'Expand Wildcards', + name: 'expand_wildcards', + description: 'Type of index that wildcard expressions can match. Defaults to open', + type: 'options', + options: [ + { + name: 'All', + value: 'all', + }, + { + name: 'Closed', + value: 'closed', + }, + { + name: 'Hidden', + value: 'hidden', + }, + { + name: 'None', + value: 'none', + }, + { + name: 'Open', + value: 'open', + }, + ], + default: 'all', + }, + { + displayName: 'Flat Settings', + name: 'flat_settings', + description: 'If true, return settings in flat format. Defaults to false', + type: 'boolean', + default: false, + }, + { + displayName: 'Ignore Unavailable', + name: 'ignore_unavailable', + description: 'If false, requests that target a missing index return an error. Defaults to false', + type: 'boolean', + default: false, + }, + { + displayName: 'Include Defaults', + name: 'include_defaults', + description: 'If true, return all default settings in the response. Defaults to false', + type: 'boolean', + default: false, + }, + { + displayName: 'Local', + name: 'local', + description: 'If true, retrieve information from the local node only. Defaults to false', + type: 'boolean', + default: false, + }, + { + displayName: 'Master Timeout', + name: 'master_timeout', + description: 'Period to wait for a connection to the master node. If no response is received before the timeout expires,
the request fails and returns an error. Defaults to 1m. See the Elasticsearch time units reference', + type: 'string', + default: '1m', + }, + ], + }, + + // ---------------------------------------- + // index: getAll + // ---------------------------------------- + { + displayName: 'Return All', + name: 'returnAll', + type: 'boolean', + default: false, + description: 'Whether to return all results or only up to a given limit', + displayOptions: { + show: { + resource: [ + 'index', + ], + operation: [ + 'getAll', + ], + }, + }, + }, + { + displayName: 'Limit', + name: 'limit', + type: 'number', + default: 50, + description: 'How many results to return', + typeOptions: { + minValue: 1, + }, + displayOptions: { + show: { + resource: [ + 'index', + ], + operation: [ + 'getAll', + ], + returnAll: [ + false, + ], + }, + }, + }, +] as INodeProperties[]; diff --git a/packages/nodes-base/nodes/Elasticsearch/descriptions/index.ts b/packages/nodes-base/nodes/Elasticsearch/descriptions/index.ts new file mode 100644 index 0000000000..f20c261442 --- /dev/null +++ b/packages/nodes-base/nodes/Elasticsearch/descriptions/index.ts @@ -0,0 +1,2 @@ +export * from './DocumentDescription'; +export * from './IndexDescription'; diff --git a/packages/nodes-base/nodes/Elasticsearch/descriptions/placeholders.ts b/packages/nodes-base/nodes/Elasticsearch/descriptions/placeholders.ts new file mode 100644 index 0000000000..bda913525a --- /dev/null +++ b/packages/nodes-base/nodes/Elasticsearch/descriptions/placeholders.ts @@ -0,0 +1,43 @@ +export const indexSettings = `{ + "settings": { + "index": { + "number_of_shards": 3, + "number_of_replicas": 2 + } + } +}`; + +export const mappings = `{ + "mappings": { + "properties": { + "field1": { "type": "text" } + } + } +}`; + +export const aliases = `{ + "aliases": { + "alias_1": {}, + "alias_2": { + "filter": { + "term": { "user.id": "kimchy" } + }, + "routing": "shard-1" + } + } +}`; + +export const query = `{ + "query": { + "term": { + "user.id": "john" + } + } +}`; + +export const document = `{ + "timestamp": "2099-05-06T16:21:15.000Z", + "event": { + "original": "192.0.2.42 - - [06/May/2099:16:21:15 +0000] \"GET /images/bg.jpg HTTP/1.0\" 200 24736" + } +}`; diff --git a/packages/nodes-base/nodes/Elasticsearch/elasticsearch.svg b/packages/nodes-base/nodes/Elasticsearch/elasticsearch.svg new file mode 100644 index 0000000000..7e2fad792c --- /dev/null +++ b/packages/nodes-base/nodes/Elasticsearch/elasticsearch.svg @@ -0,0 +1,14 @@ + + + + elastic-search-logo-color-64px + Created with Sketch. + + + + + + + + + diff --git a/packages/nodes-base/nodes/Elasticsearch/types.d.ts b/packages/nodes-base/nodes/Elasticsearch/types.d.ts new file mode 100644 index 0000000000..105766301e --- /dev/null +++ b/packages/nodes-base/nodes/Elasticsearch/types.d.ts @@ -0,0 +1,40 @@ +export type ElasticsearchApiCredentials = { + username: string; + password: string; + baseUrl: string; +}; + +export type DocumentGetAllOptions = Partial<{ + allow_no_indices: boolean; + allow_partial_search_results: boolean; + batched_reduce_size: number; + ccs_minimize_roundtrips: boolean; + docvalue_fields: string; + expand_wildcards: 'All' | 'Closed' | 'Hidden' | 'None' | 'Open'; + explain: boolean; + ignore_throttled: boolean; + ignore_unavailable: boolean; + max_concurrent_shard_requests: number; + pre_filter_shard_size: number; + query: string; + request_cache: boolean; + routing: string; + search_type: 'query_then_fetch' | 'dfs_query_then_fetch'; + seq_no_primary_term: boolean; + sort: string; + _source: boolean; + _source_excludes: string; + _source_includes: string; + stats: string; + stored_fields: boolean; + terminate_after: boolean; + timeout: number; + track_scores: boolean; + track_total_hits: string; + version: boolean; +}>; + +export type FieldsUiValues = Array<{ + fieldId: string; + fieldValue: string; +}>; diff --git a/packages/nodes-base/package.json b/packages/nodes-base/package.json index 7bbd5fc8f0..f4aacdc008 100644 --- a/packages/nodes-base/package.json +++ b/packages/nodes-base/package.json @@ -76,6 +76,7 @@ "dist/credentials/DropboxApi.credentials.js", "dist/credentials/DropboxOAuth2Api.credentials.js", "dist/credentials/EgoiApi.credentials.js", + "dist/credentials/ElasticsearchApi.credentials.js", "dist/credentials/EmeliaApi.credentials.js", "dist/credentials/ERPNextApi.credentials.js", "dist/credentials/EventbriteApi.credentials.js", @@ -355,6 +356,7 @@ "dist/nodes/Dropbox/Dropbox.node.js", "dist/nodes/EditImage.node.js", "dist/nodes/Egoi/Egoi.node.js", + "dist/nodes/Elasticsearch/Elasticsearch.node.js", "dist/nodes/EmailReadImap.node.js", "dist/nodes/EmailSend.node.js", "dist/nodes/Emelia/Emelia.node.js", From 9118e090e73290f78512c179ccd7609aa23ebfd9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Ovejero?= Date: Sat, 17 Jul 2021 14:14:12 +0200 Subject: [PATCH 03/15] :sparkles: Add AWS DynamoDB node (#1602) * dynamodb: request item * dynamodb: query database * dynamodb: scans table * dynamodb: typehints in decodeItem * dynamodb: recursively decodes map and lists * dynamodb: cleanup interface, using additional-fields collection * dynamodb: using fixedCollection for ExpressionAttributeValues * dynamodb: converts spaces to tabs * dynamodb: scans with FilterExpression * dynamodb: fixes tslint * :zap: Refactor node * :hammer: Refactor into separate dir * :zap: Add table name loader * :pencil2: Update operation descriptions * :zap: Add partition key name param to delete * :zap: Add params to get operation * :hammer: Refactor get operation per feedback * :zap: Refactor for consistency * :zap: Add createUpdate operation * aja * asasa * aja * aja * aja * :zap: Improvements * :zap: Lint node * :zap: Lint description * :fire: Remove unused option * :zap: Apply David's feedback * :pencil2: Add descriptions for specific attributes * :hammer: Rename return values * Implement define and automap * :zap: Minior changes Co-authored-by: Michael Hirschler Co-authored-by: ricardo Co-authored-by: Jan Oberhauser --- .../nodes/Aws/DynamoDB/AwsDynamoDB.node.ts | 374 +++++++ .../nodes/Aws/DynamoDB/GenericFunctions.ts | 108 ++ .../nodes/Aws/DynamoDB/ItemDescription.ts | 920 ++++++++++++++++++ .../nodes/Aws/DynamoDB/dynamodb.svg | 13 + .../nodes-base/nodes/Aws/DynamoDB/types.d.ts | 79 ++ .../nodes-base/nodes/Aws/DynamoDB/utils.ts | 134 +++ packages/nodes-base/package.json | 1 + 7 files changed, 1629 insertions(+) create mode 100644 packages/nodes-base/nodes/Aws/DynamoDB/AwsDynamoDB.node.ts create mode 100644 packages/nodes-base/nodes/Aws/DynamoDB/GenericFunctions.ts create mode 100644 packages/nodes-base/nodes/Aws/DynamoDB/ItemDescription.ts create mode 100644 packages/nodes-base/nodes/Aws/DynamoDB/dynamodb.svg create mode 100644 packages/nodes-base/nodes/Aws/DynamoDB/types.d.ts create mode 100644 packages/nodes-base/nodes/Aws/DynamoDB/utils.ts diff --git a/packages/nodes-base/nodes/Aws/DynamoDB/AwsDynamoDB.node.ts b/packages/nodes-base/nodes/Aws/DynamoDB/AwsDynamoDB.node.ts new file mode 100644 index 0000000000..39d170ad4c --- /dev/null +++ b/packages/nodes-base/nodes/Aws/DynamoDB/AwsDynamoDB.node.ts @@ -0,0 +1,374 @@ +import { + IExecuteFunctions, +} from 'n8n-core'; + +import { + IDataObject, + ILoadOptionsFunctions, + INodeExecutionData, + INodeType, + INodeTypeDescription, + NodeParameterValue, +} from 'n8n-workflow'; + +import { + awsApiRequest, + awsApiRequestAllItems, +} from './GenericFunctions'; + +import { + itemFields, + itemOperations, +} from './ItemDescription'; + +import { + FieldsUiValues, + IAttributeNameUi, + IAttributeValueUi, + IRequestBody, + PutItemUi, +} from './types'; + +import { + adjustExpressionAttributeName, + adjustExpressionAttributeValues, + adjustPutItem, + decodeItem, + simplify, +} from './utils'; + +export class AwsDynamoDB implements INodeType { + description: INodeTypeDescription = { + displayName: 'AWS DynamoDB', + name: 'awsDynamoDb', + icon: 'file:dynamodb.svg', + group: ['transform'], + version: 1, + subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}', + description: 'Consume the AWS DynamoDB API', + defaults: { + name: 'AWS DynamoDB', + color: '#2273b9', + }, + inputs: ['main'], + outputs: ['main'], + credentials: [ + { + name: 'aws', + required: true, + }, + ], + properties: [ + { + displayName: 'Resource', + name: 'resource', + type: 'options', + options: [ + { + name: 'Item', + value: 'item', + }, + ], + default: 'item', + }, + ...itemOperations, + ...itemFields, + ], + }; + + methods = { + loadOptions: { + async getTables(this: ILoadOptionsFunctions) { + const headers = { + 'Content-Type': 'application/x-amz-json-1.0', + 'X-Amz-Target': 'DynamoDB_20120810.ListTables', + }; + + const responseData = await awsApiRequest.call(this, 'dynamodb', 'POST', '/', {}, headers); + + return responseData.TableNames.map((table: string) => ({ name: table, value: table })); + }, + }, + }; + + async execute(this: IExecuteFunctions): Promise { + const items = this.getInputData(); + + const resource = this.getNodeParameter('resource', 0); + const operation = this.getNodeParameter('operation', 0); + + let responseData; + const returnData: IDataObject[] = []; + + for (let i = 0; i < items.length; i++) { + + try { + + if (resource === 'item') { + + if (operation === 'upsert') { + + // ---------------------------------- + // upsert + // ---------------------------------- + + // https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_PutItem.html + + const eavUi = this.getNodeParameter('additionalFields.eavUi.eavValues', i, []) as IAttributeValueUi[]; + const conditionExpession = this.getNodeParameter('conditionExpression', i, '') as string; + const eanUi = this.getNodeParameter('additionalFields.eanUi.eanValues', i, []) as IAttributeNameUi[]; + + const body: IRequestBody = { + TableName: this.getNodeParameter('tableName', i) as string, + }; + + const expressionAttributeValues = adjustExpressionAttributeValues(eavUi); + + if (Object.keys(expressionAttributeValues).length) { + body.ExpressionAttributeValues = expressionAttributeValues; + } + + const expressionAttributeName = adjustExpressionAttributeName(eanUi); + + if (Object.keys(expressionAttributeName).length) { + body.expressionAttributeNames = expressionAttributeName; + } + + if (conditionExpession) { + body.ConditionExpression = conditionExpession; + } + + const dataToSend = this.getNodeParameter('dataToSend', 0) as 'defineBelow' | 'autoMapInputData'; + const item: { [key: string]: string } = {}; + + if (dataToSend === 'autoMapInputData') { + + const incomingKeys = Object.keys(items[i].json); + const rawInputsToIgnore = this.getNodeParameter('inputsToIgnore', i) as string; + const inputsToIgnore = rawInputsToIgnore.split(',').map(c => c.trim()); + + for (const key of incomingKeys) { + if (inputsToIgnore.includes(key)) continue; + item[key] = items[i].json[key] as string; + } + + body.Item = adjustPutItem(item as PutItemUi); + + } else { + + const fields = this.getNodeParameter('fieldsUi.fieldValues', i, []) as FieldsUiValues; + fields.forEach(({ fieldId, fieldValue }) => item[fieldId] = fieldValue); + body.Item = adjustPutItem(item as PutItemUi); + + } + + const headers = { + 'Content-Type': 'application/x-amz-json-1.0', + 'X-Amz-Target': 'DynamoDB_20120810.PutItem', + }; + + responseData = await awsApiRequest.call(this, 'dynamodb', 'POST', '/', body, headers); + responseData = item; + + } else if (operation === 'delete') { + + // ---------------------------------- + // delete + // ---------------------------------- + + // https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_DeleteItem.html + + // tslint:disable-next-line: no-any + const body: { [key: string]: any } = { + TableName: this.getNodeParameter('tableName', i) as string, + Key: {}, + ReturnValues: this.getNodeParameter('returnValues', 0) as string, + }; + + const eavUi = this.getNodeParameter('additionalFields.eavUi.eavValues', i, []) as IAttributeValueUi[]; + const eanUi = this.getNodeParameter('additionalFields.eanUi.eanValues', i, []) as IAttributeNameUi[]; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const simple = this.getNodeParameter('simple', 0, false) as boolean; + + const items = this.getNodeParameter('keysUi.keyValues', i, []) as [{ key: string, type: string, value: string }]; + + for (const item of items) { + let value = item.value as NodeParameterValue; + // All data has to get send as string even numbers + // @ts-ignore + value = ![null, undefined].includes(value) ? value?.toString() : ''; + body.Key[item.key as string] = { [item.type as string]: value }; + } + + const expressionAttributeValues = adjustExpressionAttributeValues(eavUi); + + if (Object.keys(expressionAttributeValues).length) { + body.ExpressionAttributeValues = expressionAttributeValues; + } + + const expressionAttributeName = adjustExpressionAttributeName(eanUi); + + if (Object.keys(expressionAttributeName).length) { + body.expressionAttributeNames = expressionAttributeName; + } + + const headers = { + 'Content-Type': 'application/x-amz-json-1.0', + 'X-Amz-Target': 'DynamoDB_20120810.DeleteItem', + }; + + if (additionalFields.conditionExpression) { + body.ConditionExpression = additionalFields.conditionExpression as string; + } + + responseData = await awsApiRequest.call(this, 'dynamodb', 'POST', '/', body, headers); + + if (!Object.keys(responseData).length) { + responseData = { success: true }; + } else if (simple === true) { + responseData = decodeItem(responseData.Attributes); + } + + } else if (operation === 'get') { + + // ---------------------------------- + // get + // ---------------------------------- + + // https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_GetItem.html + + const tableName = this.getNodeParameter('tableName', 0) as string; + const simple = this.getNodeParameter('simple', 0, false) as boolean; + const select = this.getNodeParameter('select', 0) as string; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const eanUi = this.getNodeParameter('additionalFields.eanUi.eanValues', i, []) as IAttributeNameUi[]; + + // tslint:disable-next-line: no-any + const body: { [key: string]: any } = { + TableName: tableName, + Key: {}, + Select: select, + }; + + Object.assign(body, additionalFields); + + const expressionAttributeName = adjustExpressionAttributeName(eanUi); + + if (Object.keys(expressionAttributeName).length) { + body.expressionAttributeNames = expressionAttributeName; + } + + if (additionalFields.readType) { + body.ConsistentRead = additionalFields.readType === 'stronglyConsistentRead'; + } + + if (additionalFields.projectionExpression) { + body.ProjectionExpression = additionalFields.projectionExpression as string; + } + + const items = this.getNodeParameter('keysUi.keyValues', i, []) as IDataObject[]; + + for (const item of items) { + let value = item.value as NodeParameterValue; + // All data has to get send as string even numbers + // @ts-ignore + value = ![null, undefined].includes(value) ? value?.toString() : ''; + body.Key[item.key as string] = { [item.type as string]: value }; + } + + const headers = { + 'X-Amz-Target': 'DynamoDB_20120810.GetItem', + 'Content-Type': 'application/x-amz-json-1.0', + }; + + responseData = await awsApiRequest.call(this, 'dynamodb', 'POST', '/', body, headers); + + responseData = responseData.Item; + + if (simple && responseData) { + responseData = decodeItem(responseData); + } + + } else if (operation === 'getAll') { + + // ---------------------------------- + // getAll + // ---------------------------------- + + // https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Query.html + + const eavUi = this.getNodeParameter('eavUi.eavValues', i, []) as IAttributeValueUi[]; + const simple = this.getNodeParameter('simple', 0, false) as boolean; + const select = this.getNodeParameter('select', 0) as string; + const returnAll = this.getNodeParameter('returnAll', 0) as boolean; + const eanUi = this.getNodeParameter('additionalFields.eanUi.eanValues', i, []) as IAttributeNameUi[]; + + const body: IRequestBody = { + TableName: this.getNodeParameter('tableName', i) as string, + KeyConditionExpression: this.getNodeParameter('keyConditionExpression', i) as string, + ExpressionAttributeValues: adjustExpressionAttributeValues(eavUi), + }; + + const { + indexName, + projectionExpression, + } = this.getNodeParameter('options', i) as { + indexName: string; + projectionExpression: string; + }; + + const expressionAttributeName = adjustExpressionAttributeName(eanUi); + + if (Object.keys(expressionAttributeName).length) { + body.expressionAttributeNames = expressionAttributeName; + } + + if (indexName) { + body.IndexName = indexName; + } + + if (projectionExpression && select !== 'COUNT') { + body.ProjectionExpression = projectionExpression; + } + + if (select) { + body.Select = select; + } + + const headers = { + 'Content-Type': 'application/json', + 'X-Amz-Target': 'DynamoDB_20120810.Query', + }; + + if (returnAll === true && select !== 'COUNT') { + responseData = await awsApiRequestAllItems.call(this, 'dynamodb', 'POST', '/', body, headers); + } else { + body.Limit = this.getNodeParameter('limit', 0, 1) as number; + responseData = await awsApiRequest.call(this, 'dynamodb', 'POST', '/', body, headers); + if (select !== 'COUNT') { + responseData = responseData.Items; + } + } + if (simple === true) { + responseData = responseData.map(simplify); + } + } + + Array.isArray(responseData) + ? returnData.push(...responseData) + : returnData.push(responseData); + } + + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + + throw error; + } + } + + return [this.helpers.returnJsonArray(returnData)]; + } +} diff --git a/packages/nodes-base/nodes/Aws/DynamoDB/GenericFunctions.ts b/packages/nodes-base/nodes/Aws/DynamoDB/GenericFunctions.ts new file mode 100644 index 0000000000..e9a5a0316b --- /dev/null +++ b/packages/nodes-base/nodes/Aws/DynamoDB/GenericFunctions.ts @@ -0,0 +1,108 @@ +import { + URL, +} from 'url'; + +import { + sign, +} from 'aws4'; + +import { + IExecuteFunctions, + IHookFunctions, + ILoadOptionsFunctions, + IWebhookFunctions, +} from 'n8n-core'; + +import { + ICredentialDataDecryptedObject, + IDataObject, + INodeExecutionData, +} from 'n8n-workflow'; + +import { + IRequestBody, +} from './types'; + +function getEndpointForService(service: string, credentials: ICredentialDataDecryptedObject): string { + let endpoint; + if (service === 'lambda' && credentials.lambdaEndpoint) { + endpoint = credentials.lambdaEndpoint; + } else if (service === 'sns' && credentials.snsEndpoint) { + endpoint = credentials.snsEndpoint; + } else { + endpoint = `https://${service}.${credentials.region}.amazonaws.com`; + } + return (endpoint as string).replace('{region}', credentials.region as string); +} + +export async function awsApiRequest(this: IHookFunctions | IExecuteFunctions | ILoadOptionsFunctions | IWebhookFunctions, service: string, method: string, path: string, body?: object | IRequestBody, headers?: object): Promise { // tslint:disable-line:no-any + const credentials = this.getCredentials('aws'); + if (credentials === undefined) { + throw new Error('No credentials got returned!'); + } + + // Concatenate path and instantiate URL object so it parses correctly query strings + const endpoint = new URL(getEndpointForService(service, credentials) + path); + + const options = sign({ + uri: endpoint, + service, + region: credentials.region, + method, + path: '/', + headers: { ...headers }, + body: JSON.stringify(body), + }, { + accessKeyId: credentials.accessKeyId, + secretAccessKey: credentials.secretAccessKey, + }); + + try { + return JSON.parse(await this.helpers.request!(options)); + } catch (error) { + const errorMessage = (error.response && error.response.body.message) || (error.response && error.response.body.Message) || error.message; + if (error.statusCode === 403) { + if (errorMessage === 'The security token included in the request is invalid.') { + throw new Error('The AWS credentials are not valid!'); + } else if (errorMessage.startsWith('The request signature we calculated does not match the signature you provided')) { + throw new Error('The AWS credentials are not valid!'); + } + } + + throw new Error(`AWS error response [${error.statusCode}]: ${errorMessage}`); + } +} + + +export async function awsApiRequestAllItems(this: IHookFunctions | IExecuteFunctions | ILoadOptionsFunctions | IWebhookFunctions, service: string, method: string, path: string, body?: IRequestBody, headers?: object): Promise { // tslint:disable-line:no-any + + const returnData: IDataObject[] = []; + + let responseData; + + do { + responseData = await awsApiRequest.call(this, service, method, path, body, headers); + if (responseData.LastEvaluatedKey) { + body!.ExclusiveStartKey = responseData.LastEvaluatedKey; + } + returnData.push(...responseData.Items); + } while ( + responseData.LastEvaluatedKey !== undefined + ); + + return returnData; +} + +export function copyInputItem(item: INodeExecutionData, properties: string[]): IDataObject { + // Prepare the data to insert and copy it to be returned + let newItem: IDataObject; + newItem = {}; + for (const property of properties) { + if (item.json[property] === undefined) { + newItem[property] = null; + } else { + newItem[property] = JSON.parse(JSON.stringify(item.json[property])); + } + } + return newItem; +} diff --git a/packages/nodes-base/nodes/Aws/DynamoDB/ItemDescription.ts b/packages/nodes-base/nodes/Aws/DynamoDB/ItemDescription.ts new file mode 100644 index 0000000000..47a7a02599 --- /dev/null +++ b/packages/nodes-base/nodes/Aws/DynamoDB/ItemDescription.ts @@ -0,0 +1,920 @@ +import { + INodeProperties, +} from 'n8n-workflow'; + +export const itemOperations = [ + { + displayName: 'Operation', + name: 'operation', + type: 'options', + displayOptions: { + show: { + resource: [ + 'item', + ], + }, + }, + options: [ + { + name: 'Create or Update', + value: 'upsert', + description: 'Create a new record, or update the current one if it already exists (upsert/put)', + }, + { + name: 'Delete', + value: 'delete', + description: 'Delete an item', + }, + { + name: 'Get', + value: 'get', + description: 'Get an item', + }, + { + name: 'Get All', + value: 'getAll', + description: 'Get all items', + }, + ], + default: 'upsert', + }, +] as INodeProperties[]; + +export const itemFields = [ + // ---------------------------------- + // all + // ---------------------------------- + { + displayName: 'Table Name', + name: 'tableName', + description: 'Table to operate on', + type: 'options', + required: true, + displayOptions: { + show: { + resource: [ + 'item', + ], + }, + }, + default: [], + typeOptions: { + loadOptionsMethod: 'getTables', + }, + }, + + // ---------------------------------- + // upsert + // ---------------------------------- + { + displayName: 'Data to Send', + name: 'dataToSend', + type: 'options', + options: [ + { + name: 'Auto-map Input Data to Columns', + value: 'autoMapInputData', + description: 'Use when node input properties match destination column names', + }, + { + name: 'Define Below for Each Column', + value: 'defineBelow', + description: 'Set the value for each destination column', + }, + ], + displayOptions: { + show: { + operation: [ + 'upsert', + ], + }, + }, + default: 'defineBelow', + description: 'Whether to insert the input data this node receives in the new row', + }, + { + displayName: 'Inputs to Ignore', + name: 'inputsToIgnore', + type: 'string', + displayOptions: { + show: { + operation: [ + 'upsert', + ], + dataToSend: [ + 'autoMapInputData', + ], + }, + }, + default: '', + required: false, + description: 'List of input properties to avoid sending, separated by commas. Leave empty to send all properties.', + placeholder: 'Enter properties...', + }, + { + displayName: 'Fields to Send', + name: 'fieldsUi', + placeholder: 'Add Field', + type: 'fixedCollection', + typeOptions: { + multipleValueButtonText: 'Add Field to Send', + multipleValues: true, + }, + displayOptions: { + show: { + operation: [ + 'upsert', + ], + dataToSend: [ + 'defineBelow', + ], + }, + }, + default: {}, + options: [ + { + displayName: 'Field', + name: 'fieldValues', + values: [ + { + displayName: 'Field ID', + name: 'fieldId', + type: 'string', + default: '', + }, + { + displayName: 'Field Value', + name: 'fieldValue', + type: 'string', + default: '', + }, + ], + }, + ], + }, + { + displayName: 'Additional Fields', + name: 'additionalFields', + type: 'collection', + placeholder: 'Add Field', + default: {}, + displayOptions: { + show: { + resource: [ + 'item', + ], + operation: [ + 'upsert', + ], + }, + }, + options: [ + { + displayName: 'Expression Attribute Values', + name: 'eavUi', + description: 'Substitution tokens for attribute names in an expression.
Only needed when the parameter "condition expression" is set', + placeholder: 'Add Attribute Value', + type: 'fixedCollection', + default: '', + required: true, + typeOptions: { + multipleValues: true, + minValue: 1, + }, + options: [ + { + name: 'eavValues', + displayName: 'Expression Attribute Vaue', + values: [ + { + displayName: 'Attribute', + name: 'attribute', + type: 'string', + default: '', + }, + { + displayName: 'Type', + name: 'type', + type: 'options', + options: [ + { + name: 'Number', + value: 'N', + }, + { + name: 'String', + value: 'S', + }, + ], + default: 'S', + }, + { + displayName: 'Value', + name: 'value', + type: 'string', + default: '', + }, + ], + }, + ], + }, + { + displayName: 'Condition Expression', + name: 'conditionExpression', + type: 'string', + default: '', + description: 'A condition that must be satisfied in order for a conditional upsert to succeed. View details', + }, + { + displayName: 'Expression Attribute Names', + name: 'eanUi', + placeholder: 'Add Expression', + type: 'fixedCollection', + default: '', + typeOptions: { + multipleValues: true, + }, + options: [ + { + name: 'eanValues', + displayName: 'Expression', + values: [ + { + displayName: 'Key', + name: 'key', + type: 'string', + default: '', + }, + { + displayName: 'Value', + name: 'value', + type: 'string', + default: '', + }, + ], + }, + ], + description: 'One or more substitution tokens for attribute names in an expression. View details', + }, + ], + }, + + // ---------------------------------- + // delete + // ---------------------------------- + { + displayName: 'Return', + name: 'returnValues', + type: 'options', + displayOptions: { + show: { + resource: [ + 'item', + ], + operation: [ + 'delete', + ], + }, + }, + options: [ + { + name: 'Attribute Values', + value: 'ALL_OLD', + description: 'The content of the old item is returned', + }, + { + name: 'Nothing', + value: 'NONE', + description: 'Nothing is returned', + }, + ], + default: 'NONE', + description: 'Use ReturnValues if you want to get the item attributes as they appeared before they were deleted', + }, + { + displayName: 'Keys', + name: 'keysUi', + type: 'fixedCollection', + placeholder: 'Add Key', + default: {}, + typeOptions: { + multipleValues: true, + }, + displayOptions: { + show: { + resource: [ + 'item', + ], + operation: [ + 'delete', + ], + }, + }, + options: [ + { + displayName: 'Key', + name: 'keyValues', + values: [ + { + displayName: 'Key', + name: 'key', + type: 'string', + default: '', + }, + { + displayName: 'Type', + name: 'type', + type: 'options', + options: [ + { + name: 'Binary', + value: 'B', + }, + { + name: 'Number', + value: 'N', + }, + { + name: 'String', + value: 'S', + }, + ], + default: 'S', + }, + { + displayName: 'Value', + name: 'value', + type: 'string', + default: '', + }, + ], + }, + ], + description: 'Item\'s primary key. For example, with a simple primary key, you only need to provide a value for the partition key.
For a composite primary key, you must provide values for both the partition key and the sort key', + }, + { + displayName: 'Simple', + name: 'simple', + type: 'boolean', + displayOptions: { + show: { + resource: [ + 'item', + ], + operation: [ + 'delete', + ], + returnValues: [ + 'ALL_OLD', + ], + }, + }, + default: true, + description: 'Whether to return a simplified version of the response instead of the raw data', + }, + { + displayName: 'Additional Fields', + name: 'additionalFields', + type: 'collection', + placeholder: 'Add Field', + default: {}, + displayOptions: { + show: { + resource: [ + 'item', + ], + operation: [ + 'delete', + ], + }, + }, + options: [ + { + displayName: 'Condition Expression', + name: 'conditionExpression', + type: 'string', + default: '', + description: 'A condition that must be satisfied in order for a conditional delete to succeed', + }, + { + displayName: 'Expression Attribute Names', + name: 'eanUi', + placeholder: 'Add Expression', + type: 'fixedCollection', + default: '', + typeOptions: { + multipleValues: true, + }, + options: [ + { + name: 'eanValues', + displayName: 'Expression', + values: [ + { + displayName: 'Key', + name: 'key', + type: 'string', + default: '', + }, + { + displayName: 'Value', + name: 'value', + type: 'string', + default: '', + }, + ], + }, + ], + description: 'One or more substitution tokens for attribute names in an expression. Check Info', + }, + { + displayName: 'Expression Attribute Values', + name: 'expressionAttributeUi', + description: 'Substitution tokens for attribute names in an expression.
Only needed when the parameter "condition expression" is set', + placeholder: 'Add Attribute Value', + type: 'fixedCollection', + default: '', + required: true, + typeOptions: { + multipleValues: true, + minValue: 1, + }, + options: [ + { + name: 'expressionAttributeValues', + displayName: 'Expression Attribute Vaue', + values: [ + { + displayName: 'Attribute', + name: 'attribute', + type: 'string', + default: '', + }, + { + displayName: 'Type', + name: 'type', + type: 'options', + options: [ + { + name: 'Number', + value: 'N', + }, + { + name: 'String', + value: 'S', + }, + ], + default: 'S', + }, + { + displayName: 'Value', + name: 'value', + type: 'string', + default: '', + }, + ], + }, + ], + }, + ], + }, + + // ---------------------------------- + // get + // ---------------------------------- + { + displayName: 'Select', + name: 'select', + type: 'options', + displayOptions: { + show: { + resource: [ + 'item', + ], + operation: [ + 'get', + ], + }, + }, + options: [ + { + name: 'All Attributes', + value: 'ALL_ATTRIBUTES', + }, + { + name: 'All Projected Attributes', + value: 'ALL_PROJECTED_ATTRIBUTES', + }, + { + name: 'Specific Attributes', + value: 'SPECIFIC_ATTRIBUTES', + description: 'Select them in Attributes to Select under Additional Fields', + }, + ], + default: 'ALL_ATTRIBUTES', + }, + { + displayName: 'Simple', + name: 'simple', + type: 'boolean', + displayOptions: { + show: { + resource: [ + 'item', + ], + operation: [ + 'get', + ], + select: [ + 'ALL_PROJECTED_ATTRIBUTES', + 'ALL_ATTRIBUTES', + ], + }, + }, + default: true, + description: 'Whether to return a simplified version of the response instead of the raw data', + }, + { + displayName: 'Keys', + name: 'keysUi', + type: 'fixedCollection', + placeholder: 'Add Key', + default: {}, + typeOptions: { + multipleValues: true, + }, + displayOptions: { + show: { + resource: [ + 'item', + ], + operation: [ + 'get', + ], + }, + }, + options: [ + { + displayName: 'Key', + name: 'keyValues', + values: [ + { + displayName: 'Key', + name: 'key', + type: 'string', + default: '', + }, + { + displayName: 'Type', + name: 'type', + type: 'options', + options: [ + { + name: 'Binary', + value: 'B', + }, + { + name: 'Number', + value: 'N', + }, + { + name: 'String', + value: 'S', + }, + ], + default: 'S', + }, + { + displayName: 'Value', + name: 'value', + type: 'string', + default: '', + }, + ], + }, + ], + description: 'Item\'s primary key. For example, with a simple primary key, you only need to provide a value for the partition key.
For a composite primary key, you must provide values for both the partition key and the sort key', + }, + { + displayName: 'Additional Fields', + name: 'additionalFields', + type: 'collection', + placeholder: 'Add Field', + default: {}, + displayOptions: { + show: { + resource: [ + 'item', + ], + operation: [ + 'get', + ], + }, + }, + options: [ + { + displayName: 'Attributes to Select', + name: 'projectionExpression', + type: 'string', + placeholder: 'id, name', + default: '', + }, + { + displayName: 'Expression Attribute Names', + name: 'eanUi', + placeholder: 'Add Expression', + type: 'fixedCollection', + default: '', + typeOptions: { + multipleValues: true, + }, + options: [ + { + name: 'eanValues', + displayName: 'Expression', + values: [ + { + displayName: 'Key', + name: 'key', + type: 'string', + default: '', + }, + { + displayName: 'Value', + name: 'value', + type: 'string', + default: '', + }, + ], + }, + ], + description: 'One or more substitution tokens for attribute names in an expression. View details', + }, + { + displayName: 'Read Type', + name: 'readType', + type: 'options', + options: [ + { + name: 'Strongly consistent read', + value: 'stronglyConsistentRead', + }, + { + name: 'Eventually consistent read', + value: 'eventuallyConsistentRead', + }, + ], + default: 'eventuallyConsistentRead', + description: 'Type of read to perform on the table. View details', + }, + ], + }, + + // ---------------------------------- + // Get All + // ---------------------------------- + { + displayName: 'Key Condition Expression', + name: 'keyConditionExpression', + description: 'Condition to determine the items to be retrieved. The condition must perform an equality test
on a single partition key value, in this format: partitionKeyName = :partitionkeyval', + placeholder: 'id = :id', + default: '', + type: 'string', + required: true, + displayOptions: { + show: { + resource: [ + 'item', + ], + operation: [ + 'getAll', + ], + }, + }, + }, + { + displayName: 'Expression Attribute Values', + name: 'eavUi', + description: 'Substitution tokens for attribute names in an expression', + placeholder: 'Add Attribute Value', + type: 'fixedCollection', + default: '', + required: true, + typeOptions: { + multipleValues: true, + minValue: 1, + }, + displayOptions: { + show: { + resource: [ + 'item', + ], + operation: [ + 'getAll', + ], + }, + }, + options: [ + { + name: 'eavValues', + displayName: 'Expression Attribute Vaue', + values: [ + { + displayName: 'Attribute', + name: 'attribute', + type: 'string', + default: '', + }, + { + displayName: 'Type', + name: 'type', + type: 'options', + options: [ + { + name: 'Number', + value: 'N', + }, + { + name: 'String', + value: 'S', + }, + ], + default: 'S', + }, + { + displayName: 'Value', + name: 'value', + type: 'string', + default: '', + }, + ], + }, + ], + }, + { + displayName: 'Return All', + name: 'returnAll', + type: 'boolean', + displayOptions: { + show: { + resource: [ + 'item', + ], + operation: [ + 'getAll', + ], + }, + }, + default: false, + description: 'Whether to return all results or only up to a given limit', + }, + { + displayName: 'Limit', + name: 'limit', + type: 'number', + displayOptions: { + show: { + operation: [ + 'getAll', + ], + returnAll: [ + false, + ], + }, + }, + typeOptions: { + minValue: 1, + maxValue: 100, + }, + default: 50, + description: 'How many results to return', + }, + { + displayName: 'Select', + name: 'select', + type: 'options', + displayOptions: { + show: { + resource: [ + 'item', + ], + operation: [ + 'getAll', + ], + }, + }, + options: [ + { + name: 'All Attributes', + value: 'ALL_ATTRIBUTES', + }, + { + name: 'All Projected Attributes', + value: 'ALL_PROJECTED_ATTRIBUTES', + }, + { + name: 'Count', + value: 'COUNT', + }, + { + name: 'Specific Attributes', + value: 'SPECIFIC_ATTRIBUTES', + description: 'Select them in Attributes to Select under Additional Fields', + }, + ], + default: 'ALL_ATTRIBUTES', + }, + { + displayName: 'Simple', + name: 'simple', + type: 'boolean', + displayOptions: { + show: { + resource: [ + 'item', + ], + operation: [ + 'getAll', + ], + select: [ + 'ALL_PROJECTED_ATTRIBUTES', + 'ALL_ATTRIBUTES', + 'SPECIFIC_ATTRIBUTES', + ], + }, + }, + default: true, + description: 'Whether to return a simplified version of the response instead of the raw data', + }, + { + displayName: 'Options', + name: 'options', + type: 'collection', + placeholder: 'Add Field', + default: {}, + displayOptions: { + show: { + resource: [ + 'item', + ], + operation: [ + 'getAll', + ], + }, + }, + options: [ + { + displayName: 'Index Name', + name: 'indexName', + description: 'Name of the index to query. It can be any
secondary local or global index on the table.', + type: 'string', + default: '', + }, + { + displayName: 'Attributes to Select', + name: 'projectionExpression', + type: 'string', + default: '', + description: 'Text that identifies one or more attributes to retrieve from the table.
These attributes can include scalars, sets, or elements of a JSON document. The attributes
in the expression must be separated by commas', + }, + { + displayName: 'Filter Expression', + name: 'filterExpression', + type: 'string', + default: '', + description: 'Text that contains conditions that DynamoDB applies after the Query operation,
but before the data is returned. Items that do not satisfy the FilterExpression criteria
are not returned', + }, + { + displayName: 'Expression Attribute Names', + name: 'eanUi', + placeholder: 'Add Expression', + type: 'fixedCollection', + default: '', + typeOptions: { + multipleValues: true, + }, + options: [ + { + name: 'eanValues', + displayName: 'Expression', + values: [ + { + displayName: 'Key', + name: 'key', + type: 'string', + default: '', + }, + { + displayName: 'Value', + name: 'value', + type: 'string', + default: '', + }, + ], + }, + ], + description: 'One or more substitution tokens for attribute names in an expression. Check Info', + }, + ], + }, +] as INodeProperties[]; diff --git a/packages/nodes-base/nodes/Aws/DynamoDB/dynamodb.svg b/packages/nodes-base/nodes/Aws/DynamoDB/dynamodb.svg new file mode 100644 index 0000000000..a3293dcc7e --- /dev/null +++ b/packages/nodes-base/nodes/Aws/DynamoDB/dynamodb.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/packages/nodes-base/nodes/Aws/DynamoDB/types.d.ts b/packages/nodes-base/nodes/Aws/DynamoDB/types.d.ts new file mode 100644 index 0000000000..99eada32c7 --- /dev/null +++ b/packages/nodes-base/nodes/Aws/DynamoDB/types.d.ts @@ -0,0 +1,79 @@ +export interface IRequestBody { + [key: string]: string | IAttributeValue | undefined | boolean | object | number; + TableName: string; + Key?: object; + IndexName?: string; + ProjectionExpression?: string; + KeyConditionExpression?: string; + ExpressionAttributeValues?: IAttributeValue; + ConsistentRead?: boolean; + FilterExpression?: string; + Limit?: number; + ExclusiveStartKey?: IAttributeValue; +} + +export interface IAttributeValue { + [attribute: string]: IAttributeValueValue; +} + +interface IAttributeValueValue { + [type: string]: string | string[] | IAttributeValue[]; +} + +export interface IAttributeValueUi { + attribute: string; + type: AttributeValueType; + value: string; +} + +export interface IAttributeNameUi { + key: string; + value: string; +} + +type AttributeValueType = + | 'B' // binary + | 'BOOL' // boolean + | 'BS' // binary set + | 'L' // list + | 'M' // map + | 'N' // number + | 'NULL' + | 'NS' // number set + | 'S' // string + | 'SS'; // string set + +export type PartitionKey = { + details: { + name: string; + type: string; + value: string; + }, +}; + +export enum EAttributeValueType { + S = 'S', SS = 'SS', M = 'M', L = 'L', NS = 'NS', N = 'N', BOOL = 'BOOL', B = 'B', BS = 'BS', NULL = 'NULL', +} + +export interface IExpressionAttributeValue { + attribute: string; + type: EAttributeValueType; + value: string; +} + +export type FieldsUiValues = Array<{ + fieldId: string; + fieldValue: string; +}>; + +export type PutItemUi = { + attribute: string; + type: 'S' | 'N'; + value: string; +}; + +export type AdjustedPutItem = { + [attribute: string]: { + [type: string]: string + } +}; diff --git a/packages/nodes-base/nodes/Aws/DynamoDB/utils.ts b/packages/nodes-base/nodes/Aws/DynamoDB/utils.ts new file mode 100644 index 0000000000..876b56c57a --- /dev/null +++ b/packages/nodes-base/nodes/Aws/DynamoDB/utils.ts @@ -0,0 +1,134 @@ +import { + IDataObject, + INodeExecutionData, +} from 'n8n-workflow'; + +import { + AdjustedPutItem, + AttributeValueType, + EAttributeValueType, + IAttributeNameUi, + IAttributeValue, + IAttributeValueUi, + IAttributeValueValue, + PutItemUi, +} from './types'; + +const addColon = (attribute: string) => attribute = attribute.charAt(0) === ':' ? attribute : `:${attribute}`; + +const addPound = (key: string) => key = key.charAt(0) === '#' ? key : `#${key}`; + +export function adjustExpressionAttributeValues(eavUi: IAttributeValueUi[]) { + const eav: IAttributeValue = {}; + + eavUi.forEach(({ attribute, type, value }) => { + eav[addColon(attribute)] = { [type]: value } as IAttributeValueValue; + }); + + return eav; +} + +export function adjustExpressionAttributeName(eanUi: IAttributeNameUi[]) { + + // tslint:disable-next-line: no-any + const ean: { [key: string]: any } = {}; + + eanUi.forEach(({ key, value }) => { + ean[addPound(key)] = { value } as IAttributeValueValue; + }); + + return ean; +} + +export function adjustPutItem(putItemUi: PutItemUi) { + const adjustedPutItem: AdjustedPutItem = {}; + + Object.entries(putItemUi).forEach(([attribute, value]) => { + let type: string; + + if (typeof value === 'boolean') { + type = 'BOOL'; + } else if (typeof value === 'object' && !Array.isArray(value) && value !== null) { + type = 'M'; + // @ts-ignore + } else if (isNaN(value)) { + type = 'S'; + } else { + type = 'N'; + } + + adjustedPutItem[attribute] = { [type]: value.toString() }; + }); + + return adjustedPutItem; +} + +export function simplify(item: IAttributeValue): IDataObject { + const output: IDataObject = {}; + + for (const [attribute, value] of Object.entries(item)) { + const [type, content] = Object.entries(value)[0] as [AttributeValueType, string]; + output[attribute] = decodeAttribute(type, content); + } + + return output; +} + +function decodeAttribute(type: AttributeValueType, attribute: string) { + switch (type) { + case 'BOOL': + return Boolean(attribute); + case 'N': + return Number(attribute); + case 'S': + return String(attribute); + case 'SS': + case 'NS': + return attribute; + default: + return null; + } +} + +// tslint:disable-next-line: no-any +export function validateJSON(input: any): object { + try { + return JSON.parse(input); + } catch (error) { + throw new Error('Items must be a valid JSON'); + } +} + +export function copyInputItem(item: INodeExecutionData, properties: string[]): IDataObject { + // Prepare the data to insert and copy it to be returned + let newItem: IDataObject; + newItem = {}; + for (const property of properties) { + if (item.json[property] === undefined) { + newItem[property] = null; + } else { + newItem[property] = JSON.parse(JSON.stringify(item.json[property])); + } + } + return newItem; +} + +export function mapToAttributeValues(item: IDataObject): void { + for (const key of Object.keys(item)) { + if (!key.startsWith(':')) { + item[`:${key}`] = item[key]; + delete item[key]; + } + } +} + +export function decodeItem(item: IAttributeValue): IDataObject { + const _item: IDataObject = {}; + for (const entry of Object.entries(item)) { + const [attribute, value]: [string, object] = entry; + const [type, content]: [string, object] = Object.entries(value)[0]; + _item[attribute] = decodeAttribute(type as EAttributeValueType, content as unknown as string); + } + + return _item; +} diff --git a/packages/nodes-base/package.json b/packages/nodes-base/package.json index f4aacdc008..56e66497ac 100644 --- a/packages/nodes-base/package.json +++ b/packages/nodes-base/package.json @@ -305,6 +305,7 @@ "dist/nodes/Autopilot/AutopilotTrigger.node.js", "dist/nodes/Aws/AwsLambda.node.js", "dist/nodes/Aws/Comprehend/AwsComprehend.node.js", + "dist/nodes/Aws/DynamoDB/AwsDynamoDB.node.js", "dist/nodes/Aws/Rekognition/AwsRekognition.node.js", "dist/nodes/Aws/S3/AwsS3.node.js", "dist/nodes/Aws/SES/AwsSes.node.js", From 3aec53e2cca8395d5187a87e0e2f5be96067cecc Mon Sep 17 00:00:00 2001 From: Jan Oberhauser Date: Sun, 18 Jul 2021 00:02:39 +0200 Subject: [PATCH 04/15] :bug: Fix some issues with uncaught errors #1906 --- packages/cli/src/Server.ts | 373 +++++++++++++++++++------------------ 1 file changed, 194 insertions(+), 179 deletions(-) diff --git a/packages/cli/src/Server.ts b/packages/cli/src/Server.ts index ee2f50f2cf..b36a0fe0f9 100644 --- a/packages/cli/src/Server.ts +++ b/packages/cli/src/Server.ts @@ -927,32 +927,37 @@ class App { // Returns the node icon this.app.get([`/${this.restEndpoint}/node-icon/:nodeType`, `/${this.restEndpoint}/node-icon/:scope/:nodeType`], async (req: express.Request, res: express.Response): Promise => { - const nodeTypeName = `${req.params.scope ? `${req.params.scope}/` : ''}${req.params.nodeType}`; + try { + const nodeTypeName = `${req.params.scope ? `${req.params.scope}/` : ''}${req.params.nodeType}`; - const nodeTypes = NodeTypes(); - const nodeType = nodeTypes.getByName(nodeTypeName); + const nodeTypes = NodeTypes(); + const nodeType = nodeTypes.getByName(nodeTypeName); - if (nodeType === undefined) { - res.status(404).send('The nodeType is not known.'); - return; + if (nodeType === undefined) { + res.status(404).send('The nodeType is not known.'); + return; + } + + if (nodeType.description.icon === undefined) { + res.status(404).send('No icon found for node.'); + return; + } + + if (!nodeType.description.icon.startsWith('file:')) { + res.status(404).send('Node does not have a file icon.'); + return; + } + + const filepath = nodeType.description.icon.substr(5); + + const maxAge = 7 * 24 * 60 * 60 * 1000; // 7 days + res.setHeader('Cache-control', `private max-age=${maxAge}`); + + res.sendFile(filepath); + } catch (error) { + // Error response + return ResponseHelper.sendErrorResponse(res, error); } - - if (nodeType.description.icon === undefined) { - res.status(404).send('No icon found for node.'); - return; - } - - if (!nodeType.description.icon.startsWith('file:')) { - res.status(404).send('Node does not have a file icon.'); - return; - } - - const filepath = nodeType.description.icon.substr(5); - - const maxAge = 7 * 24 * 60 * 60 * 1000; // 7 days - res.setHeader('Cache-control', `private max-age=${maxAge}`); - - res.sendFile(filepath); }); @@ -1316,70 +1321,75 @@ class App { // Verify and store app code. Generate access tokens and store for respective credential. this.app.get(`/${this.restEndpoint}/oauth1-credential/callback`, async (req: express.Request, res: express.Response) => { - const { oauth_verifier, oauth_token, cid } = req.query; - - if (oauth_verifier === undefined || oauth_token === undefined) { - const errorResponse = new ResponseHelper.ResponseError('Insufficient parameters for OAuth1 callback. Received following query parameters: ' + JSON.stringify(req.query), undefined, 503); - return ResponseHelper.sendErrorResponse(res, errorResponse); - } - - const result = await Db.collections.Credentials!.findOne(cid as any); // tslint:disable-line:no-any - if (result === undefined) { - const errorResponse = new ResponseHelper.ResponseError('The credential is not known.', undefined, 404); - return ResponseHelper.sendErrorResponse(res, errorResponse); - } - - let encryptionKey = undefined; - encryptionKey = await UserSettings.getEncryptionKey(); - if (encryptionKey === undefined) { - const errorResponse = new ResponseHelper.ResponseError('No encryption key got found to decrypt the credentials!', undefined, 503); - return ResponseHelper.sendErrorResponse(res, errorResponse); - } - - // Decrypt the currently saved credentials - const workflowCredentials: IWorkflowCredentials = { - [result.type as string]: { - [result.name as string]: result as ICredentialsEncrypted, - }, - }; - const mode: WorkflowExecuteMode = 'internal'; - const credentialsHelper = new CredentialsHelper(workflowCredentials, encryptionKey); - const decryptedDataOriginal = credentialsHelper.getDecrypted(result.name, result.type, mode, true); - const oauthCredentials = credentialsHelper.applyDefaultsAndOverwrites(decryptedDataOriginal, result.type, mode); - - const options: OptionsWithUrl = { - method: 'POST', - url: _.get(oauthCredentials, 'accessTokenUrl') as string, - qs: { - oauth_token, - oauth_verifier, - }, - }; - - let oauthToken; - try { - oauthToken = await requestPromise(options); + const { oauth_verifier, oauth_token, cid } = req.query; + + if (oauth_verifier === undefined || oauth_token === undefined) { + const errorResponse = new ResponseHelper.ResponseError('Insufficient parameters for OAuth1 callback. Received following query parameters: ' + JSON.stringify(req.query), undefined, 503); + return ResponseHelper.sendErrorResponse(res, errorResponse); + } + + const result = await Db.collections.Credentials!.findOne(cid as any); // tslint:disable-line:no-any + if (result === undefined) { + const errorResponse = new ResponseHelper.ResponseError('The credential is not known.', undefined, 404); + return ResponseHelper.sendErrorResponse(res, errorResponse); + } + + let encryptionKey = undefined; + encryptionKey = await UserSettings.getEncryptionKey(); + if (encryptionKey === undefined) { + const errorResponse = new ResponseHelper.ResponseError('No encryption key got found to decrypt the credentials!', undefined, 503); + return ResponseHelper.sendErrorResponse(res, errorResponse); + } + + // Decrypt the currently saved credentials + const workflowCredentials: IWorkflowCredentials = { + [result.type as string]: { + [result.name as string]: result as ICredentialsEncrypted, + }, + }; + const mode: WorkflowExecuteMode = 'internal'; + const credentialsHelper = new CredentialsHelper(workflowCredentials, encryptionKey); + const decryptedDataOriginal = credentialsHelper.getDecrypted(result.name, result.type, mode, true); + const oauthCredentials = credentialsHelper.applyDefaultsAndOverwrites(decryptedDataOriginal, result.type, mode); + + const options: OptionsWithUrl = { + method: 'POST', + url: _.get(oauthCredentials, 'accessTokenUrl') as string, + qs: { + oauth_token, + oauth_verifier, + }, + }; + + let oauthToken; + + try { + oauthToken = await requestPromise(options); + } catch (error) { + const errorResponse = new ResponseHelper.ResponseError('Unable to get access tokens!', undefined, 404); + return ResponseHelper.sendErrorResponse(res, errorResponse); + } + + // Response comes as x-www-form-urlencoded string so convert it to JSON + + const oauthTokenJson = querystring.parse(oauthToken); + + decryptedDataOriginal.oauthTokenData = oauthTokenJson; + + const credentials = new Credentials(result.name, result.type, result.nodesAccess); + credentials.setData(decryptedDataOriginal, encryptionKey); + const newCredentialsData = credentials.getDataToSave() as unknown as ICredentialsDb; + // Add special database related data + newCredentialsData.updatedAt = this.getCurrentDate(); + // Save the credentials in DB + await Db.collections.Credentials!.update(cid as any, newCredentialsData); // tslint:disable-line:no-any + + res.sendFile(pathResolve(__dirname, '../../templates/oauth-callback.html')); } catch (error) { - const errorResponse = new ResponseHelper.ResponseError('Unable to get access tokens!', undefined, 404); - return ResponseHelper.sendErrorResponse(res, errorResponse); + // Error response + return ResponseHelper.sendErrorResponse(res, error); } - - // Response comes as x-www-form-urlencoded string so convert it to JSON - - const oauthTokenJson = querystring.parse(oauthToken); - - decryptedDataOriginal.oauthTokenData = oauthTokenJson; - - const credentials = new Credentials(result.name, result.type, result.nodesAccess); - credentials.setData(decryptedDataOriginal, encryptionKey); - const newCredentialsData = credentials.getDataToSave() as unknown as ICredentialsDb; - // Add special database related data - newCredentialsData.updatedAt = this.getCurrentDate(); - // Save the credentials in DB - await Db.collections.Credentials!.update(cid as any, newCredentialsData); // tslint:disable-line:no-any - - res.sendFile(pathResolve(__dirname, '../../templates/oauth-callback.html')); }); @@ -1478,111 +1488,116 @@ class App { // Verify and store app code. Generate access tokens and store for respective credential. this.app.get(`/${this.restEndpoint}/oauth2-credential/callback`, async (req: express.Request, res: express.Response) => { - - // realmId it's currently just use for the quickbook OAuth2 flow - const { code, state: stateEncoded } = req.query; - - if (code === undefined || stateEncoded === undefined) { - const errorResponse = new ResponseHelper.ResponseError('Insufficient parameters for OAuth2 callback. Received following query parameters: ' + JSON.stringify(req.query), undefined, 503); - return ResponseHelper.sendErrorResponse(res, errorResponse); - } - - let state; try { - state = JSON.parse(Buffer.from(stateEncoded as string, 'base64').toString()); - } catch (error) { - const errorResponse = new ResponseHelper.ResponseError('Invalid state format returned', undefined, 503); - return ResponseHelper.sendErrorResponse(res, errorResponse); - } - const result = await Db.collections.Credentials!.findOne(state.cid); - if (result === undefined) { - const errorResponse = new ResponseHelper.ResponseError('The credential is not known.', undefined, 404); - return ResponseHelper.sendErrorResponse(res, errorResponse); - } + // realmId it's currently just use for the quickbook OAuth2 flow + const { code, state: stateEncoded } = req.query; - let encryptionKey = undefined; - encryptionKey = await UserSettings.getEncryptionKey(); - if (encryptionKey === undefined) { - const errorResponse = new ResponseHelper.ResponseError('No encryption key got found to decrypt the credentials!', undefined, 503); - return ResponseHelper.sendErrorResponse(res, errorResponse); - } + if (code === undefined || stateEncoded === undefined) { + const errorResponse = new ResponseHelper.ResponseError('Insufficient parameters for OAuth2 callback. Received following query parameters: ' + JSON.stringify(req.query), undefined, 503); + return ResponseHelper.sendErrorResponse(res, errorResponse); + } - // Decrypt the currently saved credentials - const workflowCredentials: IWorkflowCredentials = { - [result.type as string]: { - [result.name as string]: result as ICredentialsEncrypted, - }, - }; - const mode: WorkflowExecuteMode = 'internal'; - const credentialsHelper = new CredentialsHelper(workflowCredentials, encryptionKey); - const decryptedDataOriginal = credentialsHelper.getDecrypted(result.name, result.type, mode, true); - const oauthCredentials = credentialsHelper.applyDefaultsAndOverwrites(decryptedDataOriginal, result.type, mode); + let state; + try { + state = JSON.parse(Buffer.from(stateEncoded as string, 'base64').toString()); + } catch (error) { + const errorResponse = new ResponseHelper.ResponseError('Invalid state format returned', undefined, 503); + return ResponseHelper.sendErrorResponse(res, errorResponse); + } - const token = new csrf(); - if (decryptedDataOriginal.csrfSecret === undefined || !token.verify(decryptedDataOriginal.csrfSecret as string, state.token)) { - const errorResponse = new ResponseHelper.ResponseError('The OAuth2 callback state is invalid!', undefined, 404); - return ResponseHelper.sendErrorResponse(res, errorResponse); - } + const result = await Db.collections.Credentials!.findOne(state.cid); + if (result === undefined) { + const errorResponse = new ResponseHelper.ResponseError('The credential is not known.', undefined, 404); + return ResponseHelper.sendErrorResponse(res, errorResponse); + } - let options = {}; + let encryptionKey = undefined; + encryptionKey = await UserSettings.getEncryptionKey(); + if (encryptionKey === undefined) { + const errorResponse = new ResponseHelper.ResponseError('No encryption key got found to decrypt the credentials!', undefined, 503); + return ResponseHelper.sendErrorResponse(res, errorResponse); + } - const oAuth2Parameters = { - clientId: _.get(oauthCredentials, 'clientId') as string, - clientSecret: _.get(oauthCredentials, 'clientSecret', '') as string | undefined, - accessTokenUri: _.get(oauthCredentials, 'accessTokenUrl', '') as string, - authorizationUri: _.get(oauthCredentials, 'authUrl', '') as string, - redirectUri: `${WebhookHelpers.getWebhookBaseUrl()}${this.restEndpoint}/oauth2-credential/callback`, - scopes: _.split(_.get(oauthCredentials, 'scope', 'openid,') as string, ','), - }; - - if (_.get(oauthCredentials, 'authentication', 'header') as string === 'body') { - options = { - body: { - client_id: _.get(oauthCredentials, 'clientId') as string, - client_secret: _.get(oauthCredentials, 'clientSecret', '') as string, + // Decrypt the currently saved credentials + const workflowCredentials: IWorkflowCredentials = { + [result.type as string]: { + [result.name as string]: result as ICredentialsEncrypted, }, }; - delete oAuth2Parameters.clientSecret; + const mode: WorkflowExecuteMode = 'internal'; + const credentialsHelper = new CredentialsHelper(workflowCredentials, encryptionKey); + const decryptedDataOriginal = credentialsHelper.getDecrypted(result.name, result.type, mode, true); + const oauthCredentials = credentialsHelper.applyDefaultsAndOverwrites(decryptedDataOriginal, result.type, mode); + + const token = new csrf(); + if (decryptedDataOriginal.csrfSecret === undefined || !token.verify(decryptedDataOriginal.csrfSecret as string, state.token)) { + const errorResponse = new ResponseHelper.ResponseError('The OAuth2 callback state is invalid!', undefined, 404); + return ResponseHelper.sendErrorResponse(res, errorResponse); + } + + let options = {}; + + const oAuth2Parameters = { + clientId: _.get(oauthCredentials, 'clientId') as string, + clientSecret: _.get(oauthCredentials, 'clientSecret', '') as string | undefined, + accessTokenUri: _.get(oauthCredentials, 'accessTokenUrl', '') as string, + authorizationUri: _.get(oauthCredentials, 'authUrl', '') as string, + redirectUri: `${WebhookHelpers.getWebhookBaseUrl()}${this.restEndpoint}/oauth2-credential/callback`, + scopes: _.split(_.get(oauthCredentials, 'scope', 'openid,') as string, ','), + }; + + if (_.get(oauthCredentials, 'authentication', 'header') as string === 'body') { + options = { + body: { + client_id: _.get(oauthCredentials, 'clientId') as string, + client_secret: _.get(oauthCredentials, 'clientSecret', '') as string, + }, + }; + delete oAuth2Parameters.clientSecret; + } + + await this.externalHooks.run('oauth2.callback', [oAuth2Parameters]); + + const oAuthObj = new clientOAuth2(oAuth2Parameters); + + const queryParameters = req.originalUrl.split('?').splice(1, 1).join(''); + + const oauthToken = await oAuthObj.code.getToken(`${oAuth2Parameters.redirectUri}?${queryParameters}`, options); + + if (Object.keys(req.query).length > 2) { + _.set(oauthToken.data, 'callbackQueryString', _.omit(req.query, 'state', 'code')); + } + + if (oauthToken === undefined) { + const errorResponse = new ResponseHelper.ResponseError('Unable to get access tokens!', undefined, 404); + return ResponseHelper.sendErrorResponse(res, errorResponse); + } + + if (decryptedDataOriginal.oauthTokenData) { + // Only overwrite supplied data as some providers do for example just return the + // refresh_token on the very first request and not on subsequent ones. + Object.assign(decryptedDataOriginal.oauthTokenData, oauthToken.data); + } else { + // No data exists so simply set + decryptedDataOriginal.oauthTokenData = oauthToken.data; + } + + _.unset(decryptedDataOriginal, 'csrfSecret'); + + const credentials = new Credentials(result.name, result.type, result.nodesAccess); + credentials.setData(decryptedDataOriginal, encryptionKey); + const newCredentialsData = credentials.getDataToSave() as unknown as ICredentialsDb; + // Add special database related data + newCredentialsData.updatedAt = this.getCurrentDate(); + // Save the credentials in DB + await Db.collections.Credentials!.update(state.cid, newCredentialsData); + + res.sendFile(pathResolve(__dirname, '../../templates/oauth-callback.html')); + } catch (error) { + // Error response + return ResponseHelper.sendErrorResponse(res, error); } - - await this.externalHooks.run('oauth2.callback', [oAuth2Parameters]); - - const oAuthObj = new clientOAuth2(oAuth2Parameters); - - const queryParameters = req.originalUrl.split('?').splice(1, 1).join(''); - - const oauthToken = await oAuthObj.code.getToken(`${oAuth2Parameters.redirectUri}?${queryParameters}`, options); - - if (Object.keys(req.query).length > 2) { - _.set(oauthToken.data, 'callbackQueryString', _.omit(req.query, 'state', 'code')); - } - - if (oauthToken === undefined) { - const errorResponse = new ResponseHelper.ResponseError('Unable to get access tokens!', undefined, 404); - return ResponseHelper.sendErrorResponse(res, errorResponse); - } - - if (decryptedDataOriginal.oauthTokenData) { - // Only overwrite supplied data as some providers do for example just return the - // refresh_token on the very first request and not on subsequent ones. - Object.assign(decryptedDataOriginal.oauthTokenData, oauthToken.data); - } else { - // No data exists so simply set - decryptedDataOriginal.oauthTokenData = oauthToken.data; - } - - _.unset(decryptedDataOriginal, 'csrfSecret'); - - const credentials = new Credentials(result.name, result.type, result.nodesAccess); - credentials.setData(decryptedDataOriginal, encryptionKey); - const newCredentialsData = credentials.getDataToSave() as unknown as ICredentialsDb; - // Add special database related data - newCredentialsData.updatedAt = this.getCurrentDate(); - // Save the credentials in DB - await Db.collections.Credentials!.update(state.cid, newCredentialsData); - - res.sendFile(pathResolve(__dirname, '../../templates/oauth-callback.html')); }); From b531f315129fd6c8a871873dee50f9fb632c093a Mon Sep 17 00:00:00 2001 From: Ricardo Espinoza Date: Sat, 17 Jul 2021 18:32:08 -0400 Subject: [PATCH 05/15] :zap: Add _id to simplified version of document:get (#2000) --- .../nodes-base/nodes/Elasticsearch/Elasticsearch.node.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/nodes-base/nodes/Elasticsearch/Elasticsearch.node.ts b/packages/nodes-base/nodes/Elasticsearch/Elasticsearch.node.ts index e28ff8cb0b..6ef02e518d 100644 --- a/packages/nodes-base/nodes/Elasticsearch/Elasticsearch.node.ts +++ b/packages/nodes-base/nodes/Elasticsearch/Elasticsearch.node.ts @@ -133,7 +133,10 @@ export class Elasticsearch implements INodeType { const simple = this.getNodeParameter('simple', i) as IDataObject; if (simple) { - responseData = responseData._source; + responseData = { + _id: responseData._id, + ...responseData._source, + }; } } else if (operation === 'getAll') { From 5d15d85f08e823851ae11ba3f3645058fd9bb3bf Mon Sep 17 00:00:00 2001 From: Ricardo Espinoza Date: Sun, 18 Jul 2021 08:08:43 -0400 Subject: [PATCH 06/15] :bug: Fix issue filtering field date type on Notion-Node (#2001) --- packages/nodes-base/nodes/Notion/GenericFunctions.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/nodes-base/nodes/Notion/GenericFunctions.ts b/packages/nodes-base/nodes/Notion/GenericFunctions.ts index 01f03261dd..d36cc5b627 100644 --- a/packages/nodes-base/nodes/Notion/GenericFunctions.ts +++ b/packages/nodes-base/nodes/Notion/GenericFunctions.ts @@ -347,9 +347,10 @@ export function mapFilters(filters: IDataObject[], timezone: string) { key = 'text'; } else if (key === 'phone_number') { key = 'phone'; - } else if (key === 'date') { + } else if (key === 'date' && !['is_empty', 'is_not_empty'].includes(value.condition as string)) { valuePropertyName = (valuePropertyName !== undefined && !Object.keys(valuePropertyName).length) ? {} : moment.tz(value.date, timezone).utc().format(); } + return Object.assign(obj, { ['property']: getNameAndType(value.key).name, [key]: { [`${value.condition}`]: valuePropertyName }, From 5be8b6d5c23c2e339dda03467b5693e876bcead9 Mon Sep 17 00:00:00 2001 From: Jan Oberhauser Date: Sun, 18 Jul 2021 14:21:30 +0200 Subject: [PATCH 07/15] :zap: Add also "simple" option to Document->GetAll --- .../nodes/Elasticsearch/Elasticsearch.node.ts | 11 +++++++++++ .../descriptions/DocumentDescription.ts | 17 +++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/packages/nodes-base/nodes/Elasticsearch/Elasticsearch.node.ts b/packages/nodes-base/nodes/Elasticsearch/Elasticsearch.node.ts index 6ef02e518d..6e2876094c 100644 --- a/packages/nodes-base/nodes/Elasticsearch/Elasticsearch.node.ts +++ b/packages/nodes-base/nodes/Elasticsearch/Elasticsearch.node.ts @@ -169,6 +169,17 @@ export class Elasticsearch implements INodeType { responseData = await elasticsearchApiRequest.call(this, 'GET', `/${indexId}/_search`, body, qs); responseData = responseData.hits.hits; + const simple = this.getNodeParameter('simple', 0) as IDataObject; + + if (simple) { + responseData = responseData.map((item: IDataObject) => { + return { + _id: item._id, + ...(item._source as Object), + }; + }); + } + } else if (operation === 'create') { // ---------------------------------------- diff --git a/packages/nodes-base/nodes/Elasticsearch/descriptions/DocumentDescription.ts b/packages/nodes-base/nodes/Elasticsearch/descriptions/DocumentDescription.ts index dca8122caa..24c0519206 100644 --- a/packages/nodes-base/nodes/Elasticsearch/descriptions/DocumentDescription.ts +++ b/packages/nodes-base/nodes/Elasticsearch/descriptions/DocumentDescription.ts @@ -247,6 +247,23 @@ export const documentFields = [ }, }, }, + { + displayName: 'Simple', + name: 'simple', + type: 'boolean', + default: true, + description: 'Whether to return a simplified version of the response instead of the raw data', + displayOptions: { + show: { + resource: [ + 'document', + ], + operation: [ + 'getAll', + ], + }, + }, + }, { displayName: 'Options', name: 'options', From 76a2653c8bde648fc5a3d72150739af3e637d9a1 Mon Sep 17 00:00:00 2001 From: Jan Oberhauser Date: Sun, 18 Jul 2021 12:25:51 +0000 Subject: [PATCH 08/15] =?UTF-8?q?:bookmark:=20Release=C2=A0n8n-nodes-base@?= =?UTF-8?q?0.127.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/nodes-base/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/nodes-base/package.json b/packages/nodes-base/package.json index 56e66497ac..d54ae825e9 100644 --- a/packages/nodes-base/package.json +++ b/packages/nodes-base/package.json @@ -1,6 +1,6 @@ { "name": "n8n-nodes-base", - "version": "0.126.0", + "version": "0.127.0", "description": "Base nodes of n8n", "license": "SEE LICENSE IN LICENSE.md", "homepage": "https://n8n.io", From d14de339a9489158d480cf597f3535c8406270a6 Mon Sep 17 00:00:00 2001 From: Jan Oberhauser Date: Sun, 18 Jul 2021 12:26:52 +0000 Subject: [PATCH 09/15] =?UTF-8?q?:bookmark:=20Release=C2=A0n8n-editor-ui@0?= =?UTF-8?q?.99.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/editor-ui/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/editor-ui/package.json b/packages/editor-ui/package.json index 6d16570dea..4486c5c02d 100644 --- a/packages/editor-ui/package.json +++ b/packages/editor-ui/package.json @@ -1,6 +1,6 @@ { "name": "n8n-editor-ui", - "version": "0.98.0", + "version": "0.99.0", "description": "Workflow Editor UI for n8n", "license": "SEE LICENSE IN LICENSE.md", "homepage": "https://n8n.io", From 1c313941f230e577baa0f3b96d0e041ac5e70912 Mon Sep 17 00:00:00 2001 From: Jan Oberhauser Date: Sun, 18 Jul 2021 12:27:39 +0000 Subject: [PATCH 10/15] :arrow_up: Set n8n-editor-ui@0.99.0 and n8n-nodes-base@0.127.0 on n8n --- packages/cli/package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/cli/package.json b/packages/cli/package.json index 19c8102235..ebe376d166 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -109,8 +109,8 @@ "lodash.get": "^4.4.2", "mysql2": "~2.2.0", "n8n-core": "~0.77.0", - "n8n-editor-ui": "~0.98.0", - "n8n-nodes-base": "~0.126.0", + "n8n-editor-ui": "~0.99.0", + "n8n-nodes-base": "~0.127.0", "n8n-workflow": "~0.63.0", "oauth-1.0a": "^2.2.6", "open": "^7.0.0", From c7c42e185b231c31da58c452765b69c31034293f Mon Sep 17 00:00:00 2001 From: Jan Oberhauser Date: Sun, 18 Jul 2021 12:27:39 +0000 Subject: [PATCH 11/15] =?UTF-8?q?:bookmark:=20Release=C2=A0n8n@0.130.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/cli/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/cli/package.json b/packages/cli/package.json index ebe376d166..180a7a5345 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "n8n", - "version": "0.129.0", + "version": "0.130.0", "description": "n8n Workflow Automation Tool", "license": "SEE LICENSE IN LICENSE.md", "homepage": "https://n8n.io", From 6a9401aa519d9809ce69361dc791137f900f18d4 Mon Sep 17 00:00:00 2001 From: Jan Oberhauser Date: Sun, 18 Jul 2021 15:06:23 +0200 Subject: [PATCH 12/15] :shirt: Fix lint issue --- packages/nodes-base/nodes/Elasticsearch/Elasticsearch.node.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/nodes-base/nodes/Elasticsearch/Elasticsearch.node.ts b/packages/nodes-base/nodes/Elasticsearch/Elasticsearch.node.ts index 6e2876094c..967b90a842 100644 --- a/packages/nodes-base/nodes/Elasticsearch/Elasticsearch.node.ts +++ b/packages/nodes-base/nodes/Elasticsearch/Elasticsearch.node.ts @@ -175,7 +175,7 @@ export class Elasticsearch implements INodeType { responseData = responseData.map((item: IDataObject) => { return { _id: item._id, - ...(item._source as Object), + ...(item._source as {}), }; }); } From d6239d5bfbc1d701c7a3bebc2c59e1f23ef6aebb Mon Sep 17 00:00:00 2001 From: Omar Ajoue Date: Tue, 20 Jul 2021 08:58:54 +0200 Subject: [PATCH 13/15] :zap: Add full continue-on-fail support to all nodes (#1996) * Update Compression node * Update Crypto node * Update DateTime node * Update EditImage node * Update EmailSend node * Update ExecuteWorkflow node * Update FTP node * Update Function node * Update FunctionItem node * Update ExecuteCommand node * Update OpenWeatherMap node * Update ReadBinaryFile node * Update ReadPdf node * Update RssFeedRead node & add URL validation * Update SpreadsheetFile node * Update Switch node * Update WriteBinaryFile node * Update Xml node * Update ActiveCampaign node * Update Airtable node * Update ApiTemplateIo node * Update Asana node * Update AwsLambda node * Update AwsSns node * Update AwsComprehend node * Update AwsRekognition node * Update AwsS3 node * Fix Error item * Update AwsSes node * Update AwsSqs node * Update Amqp node * Update Bitly node * Update Box node * Update Brandfetch node * Update CircleCi node * Update Clearbit node * Update ClickUp node * Update Cockpit node * Update CoinGecko node * Update Contentful node * Update ConvertKit node * Update Cortex node * Update CustomerIo node * Update DeepL node * Update Demio node * Update Disqus node * Update Drift node * Update Dropbox node * Update GetResponse node * Refactor & Update Ghost node * Update Github node * Update Gitlab node * Update GoogleAnalytics node * Update GoogleBooks node * Update GoogleCalendar node * Update GoogleDrive node * Update Gmail node * Update GoogleSheets node * Update GoogleSlides node * Update GoogleTasks node * Update Gotify node * Update GraphQL node * Update HackerNews node * Update Harvest node * Update HtmlExtract node * Update Hubspot node * Update Hunter node * Update Intercom node * Update Kafka node * Refactor & update Line node * Update LinkedIn node * Update Mailchimp node * Update Mandrill node * Update Matrix node * Update Mautic node * Update Medium node * Update MessageBird node * Update Mindee node * Update Mocean node * Update MondayCom node * Update MicrosoftExcel node * Update MicrosoftOneDrive node * Update MicrosoftOutlook node * Update Affinity node * Update Chargebee node * Update Discourse node * Update Freshdesk node * Update YouTube node * Update InvoiceNinja node * Update MailerLite node * Update Mailgun node * Update Mailjet node * Update Mattermost node * Update Nasa node * Update NextCloud node * Update OpenThesaurus node * Update Orbit node * Update PagerDuty node * Update PayPal node * Update Peekalink node * Update Phantombuster node * Update PostHog node * Update ProfitWell node * Refactor & Update Pushbullet node * Update QuickBooks node * Update Raindrop node * Update Reddit node * Update Rocketchat node * Update S3 node * Update Salesforce node * Update SendGrid node * Update SentryIo node * Update Shopify node * Update Signl4 node * Update Slack node * Update Spontit node * Update Spotify node * Update Storyblok node * Refactor & Update Strapi node * Refactor & Update Strava node * Update Taiga node * Refactor & update Tapfiliate node * Update Telegram node * Update TheHive node * Update Todoist node * Update TravisCi node * Update Trello node * Update Twilio node * Update Twist node * Update Twitter node * Update Uplead node * Update UProc node * Update Vero node * Update Webflow node * Update Wekan node * Update Wordpress node * Update Xero node * Update Yourls node * Update Zendesk node * Update ZohoCrm node * Refactor & Update Zoom node * Update Zulip node * Update Clockify node * Update MongoDb node * Update MySql node * Update MicrosoftTeams node * Update Stackby node * Refactor Discourse node * Support corner-case in Github node update * Support corner-case in Gitlab node update * Refactor & Update GoogleContacts node * Refactor Mindee node * Update Coda node * Lint fixes * Update Beeminder node * Update Google Firebase RealtimeDatabase node * Update HelpScout node * Update Mailcheck node * Update Paddle node * Update Pipedrive node * Update Pushover node * Update Segment node * Refactor & Update Vonage node * Added new conditions to warnings on execute batch cmd * Added keep only properties flag * Fixed code for keep only props * Added dependencies for image editing Co-authored-by: dali --- .github/workflows/test-workflows.yml | 8 + packages/cli/commands/Interfaces.d.ts | 1 + packages/cli/commands/executeBatch.ts | 13 + .../ActiveCampaign/ActiveCampaign.node.ts | 1619 ++++----- .../nodes/Affinity/Affinity.node.ts | 354 +- .../nodes/Airtable/Airtable.node.ts | 276 +- packages/nodes-base/nodes/Amqp/Amqp.node.ts | 136 +- .../nodes/ApiTemplateIo/ApiTemplateIo.node.ts | 183 +- packages/nodes-base/nodes/Asana/Asana.node.ts | 688 ++-- .../nodes-base/nodes/Aws/AwsLambda.node.ts | 63 +- packages/nodes-base/nodes/Aws/AwsSns.node.ts | 22 +- .../Aws/Comprehend/AwsComprehend.node.ts | 108 +- .../Aws/Rekognition/AwsRekognition.node.ts | 202 +- .../nodes-base/nodes/Aws/S3/AwsS3.node.ts | 978 ++--- .../nodes-base/nodes/Aws/SES/AwsSes.node.ts | 627 ++-- .../nodes-base/nodes/Aws/SQS/AwsSqs.node.ts | 160 +- .../nodes/Beeminder/Beeminder.node.ts | 98 +- packages/nodes-base/nodes/Bitly/Bitly.node.ts | 148 +- packages/nodes-base/nodes/Box/Box.node.ts | 764 ++-- .../nodes/Brandfetch/Brandfetch.node.ts | 148 +- .../nodes/Chargebee/Chargebee.node.ts | 269 +- .../nodes/CircleCi/CircleCi.node.ts | 122 +- .../nodes/Clearbit/Clearbit.node.ts | 124 +- .../nodes-base/nodes/ClickUp/ClickUp.node.ts | 1856 +++++----- .../nodes/Clockify/Clockify.node.ts | 524 +-- .../nodes-base/nodes/Cockpit/Cockpit.node.ts | 72 +- packages/nodes-base/nodes/Coda/Coda.node.ts | 494 ++- .../nodes/CoinGecko/CoinGecko.node.ts | 615 ++-- packages/nodes-base/nodes/Compression.node.ts | 199 +- .../nodes/Contentful/Contentful.node.ts | 376 +- .../nodes/ConvertKit/ConvertKit.node.ts | 528 +-- .../nodes-base/nodes/Cortex/Cortex.node.ts | 416 +-- packages/nodes-base/nodes/Crypto.node.ts | 97 +- .../nodes/CustomerIo/CustomerIo.node.ts | 386 +- packages/nodes-base/nodes/DateTime.node.ts | 194 +- packages/nodes-base/nodes/DeepL/DeepL.node.ts | 37 +- packages/nodes-base/nodes/Demio/Demio.node.ts | 120 +- .../nodes/Discourse/Discourse.node.ts | 594 ++-- .../nodes-base/nodes/Disqus/Disqus.node.ts | 212 +- packages/nodes-base/nodes/Drift/Drift.node.ts | 104 +- .../nodes-base/nodes/Dropbox/Dropbox.node.ts | 474 +-- packages/nodes-base/nodes/EditImage.node.ts | 526 +-- packages/nodes-base/nodes/EmailSend.node.ts | 147 +- .../nodes-base/nodes/ExecuteCommand.node.ts | 47 +- .../nodes-base/nodes/ExecuteWorkflow.node.ts | 87 +- .../nodes/Freshdesk/Freshdesk.node.ts | 536 +-- packages/nodes-base/nodes/Ftp.node.ts | 474 +-- packages/nodes-base/nodes/Function.node.ts | 45 +- .../nodes-base/nodes/FunctionItem.node.ts | 154 +- .../nodes/GetResponse/GetResponse.node.ts | 225 +- packages/nodes-base/nodes/Ghost/Ghost.node.ts | 354 +- .../nodes-base/nodes/Github/Github.node.ts | 813 ++--- .../nodes-base/nodes/Gitlab/Gitlab.node.ts | 369 +- .../Google/Analytics/GoogleAnalytics.node.ts | 216 +- .../nodes/Google/Books/GoogleBooks.node.ts | 214 +- .../Google/Calendar/GoogleCalendar.node.ts | 12 +- .../Google/Contacts/GoogleContacts.node.ts | 706 ++-- .../nodes/Google/Drive/GoogleDrive.node.ts | 786 +++-- .../RealtimeDatabase/RealtimeDatabase.node.ts | 89 +- .../nodes/Google/Gmail/Gmail.node.ts | 1069 +++--- .../nodes/Google/Sheet/GoogleSheets.node.ts | 400 ++- .../nodes/Google/Slides/GoogleSlides.node.ts | 236 +- .../nodes/Google/Task/GoogleTasks.node.ts | 322 +- .../nodes/Google/YouTube/YouTube.node.ts | 1740 ++++----- .../nodes-base/nodes/Gotify/Gotify.node.ts | 108 +- .../nodes-base/nodes/GraphQL/GraphQL.node.ts | 150 +- .../nodes/HackerNews/HackerNews.node.ts | 112 +- .../nodes-base/nodes/Harvest/Harvest.node.ts | 1302 +++---- .../nodes/HelpScout/HelpScout.node.ts | 508 +-- .../nodes/HtmlExtract/HtmlExtract.node.ts | 106 +- .../nodes-base/nodes/Hubspot/Hubspot.node.ts | 2920 +++++++-------- .../nodes-base/nodes/Hunter/Hunter.node.ts | 144 +- .../nodes/Intercom/Intercom.node.ts | 798 ++--- .../nodes/InvoiceNinja/InvoiceNinja.node.ts | 1084 +++--- packages/nodes-base/nodes/Kafka/Kafka.node.ts | 184 +- packages/nodes-base/nodes/Line/Line.node.ts | 108 +- .../nodes/LinkedIn/LinkedIn.node.ts | 316 +- .../nodes/Mailcheck/Mailcheck.node.ts | 18 +- .../nodes/Mailchimp/Mailchimp.node.ts | 718 ++-- .../nodes/MailerLite/MailerLite.node.ts | 131 +- .../nodes-base/nodes/Mailgun/Mailgun.node.ts | 144 +- .../nodes-base/nodes/Mailjet/Mailjet.node.ts | 322 +- .../nodes/Mandrill/Mandrill.node.ts | 252 +- .../nodes-base/nodes/Matrix/Matrix.node.ts | 18 +- .../nodes/Mattermost/Mattermost.node.ts | 736 ++-- .../nodes-base/nodes/Mautic/Mautic.node.ts | 707 ++-- .../nodes-base/nodes/Medium/Medium.node.ts | 205 +- .../nodes/MessageBird/MessageBird.node.ts | 155 +- .../Microsoft/Excel/MicrosoftExcel.node.ts | 438 ++- .../OneDrive/MicrosoftOneDrive.node.ts | 338 +- .../Outlook/MicrosoftOutlook.node.ts | 1341 ++++--- .../Microsoft/Teams/MicrosoftTeams.node.ts | 336 +- .../nodes-base/nodes/Mindee/Mindee.node.ts | 133 +- .../nodes-base/nodes/Mocean/Mocean.node.ts | 77 +- .../nodes/MondayCom/MondayCom.node.ts | 894 ++--- .../nodes-base/nodes/MongoDb/MongoDb.node.ts | 147 +- packages/nodes-base/nodes/MySql/MySql.node.ts | 123 +- packages/nodes-base/nodes/Nasa/Nasa.node.ts | 502 +-- .../nodes/NextCloud/NextCloud.node.ts | 602 ++-- .../nodes/OpenThesaurus/OpenThesaurus.node.ts | 32 +- .../nodes-base/nodes/OpenWeatherMap.node.ts | 121 +- packages/nodes-base/nodes/Orbit/Orbit.node.ts | 581 +-- .../nodes-base/nodes/Paddle/Paddle.node.ts | 581 +-- .../nodes/PagerDuty/PagerDuty.node.ts | 360 +- .../nodes-base/nodes/PayPal/PayPal.node.ts | 138 +- .../nodes/Peekalink/Peekalink.node.ts | 44 +- .../nodes/Phantombuster/Phantombuster.node.ts | 266 +- .../nodes/Pipedrive/Pipedrive.node.ts | 1083 +++--- .../nodes-base/nodes/PostHog/PostHog.node.ts | 192 +- .../nodes/ProfitWell/ProfitWell.node.ts | 82 +- .../nodes/Pushbullet/Pushbullet.node.ts | 252 +- .../nodes/Pushover/Pushover.node.ts | 113 +- .../nodes/QuickBooks/QuickBooks.node.ts | 1447 ++++---- .../nodes/Raindrop/Raindrop.node.ts | 592 ++-- .../nodes-base/nodes/ReadBinaryFile.node.ts | 57 +- packages/nodes-base/nodes/ReadPdf.node.ts | 31 +- .../nodes-base/nodes/Reddit/Reddit.node.ts | 633 ++-- .../nodes/Rocketchat/Rocketchat.node.ts | 174 +- packages/nodes-base/nodes/RssFeedRead.node.ts | 78 +- packages/nodes-base/nodes/S3/S3.node.ts | 984 +++--- .../nodes/Salesforce/Salesforce.node.ts | 3097 ++++++++-------- .../nodes-base/nodes/Segment/Segment.node.ts | 966 ++--- .../nodes/SendGrid/SendGrid.node.ts | 531 +-- .../nodes/SentryIo/SentryIo.node.ts | 768 ++-- .../nodes-base/nodes/Shopify/Shopify.node.ts | 462 +-- .../nodes-base/nodes/Signl4/Signl4.node.ts | 206 +- packages/nodes-base/nodes/Slack/Slack.node.ts | 1436 ++++---- .../nodes-base/nodes/Spontit/Spontit.node.ts | 78 +- .../nodes-base/nodes/Spotify/Spotify.node.ts | 906 ++--- .../nodes-base/nodes/SpreadsheetFile.node.ts | 257 +- .../nodes-base/nodes/Stackby/Stackby.node.ts | 150 +- .../nodes/Storyblok/Storyblok.node.ts | 260 +- .../nodes-base/nodes/Strapi/Strapi.node.ts | 171 +- .../nodes-base/nodes/Strava/Strava.node.ts | 158 +- packages/nodes-base/nodes/Switch.node.ts | 88 +- packages/nodes-base/nodes/Taiga/Taiga.node.ts | 2 +- .../nodes/Tapfiliate/Tapfiliate.node.ts | 306 +- .../nodes/Telegram/Telegram.node.ts | 592 ++-- .../nodes-base/nodes/TheHive/TheHive.node.ts | 3136 +++++++++-------- .../nodes-base/nodes/Todoist/Todoist.node.ts | 180 +- .../nodes/TravisCi/TravisCi.node.ts | 132 +- .../nodes-base/nodes/Trello/Trello.node.ts | 1108 +++--- .../nodes-base/nodes/Twilio/Twilio.node.ts | 62 +- packages/nodes-base/nodes/Twist/Twist.node.ts | 1034 +++--- .../nodes-base/nodes/Twitter/Twitter.node.ts | 296 +- packages/nodes-base/nodes/UProc/UProc.node.ts | 54 +- .../nodes-base/nodes/Uplead/Uplead.node.ts | 76 +- packages/nodes-base/nodes/Vero/Vero.node.ts | 282 +- .../nodes-base/nodes/Vonage/Vonage.node.ts | 141 +- .../nodes-base/nodes/Webflow/Webflow.node.ts | 176 +- packages/nodes-base/nodes/Wekan/Wekan.node.ts | 792 ++--- .../nodes/Wordpress/Wordpress.node.ts | 526 +-- .../nodes-base/nodes/WriteBinaryFile.node.ts | 70 +- packages/nodes-base/nodes/Xero/Xero.node.ts | 816 ++--- packages/nodes-base/nodes/Xml.node.ts | 55 +- .../nodes-base/nodes/Yourls/Yourls.node.ts | 60 +- .../nodes-base/nodes/Zendesk/Zendesk.node.ts | 494 +-- packages/nodes-base/nodes/Zoom/Zoom.node.ts | 1194 +++---- packages/nodes-base/nodes/Zulip/Zulip.node.ts | 530 +-- 159 files changed, 35795 insertions(+), 33847 deletions(-) diff --git a/.github/workflows/test-workflows.yml b/.github/workflows/test-workflows.yml index 8250a5a9b4..8eee038b15 100644 --- a/.github/workflows/test-workflows.yml +++ b/.github/workflows/test-workflows.yml @@ -31,6 +31,14 @@ jobs: uses: actions/setup-node@v1 with: node-version: ${{ matrix.node-version }} + - + name: Install dependencies + run: | + apt update -y + echo 'tzdata tzdata/Areas select Europe' | debconf-set-selections + echo 'tzdata tzdata/Zones/Europe select Paris' | debconf-set-selections + DEBIAN_FRONTEND="noninteractive" apt-get install -y graphicsmagick + shell: bash - name: npm install and build run: | diff --git a/packages/cli/commands/Interfaces.d.ts b/packages/cli/commands/Interfaces.d.ts index aedd194539..adc41c6225 100644 --- a/packages/cli/commands/Interfaces.d.ts +++ b/packages/cli/commands/Interfaces.d.ts @@ -42,6 +42,7 @@ interface INodeSpecialCases { interface INodeSpecialCase { ignoredProperties?: string[]; capResults?: number; + keepOnlyProperties?: string[]; } type ExecutionStatus = 'success' | 'error' | 'warning' | 'running'; diff --git a/packages/cli/commands/executeBatch.ts b/packages/cli/commands/executeBatch.ts index 7bc6bb858d..dc5f4030db 100644 --- a/packages/cli/commands/executeBatch.ts +++ b/packages/cli/commands/executeBatch.ts @@ -45,6 +45,10 @@ import { LoggerProxy, } from 'n8n-workflow'; +import { + pick, +} from 'lodash'; + export class ExecuteBatch extends Command { static description = '\nExecutes multiple workflows once'; @@ -166,6 +170,8 @@ export class ExecuteBatch extends Command { '429', 'econnrefused', 'missing a required parameter', + 'insufficient credit balance', + 'request timed out', ]; errorMessage = errorMessage.toLowerCase(); @@ -600,6 +606,8 @@ export class ExecuteBatch extends Command { nodeEdgeCases[node.name].capResults = parseInt(parts[1], 10); } else if (parts[0] === 'IGNORED_PROPERTIES') { nodeEdgeCases[node.name].ignoredProperties = parts[1].split(',').map(property => property.trim()); + } else if (parts[0] === 'KEEP_ONLY_PROPERTIES') { + nodeEdgeCases[node.name].keepOnlyProperties = parts[1].split(',').map(property => property.trim()); } } }); @@ -701,6 +709,11 @@ export class ExecuteBatch extends Command { nodeEdgeCases[nodeName].ignoredProperties!.forEach(ignoredProperty => delete executionData.json[ignoredProperty]); } + let keepOnlyFields = [] as string[]; + if (nodeEdgeCases[nodeName] !== undefined && nodeEdgeCases[nodeName].keepOnlyProperties !== undefined) { + keepOnlyFields = nodeEdgeCases[nodeName].keepOnlyProperties!; + } + executionData.json = keepOnlyFields.length > 0 ? pick(executionData.json, keepOnlyFields) : executionData.json; const jsonProperties = executionData.json; const nodeOutputAttributes = Object.keys(jsonProperties); diff --git a/packages/nodes-base/nodes/ActiveCampaign/ActiveCampaign.node.ts b/packages/nodes-base/nodes/ActiveCampaign/ActiveCampaign.node.ts index 6727c80540..45873f5018 100644 --- a/packages/nodes-base/nodes/ActiveCampaign/ActiveCampaign.node.ts +++ b/packages/nodes-base/nodes/ActiveCampaign/ActiveCampaign.node.ts @@ -333,856 +333,865 @@ export class ActiveCampaign implements INodeType { let dataKey: string | undefined; for (let i = 0; i < items.length; i++) { - dataKey = undefined; - resource = this.getNodeParameter('resource', 0) as string; - operation = this.getNodeParameter('operation', 0) as string; + try { - requestMethod = 'GET'; - endpoint = ''; - body = {} as IDataObject; - qs = {} as IDataObject; + dataKey = undefined; + resource = this.getNodeParameter('resource', 0) as string; + operation = this.getNodeParameter('operation', 0) as string; - if (resource === 'contact') { - if (operation === 'create') { - // ---------------------------------- - // contact:create - // ---------------------------------- + requestMethod = 'GET'; + endpoint = ''; + body = {} as IDataObject; + qs = {} as IDataObject; - requestMethod = 'POST'; + if (resource === 'contact') { + if (operation === 'create') { + // ---------------------------------- + // contact:create + // ---------------------------------- + + requestMethod = 'POST'; + + const updateIfExists = this.getNodeParameter('updateIfExists', i) as boolean; + if (updateIfExists === true) { + endpoint = '/api/3/contact/sync'; + } else { + endpoint = '/api/3/contacts'; + } + + dataKey = 'contact'; + + body.contact = { + email: this.getNodeParameter('email', i) as string, + } as IDataObject; + + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + addAdditionalFields(body.contact as IDataObject, additionalFields); + + } else if (operation === 'delete') { + // ---------------------------------- + // contact:delete + // ---------------------------------- + + requestMethod = 'DELETE'; + + const contactId = this.getNodeParameter('contactId', i) as number; + endpoint = `/api/3/contacts/${contactId}`; + + } else if (operation === 'get') { + // ---------------------------------- + // contact:get + // ---------------------------------- + + requestMethod = 'GET'; + + const contactId = this.getNodeParameter('contactId', i) as number; + endpoint = `/api/3/contacts/${contactId}`; + + } else if (operation === 'getAll') { + // ---------------------------------- + // contacts:getAll + // ---------------------------------- + + requestMethod = 'GET'; + + returnAll = this.getNodeParameter('returnAll', i) as boolean; + const simple = this.getNodeParameter('simple', i, true) as boolean; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + + if (returnAll === false) { + qs.limit = this.getNodeParameter('limit', i) as number; + } + + Object.assign(qs, additionalFields); + + if (qs.orderBy) { + qs[qs.orderBy as string] = true; + delete qs.orderBy; + } + + if (simple === true) { + dataKey = 'contacts'; + } + + endpoint = `/api/3/contacts`; + + } else if (operation === 'update') { + // ---------------------------------- + // contact:update + // ---------------------------------- + + requestMethod = 'PUT'; + + const contactId = this.getNodeParameter('contactId', i) as number; + endpoint = `/api/3/contacts/${contactId}`; + + dataKey = 'contact'; + + body.contact = {} as IDataObject; + + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + addAdditionalFields(body.contact as IDataObject, updateFields); - const updateIfExists = this.getNodeParameter('updateIfExists', i) as boolean; - if (updateIfExists === true) { - endpoint = '/api/3/contact/sync'; } else { - endpoint = '/api/3/contacts'; + throw new NodeOperationError(this.getNode(), `The operation "${operation}" is not known`); } + } else if (resource === 'account') { + if (operation === 'create') { + // ---------------------------------- + // account:create + // ---------------------------------- - dataKey = 'contact'; + requestMethod = 'POST'; - body.contact = { - email: this.getNodeParameter('email', i) as string, - } as IDataObject; + endpoint = '/api/3/accounts'; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - addAdditionalFields(body.contact as IDataObject, additionalFields); + dataKey = 'account'; - } else if (operation === 'delete') { - // ---------------------------------- - // contact:delete - // ---------------------------------- + body.account = { + name: this.getNodeParameter('name', i) as string, + } as IDataObject; - requestMethod = 'DELETE'; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + addAdditionalFields(body.account as IDataObject, additionalFields); - const contactId = this.getNodeParameter('contactId', i) as number; - endpoint = `/api/3/contacts/${contactId}`; + } else if (operation === 'delete') { + // ---------------------------------- + // account:delete + // ---------------------------------- - } else if (operation === 'get') { - // ---------------------------------- - // contact:get - // ---------------------------------- + requestMethod = 'DELETE'; - requestMethod = 'GET'; + const accountId = this.getNodeParameter('accountId', i) as number; + endpoint = `/api/3/accounts/${accountId}`; - const contactId = this.getNodeParameter('contactId', i) as number; - endpoint = `/api/3/contacts/${contactId}`; + } else if (operation === 'get') { + // ---------------------------------- + // account:get + // ---------------------------------- - } else if (operation === 'getAll') { - // ---------------------------------- - // contacts:getAll - // ---------------------------------- + requestMethod = 'GET'; - requestMethod = 'GET'; + const accountId = this.getNodeParameter('accountId', i) as number; + endpoint = `/api/3/accounts/${accountId}`; - returnAll = this.getNodeParameter('returnAll', i) as boolean; - const simple = this.getNodeParameter('simple', i, true) as boolean; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + } else if (operation === 'getAll') { + // ---------------------------------- + // account:getAll + // ---------------------------------- - if (returnAll === false) { - qs.limit = this.getNodeParameter('limit', i) as number; + requestMethod = 'GET'; + + const simple = this.getNodeParameter('simple', i, true) as boolean; + returnAll = this.getNodeParameter('returnAll', i) as boolean; + if (returnAll === false) { + qs.limit = this.getNodeParameter('limit', i) as number; + } + + if (simple === true) { + dataKey = 'accounts'; + } + + endpoint = `/api/3/accounts`; + + const filters = this.getNodeParameter('filters', i) as IDataObject; + Object.assign(qs, filters); + + } else if (operation === 'update') { + // ---------------------------------- + // account:update + // ---------------------------------- + + requestMethod = 'PUT'; + + const accountId = this.getNodeParameter('accountId', i) as number; + endpoint = `/api/3/accounts/${accountId}`; + + dataKey = 'account'; + + body.account = {} as IDataObject; + + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + addAdditionalFields(body.account as IDataObject, updateFields); + + } else { + throw new NodeOperationError(this.getNode(), `The operation "${operation}" is not known`); } + } else if (resource === 'accountContact') { + if (operation === 'create') { + // ---------------------------------- + // account:create + // ---------------------------------- - Object.assign(qs, additionalFields); + requestMethod = 'POST'; - if (qs.orderBy) { - qs[qs.orderBy as string] = true; - delete qs.orderBy; + endpoint = '/api/3/accountContacts'; + + dataKey = 'accountContact'; + + body.accountContact = { + contact: this.getNodeParameter('contact', i) as string, + account: this.getNodeParameter('account', i) as string, + } as IDataObject; + + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + addAdditionalFields(body.account as IDataObject, additionalFields); + + } else if (operation === 'update') { + // ---------------------------------- + // accountContact:update + // ---------------------------------- + + requestMethod = 'PUT'; + + const accountContactId = this.getNodeParameter('accountContactId', i) as number; + endpoint = `/api/3/accountContacts/${accountContactId}`; + + dataKey = 'accountContact'; + + body.accountContact = {} as IDataObject; + + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + addAdditionalFields(body.accountContact as IDataObject, updateFields); + + } else if (operation === 'delete') { + // ---------------------------------- + // accountContact:delete + // ---------------------------------- + + requestMethod = 'DELETE'; + + const accountContactId = this.getNodeParameter('accountContactId', i) as number; + endpoint = `/api/3/accountContacts/${accountContactId}`; + + } else { + throw new NodeOperationError(this.getNode(), `The operation "${operation}" is not known`); } + } else if (resource === 'contactTag') { + if (operation === 'add') { + // ---------------------------------- + // contactTag:add + // ---------------------------------- + + requestMethod = 'POST'; + + endpoint = '/api/3/contactTags'; + + dataKey = 'contactTag'; + + body.contactTag = { + contact: this.getNodeParameter('contactId', i) as string, + tag: this.getNodeParameter('tagId', i) as string, + } as IDataObject; + + } else if (operation === 'remove') { + // ---------------------------------- + // contactTag:remove + // ---------------------------------- + + requestMethod = 'DELETE'; + + const contactTagId = this.getNodeParameter('contactTagId', i) as number; + endpoint = `/api/3/contactTags/${contactTagId}`; + + } else { + throw new NodeOperationError(this.getNode(), `The operation "${operation}" is not known`); + } + } else if (resource === 'contactList') { + if (operation === 'add') { + // ---------------------------------- + // contactList:add + // ---------------------------------- + + requestMethod = 'POST'; + + endpoint = '/api/3/contactLists'; + + dataKey = 'contactTag'; + + body.contactList = { + list: this.getNodeParameter('listId', i) as string, + contact: this.getNodeParameter('contactId', i) as string, + status: 1, + } as IDataObject; + + } else if (operation === 'remove') { + // ---------------------------------- + // contactList:remove + // ---------------------------------- + + requestMethod = 'POST'; + + endpoint = '/api/3/contactLists'; + + body.contactList = { + list: this.getNodeParameter('listId', i) as string, + contact: this.getNodeParameter('contactId', i) as string, + status: 2, + } as IDataObject; - if (simple === true) { dataKey = 'contacts'; + + } else { + throw new NodeOperationError(this.getNode(), `The operation "${operation}" is not known`); } + } else if (resource === 'list') { + if (operation === 'getAll') { + // ---------------------------------- + // list:getAll + // ---------------------------------- - endpoint = `/api/3/contacts`; + requestMethod = 'GET'; - } else if (operation === 'update') { - // ---------------------------------- - // contact:update - // ---------------------------------- + returnAll = this.getNodeParameter('returnAll', i) as boolean; + const simple = this.getNodeParameter('simple', i, true) as boolean; - requestMethod = 'PUT'; - const contactId = this.getNodeParameter('contactId', i) as number; - endpoint = `/api/3/contacts/${contactId}`; - - dataKey = 'contact'; - - body.contact = {} as IDataObject; - - const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; - addAdditionalFields(body.contact as IDataObject, updateFields); - - } else { - throw new NodeOperationError(this.getNode(), `The operation "${operation}" is not known`); - } - } else if (resource === 'account') { - if (operation === 'create') { - // ---------------------------------- - // account:create - // ---------------------------------- - - requestMethod = 'POST'; - - endpoint = '/api/3/accounts'; - - dataKey = 'account'; - - body.account = { - name: this.getNodeParameter('name', i) as string, - } as IDataObject; - - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - addAdditionalFields(body.account as IDataObject, additionalFields); - - } else if (operation === 'delete') { - // ---------------------------------- - // account:delete - // ---------------------------------- - - requestMethod = 'DELETE'; - - const accountId = this.getNodeParameter('accountId', i) as number; - endpoint = `/api/3/accounts/${accountId}`; - - } else if (operation === 'get') { - // ---------------------------------- - // account:get - // ---------------------------------- - - requestMethod = 'GET'; - - const accountId = this.getNodeParameter('accountId', i) as number; - endpoint = `/api/3/accounts/${accountId}`; - - } else if (operation === 'getAll') { - // ---------------------------------- - // account:getAll - // ---------------------------------- - - requestMethod = 'GET'; - - const simple = this.getNodeParameter('simple', i, true) as boolean; - returnAll = this.getNodeParameter('returnAll', i) as boolean; - if (returnAll === false) { - qs.limit = this.getNodeParameter('limit', i) as number; - } - - if (simple === true) { - dataKey = 'accounts'; - } - - endpoint = `/api/3/accounts`; - - const filters = this.getNodeParameter('filters', i) as IDataObject; - Object.assign(qs, filters); - - } else if (operation === 'update') { - // ---------------------------------- - // account:update - // ---------------------------------- - - requestMethod = 'PUT'; - - const accountId = this.getNodeParameter('accountId', i) as number; - endpoint = `/api/3/accounts/${accountId}`; - - dataKey = 'account'; - - body.account = {} as IDataObject; - - const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; - addAdditionalFields(body.account as IDataObject, updateFields); - - } else { - throw new NodeOperationError(this.getNode(), `The operation "${operation}" is not known`); - } - } else if (resource === 'accountContact') { - if (operation === 'create') { - // ---------------------------------- - // account:create - // ---------------------------------- - - requestMethod = 'POST'; - - endpoint = '/api/3/accountContacts'; - - dataKey = 'accountContact'; - - body.accountContact = { - contact: this.getNodeParameter('contact', i) as string, - account: this.getNodeParameter('account', i) as string, - } as IDataObject; - - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - addAdditionalFields(body.account as IDataObject, additionalFields); - - } else if (operation === 'update') { - // ---------------------------------- - // accountContact:update - // ---------------------------------- - - requestMethod = 'PUT'; - - const accountContactId = this.getNodeParameter('accountContactId', i) as number; - endpoint = `/api/3/accountContacts/${accountContactId}`; - - dataKey = 'accountContact'; - - body.accountContact = {} as IDataObject; - - const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; - addAdditionalFields(body.accountContact as IDataObject, updateFields); - - } else if (operation === 'delete') { - // ---------------------------------- - // accountContact:delete - // ---------------------------------- - - requestMethod = 'DELETE'; - - const accountContactId = this.getNodeParameter('accountContactId', i) as number; - endpoint = `/api/3/accountContacts/${accountContactId}`; - - } else { - throw new NodeOperationError(this.getNode(), `The operation "${operation}" is not known`); - } - } else if (resource === 'contactTag') { - if (operation === 'add') { - // ---------------------------------- - // contactTag:add - // ---------------------------------- - - requestMethod = 'POST'; - - endpoint = '/api/3/contactTags'; - - dataKey = 'contactTag'; - - body.contactTag = { - contact: this.getNodeParameter('contactId', i) as string, - tag: this.getNodeParameter('tagId', i) as string, - } as IDataObject; - - } else if (operation === 'remove') { - // ---------------------------------- - // contactTag:remove - // ---------------------------------- - - requestMethod = 'DELETE'; - - const contactTagId = this.getNodeParameter('contactTagId', i) as number; - endpoint = `/api/3/contactTags/${contactTagId}`; - - } else { - throw new NodeOperationError(this.getNode(), `The operation "${operation}" is not known`); - } - } else if (resource === 'contactList') { - if (operation === 'add') { - // ---------------------------------- - // contactList:add - // ---------------------------------- - - requestMethod = 'POST'; - - endpoint = '/api/3/contactLists'; - - dataKey = 'contactTag'; - - body.contactList = { - list: this.getNodeParameter('listId', i) as string, - contact: this.getNodeParameter('contactId', i) as string, - status: 1, - } as IDataObject; - - } else if (operation === 'remove') { - // ---------------------------------- - // contactList:remove - // ---------------------------------- - - requestMethod = 'POST'; - - endpoint = '/api/3/contactLists'; - - body.contactList = { - list: this.getNodeParameter('listId', i) as string, - contact: this.getNodeParameter('contactId', i) as string, - status: 2, - } as IDataObject; - - dataKey = 'contacts'; - - } else { - throw new NodeOperationError(this.getNode(), `The operation "${operation}" is not known`); - } - } else if (resource === 'list') { - if (operation === 'getAll') { - // ---------------------------------- - // list:getAll - // ---------------------------------- - - requestMethod = 'GET'; - - returnAll = this.getNodeParameter('returnAll', i) as boolean; - const simple = this.getNodeParameter('simple', i, true) as boolean; - - - if (returnAll === false) { - qs.limit = this.getNodeParameter('limit', i) as number; - } - - if (simple === true) { - dataKey = 'lists'; - } - - endpoint = `/api/3/lists`; - } - - } else if (resource === 'tag') { - if (operation === 'create') { - // ---------------------------------- - // tag:create - // ---------------------------------- - - requestMethod = 'POST'; - - endpoint = '/api/3/tags'; - - dataKey = 'tag'; - - body.tag = { - tag: this.getNodeParameter('name', i) as string, - tagType: this.getNodeParameter('tagType', i) as string, - } as IDataObject; - - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - addAdditionalFields(body.tag as IDataObject, additionalFields); - - } else if (operation === 'delete') { - // ---------------------------------- - // tag:delete - // ---------------------------------- - - requestMethod = 'DELETE'; - - const tagId = this.getNodeParameter('tagId', i) as number; - endpoint = `/api/3/tags/${tagId}`; - - } else if (operation === 'get') { - // ---------------------------------- - // tag:get - // ---------------------------------- - - requestMethod = 'GET'; - - const tagId = this.getNodeParameter('tagId', i) as number; - endpoint = `/api/3/tags/${tagId}`; - - } else if (operation === 'getAll') { - // ---------------------------------- - // tags:getAll - // ---------------------------------- - - requestMethod = 'GET'; - - const simple = this.getNodeParameter('simple', i, true) as boolean; - returnAll = this.getNodeParameter('returnAll', i) as boolean; - if (returnAll === false) { - qs.limit = this.getNodeParameter('limit', i) as number; - } - - if (simple === true) { - dataKey = 'tags'; - } - - endpoint = `/api/3/tags`; - - } else if (operation === 'update') { - // ---------------------------------- - // tags:update - // ---------------------------------- - - requestMethod = 'PUT'; - - const tagId = this.getNodeParameter('tagId', i) as number; - endpoint = `/api/3/tags/${tagId}`; - - dataKey = 'tag'; - - body.tag = {} as IDataObject; - - const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; - addAdditionalFields(body.tag as IDataObject, updateFields); - - } else { - throw new NodeOperationError(this.getNode(), `The operation "${operation}" is not known`); - } - } else if (resource === 'deal') { - if (operation === 'create') { - // ---------------------------------- - // deal:create - // ---------------------------------- - - requestMethod = 'POST'; - - endpoint = '/api/3/deals'; - - body.deal = { - title: this.getNodeParameter('title', i) as string, - contact: this.getNodeParameter('contact', i) as string, - value: this.getNodeParameter('value', i) as number, - currency: this.getNodeParameter('currency', i) as string, - } as IDataObject; - - const group = this.getNodeParameter('group', i) as string; - if (group !== '') { - addAdditionalFields(body.deal as IDataObject, { group }); - } - - const owner = this.getNodeParameter('owner', i) as string; - if (owner !== '') { - addAdditionalFields(body.deal as IDataObject, { owner }); - } - - const stage = this.getNodeParameter('stage', i) as string; - if (stage !== '') { - addAdditionalFields(body.deal as IDataObject, { stage }); - } - - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - addAdditionalFields(body.deal as IDataObject, additionalFields); - - } else if (operation === 'update') { - // ---------------------------------- - // deal:update - // ---------------------------------- - - requestMethod = 'PUT'; - - const dealId = this.getNodeParameter('dealId', i) as number; - endpoint = `/api/3/deals/${dealId}`; - - body.deal = {} as IDataObject; - - const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; - addAdditionalFields(body.deal as IDataObject, updateFields); - - } else if (operation === 'delete') { - // ---------------------------------- - // deal:delete - // ---------------------------------- - - requestMethod = 'DELETE'; - - const dealId = this.getNodeParameter('dealId', i) as number; - endpoint = `/api/3/deals/${dealId}`; - - } else if (operation === 'get') { - // ---------------------------------- - // deal:get - // ---------------------------------- - - requestMethod = 'GET'; - - const dealId = this.getNodeParameter('dealId', i) as number; - endpoint = `/api/3/deals/${dealId}`; - - } else if (operation === 'getAll') { - // ---------------------------------- - // deals:getAll - // ---------------------------------- - - requestMethod = 'GET'; - - const simple = this.getNodeParameter('simple', i, true) as boolean; - returnAll = this.getNodeParameter('returnAll', i) as boolean; - if (returnAll === false) { - qs.limit = this.getNodeParameter('limit', i) as number; - } - - if (simple === true) { - dataKey = 'deals'; - } - - endpoint = `/api/3/deals`; - - } else if (operation === 'createNote') { - // ---------------------------------- - // deal:createNote - // ---------------------------------- - requestMethod = 'POST'; - - body.note = { - note: this.getNodeParameter('dealNote', i) as string, - } as IDataObject; - - const dealId = this.getNodeParameter('dealId', i) as number; - endpoint = `/api/3/deals/${dealId}/notes`; - - } else if (operation === 'updateNote') { - // ---------------------------------- - // deal:updateNote - // ---------------------------------- - requestMethod = 'PUT'; - - body.note = { - note: this.getNodeParameter('dealNote', i) as string, - } as IDataObject; - - const dealId = this.getNodeParameter('dealId', i) as number; - const dealNoteId = this.getNodeParameter('dealNoteId', i) as number; - endpoint = `/api/3/deals/${dealId}/notes/${dealNoteId}`; - - } else { - throw new NodeOperationError(this.getNode(), `The operation "${operation}" is not known`); - } - } else if (resource === 'connection') { - if (operation === 'create') { - // ---------------------------------- - // connection:create - // ---------------------------------- - - requestMethod = 'POST'; - - endpoint = '/api/3/connections'; - - body.connection = { - service: this.getNodeParameter('service', i) as string, - externalid: this.getNodeParameter('externalid', i) as string, - name: this.getNodeParameter('name', i) as string, - logoUrl: this.getNodeParameter('logoUrl', i) as string, - linkUrl: this.getNodeParameter('linkUrl', i) as string, - } as IDataObject; - - } else if (operation === 'update') { - // ---------------------------------- - // connection:update - // ---------------------------------- - - requestMethod = 'PUT'; - - const connectionId = this.getNodeParameter('connectionId', i) as number; - endpoint = `/api/3/connections/${connectionId}`; - - body.connection = {} as IDataObject; - - const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; - addAdditionalFields(body.connection as IDataObject, updateFields); - - } else if (operation === 'delete') { - // ---------------------------------- - // connection:delete - // ---------------------------------- - - requestMethod = 'DELETE'; - - const connectionId = this.getNodeParameter('connectionId', i) as number; - endpoint = `/api/3/connections/${connectionId}`; - - } else if (operation === 'get') { - // ---------------------------------- - // connection:get - // ---------------------------------- - - requestMethod = 'GET'; - - const connectionId = this.getNodeParameter('connectionId', i) as number; - endpoint = `/api/3/connections/${connectionId}`; - - } else if (operation === 'getAll') { - // ---------------------------------- - // connections:getAll - // ---------------------------------- - - requestMethod = 'GET'; - - const simple = this.getNodeParameter('simple', i, true) as boolean; - returnAll = this.getNodeParameter('returnAll', i) as boolean; - if (returnAll === false) { - qs.limit = this.getNodeParameter('limit', i) as number; - } - - if (simple === true) { - dataKey = 'connections'; - } - - endpoint = `/api/3/connections`; - - } else { - throw new NodeOperationError(this.getNode(), `The operation "${operation}" is not known`); - } - } else if (resource === 'ecommerceOrder') { - if (operation === 'create') { - // ---------------------------------- - // ecommerceOrder:create - // ---------------------------------- - - requestMethod = 'POST'; - - endpoint = '/api/3/ecomOrders'; - - body.ecomOrder = { - source: this.getNodeParameter('source', i) as string, - email: this.getNodeParameter('email', i) as string, - totalPrice: this.getNodeParameter('totalPrice', i) as number, - currency: this.getNodeParameter('currency', i)!.toString().toUpperCase() as string, - externalCreatedDate: this.getNodeParameter('externalCreatedDate', i) as string, - connectionid: this.getNodeParameter('connectionid', i) as number, - customerid: this.getNodeParameter('customerid', i) as number, - } as IDataObject; - - const externalid = this.getNodeParameter('externalid', i) as string; - if (externalid !== '') { - addAdditionalFields(body.ecomOrder as IDataObject, { externalid }); - } - - const externalcheckoutid = this.getNodeParameter('externalcheckoutid', i) as string; - if (externalcheckoutid !== '') { - addAdditionalFields(body.ecomOrder as IDataObject, { externalcheckoutid }); - } - - const abandonedDate = this.getNodeParameter('abandonedDate', i) as string; - if (abandonedDate !== '') { - addAdditionalFields(body.ecomOrder as IDataObject, { abandonedDate }); - } - - const orderProducts = this.getNodeParameter('orderProducts', i) as unknown as IProduct[]; - addAdditionalFields(body.ecomOrder as IDataObject, { orderProducts }); - - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - addAdditionalFields(body.ecomOrder as IDataObject, additionalFields); - - } else if (operation === 'update') { - // ---------------------------------- - // ecommerceOrder:update - // ---------------------------------- - - requestMethod = 'PUT'; - - const orderId = this.getNodeParameter('orderId', i) as number; - endpoint = `/api/3/ecomOrders/${orderId}`; - - body.ecomOrder = {} as IDataObject; - - const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; - addAdditionalFields(body.ecomOrder as IDataObject, updateFields); - - } else if (operation === 'delete') { - // ---------------------------------- - // ecommerceOrder:delete - // ---------------------------------- - - requestMethod = 'DELETE'; - - const orderId = this.getNodeParameter('orderId', i) as number; - endpoint = `/api/3/ecomOrders/${orderId}`; - - } else if (operation === 'get') { - // ---------------------------------- - // ecommerceOrder:get - // ---------------------------------- - - requestMethod = 'GET'; - - const orderId = this.getNodeParameter('orderId', i) as number; - endpoint = `/api/3/ecomOrders/${orderId}`; - - } else if (operation === 'getAll') { - // ---------------------------------- - // ecommerceOrders:getAll - // ---------------------------------- - - requestMethod = 'GET'; - - const simple = this.getNodeParameter('simple', i, true) as boolean; - returnAll = this.getNodeParameter('returnAll', i) as boolean; - if (returnAll === false) { - qs.limit = this.getNodeParameter('limit', i) as number; - } - - if (simple === true) { - dataKey = 'ecomOrders'; - } - - endpoint = `/api/3/ecomOrders`; - - } else { - throw new NodeOperationError(this.getNode(), `The operation "${operation}" is not known`); - } - } else if (resource === 'ecommerceCustomer') { - if (operation === 'create') { - // ---------------------------------- - // ecommerceCustomer:create - // ---------------------------------- - - requestMethod = 'POST'; - - endpoint = '/api/3/ecomCustomers'; - - body.ecomCustomer = { - connectionid: this.getNodeParameter('connectionid', i) as string, - externalid: this.getNodeParameter('externalid', i) as string, - email: this.getNodeParameter('email', i) as string, - } as IDataObject; - - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - if (additionalFields.acceptsMarketing !== undefined) { - if (additionalFields.acceptsMarketing === true) { - additionalFields.acceptsMarketing = '1'; - } else { - additionalFields.acceptsMarketing = '0'; + if (returnAll === false) { + qs.limit = this.getNodeParameter('limit', i) as number; } - } - addAdditionalFields(body.ecomCustomer as IDataObject, additionalFields); - } else if (operation === 'update') { - // ---------------------------------- - // ecommerceCustomer:update - // ---------------------------------- - - requestMethod = 'PUT'; - - const ecommerceCustomerId = this.getNodeParameter('ecommerceCustomerId', i) as number; - endpoint = `/api/3/ecomCustomers/${ecommerceCustomerId}`; - - body.ecomCustomer = {} as IDataObject; - - const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; - if (updateFields.acceptsMarketing !== undefined) { - if (updateFields.acceptsMarketing === true) { - updateFields.acceptsMarketing = '1'; - } else { - updateFields.acceptsMarketing = '0'; + if (simple === true) { + dataKey = 'lists'; } - } - addAdditionalFields(body.ecomCustomer as IDataObject, updateFields); - } else if (operation === 'delete') { - // ---------------------------------- - // ecommerceCustomer:delete - // ---------------------------------- - - requestMethod = 'DELETE'; - - const ecommerceCustomerId = this.getNodeParameter('ecommerceCustomerId', i) as number; - endpoint = `/api/3/ecomCustomers/${ecommerceCustomerId}`; - - } else if (operation === 'get') { - // ---------------------------------- - // ecommerceCustomer:get - // ---------------------------------- - - requestMethod = 'GET'; - - const ecommerceCustomerId = this.getNodeParameter('ecommerceCustomerId', i) as number; - endpoint = `/api/3/ecomCustomers/${ecommerceCustomerId}`; - - } else if (operation === 'getAll') { - // ---------------------------------- - // ecommerceCustomers:getAll - // ---------------------------------- - - requestMethod = 'GET'; - - const simple = this.getNodeParameter('simple', i, true) as boolean; - returnAll = this.getNodeParameter('returnAll', i) as boolean; - if (returnAll === false) { - qs.limit = this.getNodeParameter('limit', i) as number; + endpoint = `/api/3/lists`; } - if (simple === true) { - dataKey = 'ecomCustomers'; - } + } else if (resource === 'tag') { + if (operation === 'create') { + // ---------------------------------- + // tag:create + // ---------------------------------- - endpoint = `/api/3/ecomCustomers`; + requestMethod = 'POST'; + + endpoint = '/api/3/tags'; + + dataKey = 'tag'; + + body.tag = { + tag: this.getNodeParameter('name', i) as string, + tagType: this.getNodeParameter('tagType', i) as string, + } as IDataObject; + + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + addAdditionalFields(body.tag as IDataObject, additionalFields); + + } else if (operation === 'delete') { + // ---------------------------------- + // tag:delete + // ---------------------------------- + + requestMethod = 'DELETE'; + + const tagId = this.getNodeParameter('tagId', i) as number; + endpoint = `/api/3/tags/${tagId}`; + + } else if (operation === 'get') { + // ---------------------------------- + // tag:get + // ---------------------------------- + + requestMethod = 'GET'; + + const tagId = this.getNodeParameter('tagId', i) as number; + endpoint = `/api/3/tags/${tagId}`; + + } else if (operation === 'getAll') { + // ---------------------------------- + // tags:getAll + // ---------------------------------- + + requestMethod = 'GET'; + + const simple = this.getNodeParameter('simple', i, true) as boolean; + returnAll = this.getNodeParameter('returnAll', i) as boolean; + if (returnAll === false) { + qs.limit = this.getNodeParameter('limit', i) as number; + } + + if (simple === true) { + dataKey = 'tags'; + } + + endpoint = `/api/3/tags`; + + } else if (operation === 'update') { + // ---------------------------------- + // tags:update + // ---------------------------------- + + requestMethod = 'PUT'; + + const tagId = this.getNodeParameter('tagId', i) as number; + endpoint = `/api/3/tags/${tagId}`; + + dataKey = 'tag'; + + body.tag = {} as IDataObject; + + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + addAdditionalFields(body.tag as IDataObject, updateFields); + + } else { + throw new NodeOperationError(this.getNode(), `The operation "${operation}" is not known`); + } + } else if (resource === 'deal') { + if (operation === 'create') { + // ---------------------------------- + // deal:create + // ---------------------------------- + + requestMethod = 'POST'; + + endpoint = '/api/3/deals'; + + body.deal = { + title: this.getNodeParameter('title', i) as string, + contact: this.getNodeParameter('contact', i) as string, + value: this.getNodeParameter('value', i) as number, + currency: this.getNodeParameter('currency', i) as string, + } as IDataObject; + + const group = this.getNodeParameter('group', i) as string; + if (group !== '') { + addAdditionalFields(body.deal as IDataObject, { group }); + } + + const owner = this.getNodeParameter('owner', i) as string; + if (owner !== '') { + addAdditionalFields(body.deal as IDataObject, { owner }); + } + + const stage = this.getNodeParameter('stage', i) as string; + if (stage !== '') { + addAdditionalFields(body.deal as IDataObject, { stage }); + } + + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + addAdditionalFields(body.deal as IDataObject, additionalFields); + + } else if (operation === 'update') { + // ---------------------------------- + // deal:update + // ---------------------------------- + + requestMethod = 'PUT'; + + const dealId = this.getNodeParameter('dealId', i) as number; + endpoint = `/api/3/deals/${dealId}`; + + body.deal = {} as IDataObject; + + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + addAdditionalFields(body.deal as IDataObject, updateFields); + + } else if (operation === 'delete') { + // ---------------------------------- + // deal:delete + // ---------------------------------- + + requestMethod = 'DELETE'; + + const dealId = this.getNodeParameter('dealId', i) as number; + endpoint = `/api/3/deals/${dealId}`; + + } else if (operation === 'get') { + // ---------------------------------- + // deal:get + // ---------------------------------- + + requestMethod = 'GET'; + + const dealId = this.getNodeParameter('dealId', i) as number; + endpoint = `/api/3/deals/${dealId}`; + + } else if (operation === 'getAll') { + // ---------------------------------- + // deals:getAll + // ---------------------------------- + + requestMethod = 'GET'; + + const simple = this.getNodeParameter('simple', i, true) as boolean; + returnAll = this.getNodeParameter('returnAll', i) as boolean; + if (returnAll === false) { + qs.limit = this.getNodeParameter('limit', i) as number; + } + + if (simple === true) { + dataKey = 'deals'; + } + + endpoint = `/api/3/deals`; + + } else if (operation === 'createNote') { + // ---------------------------------- + // deal:createNote + // ---------------------------------- + requestMethod = 'POST'; + + body.note = { + note: this.getNodeParameter('dealNote', i) as string, + } as IDataObject; + + const dealId = this.getNodeParameter('dealId', i) as number; + endpoint = `/api/3/deals/${dealId}/notes`; + + } else if (operation === 'updateNote') { + // ---------------------------------- + // deal:updateNote + // ---------------------------------- + requestMethod = 'PUT'; + + body.note = { + note: this.getNodeParameter('dealNote', i) as string, + } as IDataObject; + + const dealId = this.getNodeParameter('dealId', i) as number; + const dealNoteId = this.getNodeParameter('dealNoteId', i) as number; + endpoint = `/api/3/deals/${dealId}/notes/${dealNoteId}`; + + } else { + throw new NodeOperationError(this.getNode(), `The operation "${operation}" is not known`); + } + } else if (resource === 'connection') { + if (operation === 'create') { + // ---------------------------------- + // connection:create + // ---------------------------------- + + requestMethod = 'POST'; + + endpoint = '/api/3/connections'; + + body.connection = { + service: this.getNodeParameter('service', i) as string, + externalid: this.getNodeParameter('externalid', i) as string, + name: this.getNodeParameter('name', i) as string, + logoUrl: this.getNodeParameter('logoUrl', i) as string, + linkUrl: this.getNodeParameter('linkUrl', i) as string, + } as IDataObject; + + } else if (operation === 'update') { + // ---------------------------------- + // connection:update + // ---------------------------------- + + requestMethod = 'PUT'; + + const connectionId = this.getNodeParameter('connectionId', i) as number; + endpoint = `/api/3/connections/${connectionId}`; + + body.connection = {} as IDataObject; + + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + addAdditionalFields(body.connection as IDataObject, updateFields); + + } else if (operation === 'delete') { + // ---------------------------------- + // connection:delete + // ---------------------------------- + + requestMethod = 'DELETE'; + + const connectionId = this.getNodeParameter('connectionId', i) as number; + endpoint = `/api/3/connections/${connectionId}`; + + } else if (operation === 'get') { + // ---------------------------------- + // connection:get + // ---------------------------------- + + requestMethod = 'GET'; + + const connectionId = this.getNodeParameter('connectionId', i) as number; + endpoint = `/api/3/connections/${connectionId}`; + + } else if (operation === 'getAll') { + // ---------------------------------- + // connections:getAll + // ---------------------------------- + + requestMethod = 'GET'; + + const simple = this.getNodeParameter('simple', i, true) as boolean; + returnAll = this.getNodeParameter('returnAll', i) as boolean; + if (returnAll === false) { + qs.limit = this.getNodeParameter('limit', i) as number; + } + + if (simple === true) { + dataKey = 'connections'; + } + + endpoint = `/api/3/connections`; + + } else { + throw new NodeOperationError(this.getNode(), `The operation "${operation}" is not known`); + } + } else if (resource === 'ecommerceOrder') { + if (operation === 'create') { + // ---------------------------------- + // ecommerceOrder:create + // ---------------------------------- + + requestMethod = 'POST'; + + endpoint = '/api/3/ecomOrders'; + + body.ecomOrder = { + source: this.getNodeParameter('source', i) as string, + email: this.getNodeParameter('email', i) as string, + totalPrice: this.getNodeParameter('totalPrice', i) as number, + currency: this.getNodeParameter('currency', i)!.toString().toUpperCase() as string, + externalCreatedDate: this.getNodeParameter('externalCreatedDate', i) as string, + connectionid: this.getNodeParameter('connectionid', i) as number, + customerid: this.getNodeParameter('customerid', i) as number, + } as IDataObject; + + const externalid = this.getNodeParameter('externalid', i) as string; + if (externalid !== '') { + addAdditionalFields(body.ecomOrder as IDataObject, { externalid }); + } + + const externalcheckoutid = this.getNodeParameter('externalcheckoutid', i) as string; + if (externalcheckoutid !== '') { + addAdditionalFields(body.ecomOrder as IDataObject, { externalcheckoutid }); + } + + const abandonedDate = this.getNodeParameter('abandonedDate', i) as string; + if (abandonedDate !== '') { + addAdditionalFields(body.ecomOrder as IDataObject, { abandonedDate }); + } + + const orderProducts = this.getNodeParameter('orderProducts', i) as unknown as IProduct[]; + addAdditionalFields(body.ecomOrder as IDataObject, { orderProducts }); + + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + addAdditionalFields(body.ecomOrder as IDataObject, additionalFields); + + } else if (operation === 'update') { + // ---------------------------------- + // ecommerceOrder:update + // ---------------------------------- + + requestMethod = 'PUT'; + + const orderId = this.getNodeParameter('orderId', i) as number; + endpoint = `/api/3/ecomOrders/${orderId}`; + + body.ecomOrder = {} as IDataObject; + + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + addAdditionalFields(body.ecomOrder as IDataObject, updateFields); + + } else if (operation === 'delete') { + // ---------------------------------- + // ecommerceOrder:delete + // ---------------------------------- + + requestMethod = 'DELETE'; + + const orderId = this.getNodeParameter('orderId', i) as number; + endpoint = `/api/3/ecomOrders/${orderId}`; + + } else if (operation === 'get') { + // ---------------------------------- + // ecommerceOrder:get + // ---------------------------------- + + requestMethod = 'GET'; + + const orderId = this.getNodeParameter('orderId', i) as number; + endpoint = `/api/3/ecomOrders/${orderId}`; + + } else if (operation === 'getAll') { + // ---------------------------------- + // ecommerceOrders:getAll + // ---------------------------------- + + requestMethod = 'GET'; + + const simple = this.getNodeParameter('simple', i, true) as boolean; + returnAll = this.getNodeParameter('returnAll', i) as boolean; + if (returnAll === false) { + qs.limit = this.getNodeParameter('limit', i) as number; + } + + if (simple === true) { + dataKey = 'ecomOrders'; + } + + endpoint = `/api/3/ecomOrders`; + + } else { + throw new NodeOperationError(this.getNode(), `The operation "${operation}" is not known`); + } + } else if (resource === 'ecommerceCustomer') { + if (operation === 'create') { + // ---------------------------------- + // ecommerceCustomer:create + // ---------------------------------- + + requestMethod = 'POST'; + + endpoint = '/api/3/ecomCustomers'; + + body.ecomCustomer = { + connectionid: this.getNodeParameter('connectionid', i) as string, + externalid: this.getNodeParameter('externalid', i) as string, + email: this.getNodeParameter('email', i) as string, + } as IDataObject; + + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + if (additionalFields.acceptsMarketing !== undefined) { + if (additionalFields.acceptsMarketing === true) { + additionalFields.acceptsMarketing = '1'; + } else { + additionalFields.acceptsMarketing = '0'; + } + } + addAdditionalFields(body.ecomCustomer as IDataObject, additionalFields); + + } else if (operation === 'update') { + // ---------------------------------- + // ecommerceCustomer:update + // ---------------------------------- + + requestMethod = 'PUT'; + + const ecommerceCustomerId = this.getNodeParameter('ecommerceCustomerId', i) as number; + endpoint = `/api/3/ecomCustomers/${ecommerceCustomerId}`; + + body.ecomCustomer = {} as IDataObject; + + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + if (updateFields.acceptsMarketing !== undefined) { + if (updateFields.acceptsMarketing === true) { + updateFields.acceptsMarketing = '1'; + } else { + updateFields.acceptsMarketing = '0'; + } + } + addAdditionalFields(body.ecomCustomer as IDataObject, updateFields); + + } else if (operation === 'delete') { + // ---------------------------------- + // ecommerceCustomer:delete + // ---------------------------------- + + requestMethod = 'DELETE'; + + const ecommerceCustomerId = this.getNodeParameter('ecommerceCustomerId', i) as number; + endpoint = `/api/3/ecomCustomers/${ecommerceCustomerId}`; + + } else if (operation === 'get') { + // ---------------------------------- + // ecommerceCustomer:get + // ---------------------------------- + + requestMethod = 'GET'; + + const ecommerceCustomerId = this.getNodeParameter('ecommerceCustomerId', i) as number; + endpoint = `/api/3/ecomCustomers/${ecommerceCustomerId}`; + + } else if (operation === 'getAll') { + // ---------------------------------- + // ecommerceCustomers:getAll + // ---------------------------------- + + requestMethod = 'GET'; + + const simple = this.getNodeParameter('simple', i, true) as boolean; + returnAll = this.getNodeParameter('returnAll', i) as boolean; + if (returnAll === false) { + qs.limit = this.getNodeParameter('limit', i) as number; + } + + if (simple === true) { + dataKey = 'ecomCustomers'; + } + + endpoint = `/api/3/ecomCustomers`; + + } else { + throw new NodeOperationError(this.getNode(), `The operation "${operation}" is not known`); + } + } else if (resource === 'ecommerceOrderProducts') { + if (operation === 'getByProductId') { + // ---------------------------------- + // ecommerceOrderProducts:getByProductId + // ---------------------------------- + + requestMethod = 'GET'; + + const procuctId = this.getNodeParameter('procuctId', i) as number; + endpoint = `/api/3/ecomOrderProducts/${procuctId}`; + + + } else if (operation === 'getByOrderId') { + // ---------------------------------- + // ecommerceOrderProducts:getByOrderId + // ---------------------------------- + + requestMethod = 'GET'; + + //dataKey = 'ecomOrderProducts'; + + const orderId = this.getNodeParameter('orderId', i) as number; + endpoint = `/api/3/ecomOrders/${orderId}/orderProducts`; + + } else if (operation === 'getAll') { + // ---------------------------------- + // ecommerceOrderProductss:getAll + // ---------------------------------- + + requestMethod = 'GET'; + + const simple = this.getNodeParameter('simple', i, true) as boolean; + returnAll = this.getNodeParameter('returnAll', i) as boolean; + if (returnAll === false) { + qs.limit = this.getNodeParameter('limit', i) as number; + } + + if (simple === true) { + dataKey = 'ecomOrderProducts'; + } + + endpoint = `/api/3/ecomOrderProducts`; + + } else { + throw new NodeOperationError(this.getNode(), `The operation "${operation}" is not known`); + } } else { - throw new NodeOperationError(this.getNode(), `The operation "${operation}" is not known`); + throw new NodeOperationError(this.getNode(), `The resource "${resource}" is not known!`); } - } else if (resource === 'ecommerceOrderProducts') { - if (operation === 'getByProductId') { - // ---------------------------------- - // ecommerceOrderProducts:getByProductId - // ---------------------------------- - - requestMethod = 'GET'; - - const procuctId = this.getNodeParameter('procuctId', i) as number; - endpoint = `/api/3/ecomOrderProducts/${procuctId}`; - - - } else if (operation === 'getByOrderId') { - // ---------------------------------- - // ecommerceOrderProducts:getByOrderId - // ---------------------------------- - - requestMethod = 'GET'; - - //dataKey = 'ecomOrderProducts'; - - const orderId = this.getNodeParameter('orderId', i) as number; - endpoint = `/api/3/ecomOrders/${orderId}/orderProducts`; - - } else if (operation === 'getAll') { - // ---------------------------------- - // ecommerceOrderProductss:getAll - // ---------------------------------- - - requestMethod = 'GET'; - - const simple = this.getNodeParameter('simple', i, true) as boolean; - returnAll = this.getNodeParameter('returnAll', i) as boolean; - if (returnAll === false) { - qs.limit = this.getNodeParameter('limit', i) as number; - } - - if (simple === true) { - dataKey = 'ecomOrderProducts'; - } - - endpoint = `/api/3/ecomOrderProducts`; + let responseData; + if (returnAll === true) { + responseData = await activeCampaignApiRequestAllItems.call(this, requestMethod, endpoint, body, qs, dataKey); } else { - throw new NodeOperationError(this.getNode(), `The operation "${operation}" is not known`); + responseData = await activeCampaignApiRequest.call(this, requestMethod, endpoint, body, qs, dataKey); } - } else { - throw new NodeOperationError(this.getNode(), `The resource "${resource}" is not known!`); - } + if (resource === 'contactList' && operation === 'add' && responseData === undefined) { + responseData = { success: true }; + } - let responseData; - if (returnAll === true) { - responseData = await activeCampaignApiRequestAllItems.call(this, requestMethod, endpoint, body, qs, dataKey); - } else { - responseData = await activeCampaignApiRequest.call(this, requestMethod, endpoint, body, qs, dataKey); - } - - if (resource === 'contactList' && operation === 'add' && responseData === undefined) { - responseData = { success: true }; - } - - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else { - returnData.push(responseData as IDataObject); + if (Array.isArray(responseData)) { + returnData.push.apply(returnData, responseData as IDataObject[]); + } else { + returnData.push(responseData as IDataObject); + } + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } } diff --git a/packages/nodes-base/nodes/Affinity/Affinity.node.ts b/packages/nodes-base/nodes/Affinity/Affinity.node.ts index e422214db3..665486d9c4 100644 --- a/packages/nodes-base/nodes/Affinity/Affinity.node.ts +++ b/packages/nodes-base/nodes/Affinity/Affinity.node.ts @@ -162,196 +162,204 @@ export class Affinity implements INodeType { 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 === 'list') { - //https://api-docs.affinity.co/#get-a-specific-list - if (operation === 'get') { - const listId = this.getNodeParameter('listId', i) as string; - responseData = await affinityApiRequest.call(this, 'GET', `/lists/${listId}`, {}, qs); - } - //https://api-docs.affinity.co/#get-all-lists - if (operation === 'getAll') { - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - responseData = await affinityApiRequest.call(this, 'GET', `/lists`, {}, qs); - if (returnAll === false) { - const limit = this.getNodeParameter('limit', i) as number; - responseData = responseData.splice(0, limit); + try { + if (resource === 'list') { + //https://api-docs.affinity.co/#get-a-specific-list + if (operation === 'get') { + const listId = this.getNodeParameter('listId', i) as string; + responseData = await affinityApiRequest.call(this, 'GET', `/lists/${listId}`, {}, qs); + } + //https://api-docs.affinity.co/#get-all-lists + if (operation === 'getAll') { + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + responseData = await affinityApiRequest.call(this, 'GET', `/lists`, {}, qs); + if (returnAll === false) { + const limit = this.getNodeParameter('limit', i) as number; + responseData = responseData.splice(0, limit); + } } } - } - if (resource === 'listEntry') { - //https://api-docs.affinity.co/#create-a-new-list-entry - if (operation === 'create') { - const listId = this.getNodeParameter('listId', i) as string; - const entityId = this.getNodeParameter('entityId', i) as string; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const body: IDataObject = { - entity_id: parseInt(entityId, 10), - }; - Object.assign(body, additionalFields); - responseData = await affinityApiRequest.call(this, 'POST', `/lists/${listId}/list-entries`, body); - } - //https://api-docs.affinity.co/#get-a-specific-list-entry - if (operation === 'get') { - const listId = this.getNodeParameter('listId', i) as string; - const listEntryId = this.getNodeParameter('listEntryId', i) as string; - responseData = await affinityApiRequest.call(this, 'GET', `/lists/${listId}/list-entries/${listEntryId}`, {}, qs); - } - //https://api-docs.affinity.co/#get-all-list-entries - if (operation === 'getAll') { - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - const listId = this.getNodeParameter('listId', i) as string; - if (returnAll === true) { - responseData = await affinityApiRequestAllItems.call(this, 'list_entries', 'GET', `/lists/${listId}/list-entries`, {}, qs); - } else { - qs.page_size = this.getNodeParameter('limit', i) as number; - responseData = await affinityApiRequest.call(this, 'GET', `/lists/${listId}/list-entries`, {}, qs); - responseData = responseData.list_entries; + if (resource === 'listEntry') { + //https://api-docs.affinity.co/#create-a-new-list-entry + if (operation === 'create') { + const listId = this.getNodeParameter('listId', i) as string; + const entityId = this.getNodeParameter('entityId', i) as string; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const body: IDataObject = { + entity_id: parseInt(entityId, 10), + }; + Object.assign(body, additionalFields); + responseData = await affinityApiRequest.call(this, 'POST', `/lists/${listId}/list-entries`, body); + } + //https://api-docs.affinity.co/#get-a-specific-list-entry + if (operation === 'get') { + const listId = this.getNodeParameter('listId', i) as string; + const listEntryId = this.getNodeParameter('listEntryId', i) as string; + responseData = await affinityApiRequest.call(this, 'GET', `/lists/${listId}/list-entries/${listEntryId}`, {}, qs); + } + //https://api-docs.affinity.co/#get-all-list-entries + if (operation === 'getAll') { + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + const listId = this.getNodeParameter('listId', i) as string; + if (returnAll === true) { + responseData = await affinityApiRequestAllItems.call(this, 'list_entries', 'GET', `/lists/${listId}/list-entries`, {}, qs); + } else { + qs.page_size = this.getNodeParameter('limit', i) as number; + responseData = await affinityApiRequest.call(this, 'GET', `/lists/${listId}/list-entries`, {}, qs); + responseData = responseData.list_entries; + } + } + //https://api-docs.affinity.co/#delete-a-specific-list-entry + if (operation === 'delete') { + const listId = this.getNodeParameter('listId', i) as string; + const listEntryId = this.getNodeParameter('listEntryId', i) as string; + responseData = await affinityApiRequest.call(this, 'DELETE', `/lists/${listId}/list-entries/${listEntryId}`, {}, qs); } } - //https://api-docs.affinity.co/#delete-a-specific-list-entry - if (operation === 'delete') { - const listId = this.getNodeParameter('listId', i) as string; - const listEntryId = this.getNodeParameter('listEntryId', i) as string; - responseData = await affinityApiRequest.call(this, 'DELETE', `/lists/${listId}/list-entries/${listEntryId}`, {}, qs); - } - } - if (resource === 'person') { - //https://api-docs.affinity.co/#create-a-new-person - if (operation === 'create') { - const firstName = this.getNodeParameter('firstName', i) as string; - const lastName = this.getNodeParameter('lastName', i) as string; - const emails = this.getNodeParameter('emails', i) as string[]; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const body: IPerson = { - first_name: firstName, - last_name: lastName, - emails, - }; - if (additionalFields.organizations) { - body.organization_ids = additionalFields.organizations as number[]; + if (resource === 'person') { + //https://api-docs.affinity.co/#create-a-new-person + if (operation === 'create') { + const firstName = this.getNodeParameter('firstName', i) as string; + const lastName = this.getNodeParameter('lastName', i) as string; + const emails = this.getNodeParameter('emails', i) as string[]; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const body: IPerson = { + first_name: firstName, + last_name: lastName, + emails, + }; + if (additionalFields.organizations) { + body.organization_ids = additionalFields.organizations as number[]; + } + responseData = await affinityApiRequest.call(this, 'POST', '/persons', body); } - responseData = await affinityApiRequest.call(this, 'POST', '/persons', body); - } - //https://api-docs.affinity.co/#update-a-person - if (operation === 'update') { - const personId = this.getNodeParameter('personId', i) as number; - const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; - const emails = this.getNodeParameter('emails', i) as string[]; - const body: IPerson = { - emails, - }; - if (updateFields.firstName) { - body.first_name = updateFields.firstName as string; + //https://api-docs.affinity.co/#update-a-person + if (operation === 'update') { + const personId = this.getNodeParameter('personId', i) as number; + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + const emails = this.getNodeParameter('emails', i) as string[]; + const body: IPerson = { + emails, + }; + if (updateFields.firstName) { + body.first_name = updateFields.firstName as string; + } + if (updateFields.lastName) { + body.last_name = updateFields.lastName as string; + } + if (updateFields.organizations) { + body.organization_ids = updateFields.organizations as number[]; + } + responseData = await affinityApiRequest.call(this, 'PUT', `/persons/${personId}`, body); } - if (updateFields.lastName) { - body.last_name = updateFields.lastName as string; + //https://api-docs.affinity.co/#get-a-specific-person + if (operation === 'get') { + const personId = this.getNodeParameter('personId', i) as number; + const options = this.getNodeParameter('options', i) as IDataObject; + if (options.withInteractionDates) { + qs.with_interaction_dates = options.withInteractionDates as boolean; + } + responseData = await affinityApiRequest.call(this, 'GET', `/persons/${personId}`, {}, qs); } - if (updateFields.organizations) { - body.organization_ids = updateFields.organizations as number[]; + //https://api-docs.affinity.co/#search-for-persons + if (operation === 'getAll') { + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + const options = this.getNodeParameter('options', i) as IDataObject; + if (options.term) { + qs.term = options.term as string; + } + if (options.withInteractionDates) { + qs.with_interaction_dates = options.withInteractionDates as boolean; + } + if (returnAll === true) { + responseData = await affinityApiRequestAllItems.call(this, 'persons', 'GET', '/persons', {}, qs); + } else { + qs.page_size = this.getNodeParameter('limit', i) as number; + responseData = await affinityApiRequest.call(this, 'GET', '/persons', {}, qs); + responseData = responseData.persons; + } } - responseData = await affinityApiRequest.call(this, 'PUT', `/persons/${personId}`, body); - } - //https://api-docs.affinity.co/#get-a-specific-person - if (operation === 'get') { - const personId = this.getNodeParameter('personId', i) as number; - const options = this.getNodeParameter('options', i) as IDataObject; - if (options.withInteractionDates) { - qs.with_interaction_dates = options.withInteractionDates as boolean; - } - responseData = await affinityApiRequest.call(this, 'GET', `/persons/${personId}`, {}, qs); - } - //https://api-docs.affinity.co/#search-for-persons - if (operation === 'getAll') { - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - const options = this.getNodeParameter('options', i) as IDataObject; - if (options.term) { - qs.term = options.term as string; - } - if (options.withInteractionDates) { - qs.with_interaction_dates = options.withInteractionDates as boolean; - } - if (returnAll === true) { - responseData = await affinityApiRequestAllItems.call(this, 'persons', 'GET', '/persons', {}, qs); - } else { - qs.page_size = this.getNodeParameter('limit', i) as number; - responseData = await affinityApiRequest.call(this, 'GET', '/persons', {}, qs); - responseData = responseData.persons; + //https://api-docs.affinity.co/#delete-a-person + if (operation === 'delete') { + const personId = this.getNodeParameter('personId', i) as number; + responseData = await affinityApiRequest.call(this, 'DELETE', `/persons/${personId}`, {}, qs); } } - //https://api-docs.affinity.co/#delete-a-person - if (operation === 'delete') { - const personId = this.getNodeParameter('personId', i) as number; - responseData = await affinityApiRequest.call(this, 'DELETE', `/persons/${personId}`, {}, qs); - } - } - if (resource === 'organization') { - //https://api-docs.affinity.co/#create-a-new-organization - if (operation === 'create') { - const name = this.getNodeParameter('name', i) as string; - const domain = this.getNodeParameter('domain', i) as string; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const body: IOrganization = { - name, - domain, - }; - if (additionalFields.persons) { - body.person_ids = additionalFields.persons as number[]; + if (resource === 'organization') { + //https://api-docs.affinity.co/#create-a-new-organization + if (operation === 'create') { + const name = this.getNodeParameter('name', i) as string; + const domain = this.getNodeParameter('domain', i) as string; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const body: IOrganization = { + name, + domain, + }; + if (additionalFields.persons) { + body.person_ids = additionalFields.persons as number[]; + } + responseData = await affinityApiRequest.call(this, 'POST', '/organizations', body); } - responseData = await affinityApiRequest.call(this, 'POST', '/organizations', body); - } - //https://api-docs.affinity.co/#update-an-organization - if (operation === 'update') { - const organizationId = this.getNodeParameter('organizationId', i) as number; - const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; - const body: IOrganization = {}; - if (updateFields.name) { - body.name = updateFields.name as string; + //https://api-docs.affinity.co/#update-an-organization + if (operation === 'update') { + const organizationId = this.getNodeParameter('organizationId', i) as number; + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + const body: IOrganization = {}; + if (updateFields.name) { + body.name = updateFields.name as string; + } + if (updateFields.domain) { + body.domain = updateFields.domain as string; + } + if (updateFields.persons) { + body.person_ids = updateFields.persons as number[]; + } + responseData = await affinityApiRequest.call(this, 'PUT', `/organizations/${organizationId}`, body); } - if (updateFields.domain) { - body.domain = updateFields.domain as string; + //https://api-docs.affinity.co/#get-a-specific-organization + if (operation === 'get') { + const organizationId = this.getNodeParameter('organizationId', i) as number; + const options = this.getNodeParameter('options', i) as IDataObject; + if (options.withInteractionDates) { + qs.with_interaction_dates = options.withInteractionDates as boolean; + } + responseData = await affinityApiRequest.call(this, 'GET', `/organizations/${organizationId}`, {}, qs); } - if (updateFields.persons) { - body.person_ids = updateFields.persons as number[]; + //https://api-docs.affinity.co/#search-for-organizations + if (operation === 'getAll') { + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + const options = this.getNodeParameter('options', i) as IDataObject; + if (options.term) { + qs.term = options.term as string; + } + if (options.withInteractionDates) { + qs.with_interaction_dates = options.withInteractionDates as boolean; + } + if (returnAll === true) { + responseData = await affinityApiRequestAllItems.call(this, 'organizations', 'GET', '/organizations', {}, qs); + } else { + qs.page_size = this.getNodeParameter('limit', i) as number; + responseData = await affinityApiRequest.call(this, 'GET', '/organizations', {}, qs); + responseData = responseData.organizations; + } } - responseData = await affinityApiRequest.call(this, 'PUT', `/organizations/${organizationId}`, body); - } - //https://api-docs.affinity.co/#get-a-specific-organization - if (operation === 'get') { - const organizationId = this.getNodeParameter('organizationId', i) as number; - const options = this.getNodeParameter('options', i) as IDataObject; - if (options.withInteractionDates) { - qs.with_interaction_dates = options.withInteractionDates as boolean; - } - responseData = await affinityApiRequest.call(this, 'GET', `/organizations/${organizationId}`, {}, qs); - } - //https://api-docs.affinity.co/#search-for-organizations - if (operation === 'getAll') { - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - const options = this.getNodeParameter('options', i) as IDataObject; - if (options.term) { - qs.term = options.term as string; - } - if (options.withInteractionDates) { - qs.with_interaction_dates = options.withInteractionDates as boolean; - } - if (returnAll === true) { - responseData = await affinityApiRequestAllItems.call(this, 'organizations', 'GET', '/organizations', {}, qs); - } else { - qs.page_size = this.getNodeParameter('limit', i) as number; - responseData = await affinityApiRequest.call(this, 'GET', '/organizations', {}, qs); - responseData = responseData.organizations; + //https://api-docs.affinity.co/#delete-an-organization + if (operation === 'delete') { + const organizationId = this.getNodeParameter('organizationId', i) as number; + responseData = await affinityApiRequest.call(this, 'DELETE', `/organizations/${organizationId}`, {}, qs); } } - //https://api-docs.affinity.co/#delete-an-organization - if (operation === 'delete') { - const organizationId = this.getNodeParameter('organizationId', i) as number; - responseData = await affinityApiRequest.call(this, 'DELETE', `/organizations/${organizationId}`, {}, qs); + if (Array.isArray(responseData)) { + returnData.push.apply(returnData, responseData as IDataObject[]); + } else { + returnData.push(responseData as IDataObject); } - } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else { - returnData.push(responseData as IDataObject); + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } } return [this.helpers.returnJsonArray(returnData)]; diff --git a/packages/nodes-base/nodes/Airtable/Airtable.node.ts b/packages/nodes-base/nodes/Airtable/Airtable.node.ts index 333183e84a..327de8ccac 100644 --- a/packages/nodes-base/nodes/Airtable/Airtable.node.ts +++ b/packages/nodes-base/nodes/Airtable/Airtable.node.ts @@ -489,43 +489,51 @@ export class Airtable implements INodeType { let bulkSize = 10; for (let i = 0; i < items.length; i++) { - addAllFields = this.getNodeParameter('addAllFields', i) as boolean; - options = this.getNodeParameter('options', i, {}) as IDataObject; - bulkSize = options.bulkSize as number || bulkSize; + try { + addAllFields = this.getNodeParameter('addAllFields', i) as boolean; + options = this.getNodeParameter('options', i, {}) as IDataObject; + bulkSize = options.bulkSize as number || bulkSize; - const row: IDataObject = {}; + const row: IDataObject = {}; - if (addAllFields === true) { - // Add all the fields the item has - row.fields = { ...items[i].json }; - // tslint:disable-next-line: no-any - delete (row.fields! as any).id; - } else { - // Add only the specified fields - row.fields = {} as IDataObject; + if (addAllFields === true) { + // Add all the fields the item has + row.fields = { ...items[i].json }; + // tslint:disable-next-line: no-any + delete (row.fields! as any).id; + } else { + // Add only the specified fields + row.fields = {} as IDataObject; - fields = this.getNodeParameter('fields', i, []) as string[]; + fields = this.getNodeParameter('fields', i, []) as string[]; - for (const fieldName of fields) { - // @ts-ignore - row.fields[fieldName] = items[i].json[fieldName]; - } - } - - rows.push(row); - - if (rows.length === bulkSize || i === items.length - 1) { - if (options.typecast === true) { - body['typecast'] = true; + for (const fieldName of fields) { + // @ts-ignore + row.fields[fieldName] = items[i].json[fieldName]; + } } - body['records'] = rows; + rows.push(row); - responseData = await apiRequest.call(this, requestMethod, endpoint, body, qs); + if (rows.length === bulkSize || i === items.length - 1) { + if (options.typecast === true) { + body['typecast'] = true; + } - returnData.push(...responseData.records); - // empty rows - rows.length = 0; + body['records'] = rows; + + responseData = await apiRequest.call(this, requestMethod, endpoint, body, qs); + + returnData.push(...responseData.records); + // empty rows + rows.length = 0; + } + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } } @@ -537,28 +545,36 @@ export class Airtable implements INodeType { const bulkSize = options.bulkSize as number || 10; for (let i = 0; i < items.length; i++) { - let id: string; + try { + let id: string; - id = this.getNodeParameter('id', i) as string; + id = this.getNodeParameter('id', i) as string; - rows.push(id); + rows.push(id); - if (rows.length === bulkSize || i === items.length - 1) { - endpoint = `${application}/${table}`; + if (rows.length === bulkSize || i === items.length - 1) { + endpoint = `${application}/${table}`; - // Make one request after another. This is slower but makes - // sure that we do not run into the rate limit they have in - // place and so block for 30 seconds. Later some global - // functionality in core should make it easy to make requests - // according to specific rules like not more than 5 requests - // per seconds. - qs.records = rows; + // Make one request after another. This is slower but makes + // sure that we do not run into the rate limit they have in + // place and so block for 30 seconds. Later some global + // functionality in core should make it easy to make requests + // according to specific rules like not more than 5 requests + // per seconds. + qs.records = rows; - responseData = await apiRequest.call(this, requestMethod, endpoint, body, qs); + responseData = await apiRequest.call(this, requestMethod, endpoint, body, qs); - returnData.push(...responseData.records); - // empty rows - rows.length = 0; + returnData.push(...responseData.records); + // empty rows + rows.length = 0; + } + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } } @@ -566,37 +582,44 @@ export class Airtable implements INodeType { // ---------------------------------- // list // ---------------------------------- + try { + requestMethod = 'GET'; + endpoint = `${application}/${table}`; - requestMethod = 'GET'; - endpoint = `${application}/${table}`; + returnAll = this.getNodeParameter('returnAll', 0) as boolean; - returnAll = this.getNodeParameter('returnAll', 0) as boolean; + const downloadAttachments = this.getNodeParameter('downloadAttachments', 0) as boolean; - const downloadAttachments = this.getNodeParameter('downloadAttachments', 0) as boolean; + const additionalOptions = this.getNodeParameter('additionalOptions', 0, {}) as IDataObject; - const additionalOptions = this.getNodeParameter('additionalOptions', 0, {}) as IDataObject; - - for (const key of Object.keys(additionalOptions)) { - if (key === 'sort' && (additionalOptions.sort as IDataObject).property !== undefined) { - qs[key] = (additionalOptions[key] as IDataObject).property; - } else { - qs[key] = additionalOptions[key]; + for (const key of Object.keys(additionalOptions)) { + if (key === 'sort' && (additionalOptions.sort as IDataObject).property !== undefined) { + qs[key] = (additionalOptions[key] as IDataObject).property; + } else { + qs[key] = additionalOptions[key]; + } } - } - if (returnAll === true) { - responseData = await apiRequestAllItems.call(this, requestMethod, endpoint, body, qs); - } else { - qs.maxRecords = this.getNodeParameter('limit', 0) as number; - responseData = await apiRequest.call(this, requestMethod, endpoint, body, qs); - } + if (returnAll === true) { + responseData = await apiRequestAllItems.call(this, requestMethod, endpoint, body, qs); + } else { + qs.maxRecords = this.getNodeParameter('limit', 0) as number; + responseData = await apiRequest.call(this, requestMethod, endpoint, body, qs); + } - returnData.push.apply(returnData, responseData.records); + returnData.push.apply(returnData, responseData.records); - if (downloadAttachments === true) { - const downloadFieldNames = (this.getNodeParameter('downloadFieldNames', 0) as string).split(','); - const data = await downloadRecordAttachments.call(this, responseData.records, downloadFieldNames); - return [data]; + if (downloadAttachments === true) { + const downloadFieldNames = (this.getNodeParameter('downloadFieldNames', 0) as string).split(','); + const data = await downloadRecordAttachments.call(this, responseData.records, downloadFieldNames); + return [data]; + } + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + } else { + throw error; + } } } else if (operation === 'read') { @@ -619,10 +642,17 @@ export class Airtable implements INodeType { // functionality in core should make it easy to make requests // according to specific rules like not more than 5 requests // per seconds. + try { + responseData = await apiRequest.call(this, requestMethod, endpoint, body, qs); - responseData = await apiRequest.call(this, requestMethod, endpoint, body, qs); - - returnData.push(responseData); + returnData.push(responseData); + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; + } } } else if (operation === 'update') { @@ -640,60 +670,68 @@ export class Airtable implements INodeType { let bulkSize = 10; for (let i = 0; i < items.length; i++) { - updateAllFields = this.getNodeParameter('updateAllFields', i) as boolean; - options = this.getNodeParameter('options', i, {}) as IDataObject; - bulkSize = options.bulkSize as number || bulkSize; + try { + updateAllFields = this.getNodeParameter('updateAllFields', i) as boolean; + options = this.getNodeParameter('options', i, {}) as IDataObject; + bulkSize = options.bulkSize as number || bulkSize; - const row: IDataObject = {}; - row.fields = {} as IDataObject; + const row: IDataObject = {}; + row.fields = {} as IDataObject; - if (updateAllFields === true) { - // Update all the fields the item has - row.fields = { ...items[i].json }; - // remove id field - // tslint:disable-next-line: no-any - delete (row.fields! as any).id; + if (updateAllFields === true) { + // Update all the fields the item has + row.fields = { ...items[i].json }; + // remove id field + // tslint:disable-next-line: no-any + delete (row.fields! as any).id; - if (options.ignoreFields && options.ignoreFields !== '') { - const ignoreFields = (options.ignoreFields as string).split(',').map(field => field.trim()).filter(field => !!field); - if (ignoreFields.length) { - // From: https://stackoverflow.com/questions/17781472/how-to-get-a-subset-of-a-javascript-objects-properties - row.fields = Object.entries(items[i].json) - .filter(([key]) => !ignoreFields.includes(key)) - .reduce((obj, [key, val]) => Object.assign(obj, { [key]: val }), {}); + if (options.ignoreFields && options.ignoreFields !== '') { + const ignoreFields = (options.ignoreFields as string).split(',').map(field => field.trim()).filter(field => !!field); + if (ignoreFields.length) { + // From: https://stackoverflow.com/questions/17781472/how-to-get-a-subset-of-a-javascript-objects-properties + row.fields = Object.entries(items[i].json) + .filter(([key]) => !ignoreFields.includes(key)) + .reduce((obj, [key, val]) => Object.assign(obj, { [key]: val }), {}); + } + } + } else { + fields = this.getNodeParameter('fields', i, []) as string[]; + + for (const fieldName of fields) { + // @ts-ignore + row.fields[fieldName] = items[i].json[fieldName]; } } - } else { - fields = this.getNodeParameter('fields', i, []) as string[]; - for (const fieldName of fields) { - // @ts-ignore - row.fields[fieldName] = items[i].json[fieldName]; + row.id = this.getNodeParameter('id', i) as string; + + rows.push(row); + + if (rows.length === bulkSize || i === items.length - 1) { + endpoint = `${application}/${table}`; + + // Make one request after another. This is slower but makes + // sure that we do not run into the rate limit they have in + // place and so block for 30 seconds. Later some global + // functionality in core should make it easy to make requests + // according to specific rules like not more than 5 requests + // per seconds. + + const data = { records: rows, typecast: (options.typecast) ? true : false }; + + responseData = await apiRequest.call(this, requestMethod, endpoint, data, qs); + + returnData.push(...responseData.records); + + // empty rows + rows.length = 0; } - } - - row.id = this.getNodeParameter('id', i) as string; - - rows.push(row); - - if (rows.length === bulkSize || i === items.length - 1) { - endpoint = `${application}/${table}`; - - // Make one request after another. This is slower but makes - // sure that we do not run into the rate limit they have in - // place and so block for 30 seconds. Later some global - // functionality in core should make it easy to make requests - // according to specific rules like not more than 5 requests - // per seconds. - - const data = { records: rows, typecast: (options.typecast) ? true : false }; - - responseData = await apiRequest.call(this, requestMethod, endpoint, data, qs); - - returnData.push(...responseData.records); - - // empty rows - rows.length = 0; + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } } @@ -703,4 +741,4 @@ export class Airtable implements INodeType { return [this.helpers.returnJsonArray(returnData)]; } -} +} \ No newline at end of file diff --git a/packages/nodes-base/nodes/Amqp/Amqp.node.ts b/packages/nodes-base/nodes/Amqp/Amqp.node.ts index 931b82104f..f23a085a4d 100644 --- a/packages/nodes-base/nodes/Amqp/Amqp.node.ts +++ b/packages/nodes-base/nodes/Amqp/Amqp.node.ts @@ -97,84 +97,92 @@ export class Amqp implements INodeType { }; async execute(this: IExecuteFunctions): Promise { - const credentials = this.getCredentials('amqp'); - if (!credentials) { - throw new NodeOperationError(this.getNode(), 'Credentials are mandatory!'); - } + try { + const credentials = this.getCredentials('amqp'); + if (!credentials) { + throw new NodeOperationError(this.getNode(), 'Credentials are mandatory!'); + } - const sink = this.getNodeParameter('sink', 0, '') as string; - const applicationProperties = this.getNodeParameter('headerParametersJson', 0, {}) as string | object; - const options = this.getNodeParameter('options', 0, {}) as IDataObject; - const containerId = options.containerId as string; - const containerReconnect = options.reconnect as boolean || true; - const containerReconnectLimit = options.reconnectLimit as number || 50; + const sink = this.getNodeParameter('sink', 0, '') as string; + const applicationProperties = this.getNodeParameter('headerParametersJson', 0, {}) as string | object; + const options = this.getNodeParameter('options', 0, {}) as IDataObject; + const containerId = options.containerId as string; + const containerReconnect = options.reconnect as boolean || true; + const containerReconnectLimit = options.reconnectLimit as number || 50; - let headerProperties: Dictionary; // tslint:disable-line:no-any - if (typeof applicationProperties === 'string' && applicationProperties !== '') { - headerProperties = JSON.parse(applicationProperties); - } else { - headerProperties = applicationProperties as object; - } + let headerProperties: Dictionary; // tslint:disable-line:no-any + if (typeof applicationProperties === 'string' && applicationProperties !== '') { + headerProperties = JSON.parse(applicationProperties); + } else { + headerProperties = applicationProperties as object; + } - if (sink === '') { - throw new NodeOperationError(this.getNode(), 'Queue or Topic required!'); - } + if (sink === '') { + throw new NodeOperationError(this.getNode(), 'Queue or Topic required!'); + } - const container = create_container(); + const container = create_container(); - /* - Values are documentet here: https://github.com/amqp/rhea#container - */ - const connectOptions: ContainerOptions = { - host: credentials.hostname, - hostname: credentials.hostname, - port: credentials.port, - reconnect: containerReconnect, - reconnect_limit: containerReconnectLimit, - username: credentials.username ? credentials.username : undefined, - password: credentials.password ? credentials.password : undefined, - transport: credentials.transportType ? credentials.transportType : undefined, - container_id: containerId ? containerId : undefined, - id: containerId ? containerId : undefined, - }; - const conn = container.connect(connectOptions); + /* + Values are documentet here: https://github.com/amqp/rhea#container + */ + const connectOptions: ContainerOptions = { + host: credentials.hostname, + hostname: credentials.hostname, + port: credentials.port, + reconnect: containerReconnect, + reconnect_limit: containerReconnectLimit, + username: credentials.username ? credentials.username : undefined, + password: credentials.password ? credentials.password : undefined, + transport: credentials.transportType ? credentials.transportType : undefined, + container_id: containerId ? containerId : undefined, + id: containerId ? containerId : undefined, + }; + const conn = container.connect(connectOptions); - const sender = conn.open_sender(sink); + const sender = conn.open_sender(sink); - const responseData: IDataObject[] = await new Promise((resolve) => { - container.once('sendable', (context: EventContext) => { - const returnData = []; + const responseData: IDataObject[] = await new Promise((resolve) => { + container.once('sendable', (context: EventContext) => { + const returnData = []; - const items = this.getInputData(); - for (let i = 0; i < items.length; i++) { - const item = items[i]; + const items = this.getInputData(); + for (let i = 0; i < items.length; i++) { + const item = items[i]; - let body: IDataObject | string = item.json; - const sendOnlyProperty = options.sendOnlyProperty as string; + let body: IDataObject | string = item.json; + const sendOnlyProperty = options.sendOnlyProperty as string; - if (sendOnlyProperty) { - body = body[sendOnlyProperty] as string; + if (sendOnlyProperty) { + body = body[sendOnlyProperty] as string; + } + + if (options.dataAsObject !== true) { + body = JSON.stringify(body); + } + + const result = context.sender?.send({ + application_properties: headerProperties, + body, + }); + + returnData.push({ id: result?.id }); } - if (options.dataAsObject !== true) { - body = JSON.stringify(body); - } - - const result = context.sender?.send({ - application_properties: headerProperties, - body, - }); - - returnData.push({ id: result?.id }); - } - - resolve(returnData); + resolve(returnData); + }); }); - }); - sender.close(); - conn.close(); + sender.close(); + conn.close(); - return [this.helpers.returnJsonArray(responseData)]; + return [this.helpers.returnJsonArray(responseData)]; + } catch (error) { + if (this.continueOnFail()) { + return [this.helpers.returnJsonArray({ error: error.message })]; + }else{ + throw error; + } + } } } diff --git a/packages/nodes-base/nodes/ApiTemplateIo/ApiTemplateIo.node.ts b/packages/nodes-base/nodes/ApiTemplateIo/ApiTemplateIo.node.ts index 86055ad49c..1bbf47e5d1 100644 --- a/packages/nodes-base/nodes/ApiTemplateIo/ApiTemplateIo.node.ts +++ b/packages/nodes-base/nodes/ApiTemplateIo/ApiTemplateIo.node.ts @@ -420,10 +420,17 @@ export class ApiTemplateIo implements INodeType { // ---------------------------------- for (let i = 0; i < length; i++) { + try { + responseData = await apiTemplateIoApiRequest.call(this, 'GET', '/account-information'); - responseData = await apiTemplateIoApiRequest.call(this, 'GET', '/account-information'); - - returnData.push(responseData); + returnData.push(responseData); + } catch (error) { + if (this.continueOnFail()) { + returnData.push({json:{ error: error.message }}); + continue; + } + throw error; + } } } @@ -442,52 +449,60 @@ export class ApiTemplateIo implements INodeType { // https://docs.apitemplate.io/reference/api-reference.html#create-an-image-jpeg-and-png for (let i = 0; i < length; i++) { - const jsonParameters = this.getNodeParameter('jsonParameters', i) as boolean; + try { + const jsonParameters = this.getNodeParameter('jsonParameters', i) as boolean; - const options = this.getNodeParameter('options', i) as IDataObject; + const options = this.getNodeParameter('options', i) as IDataObject; - const qs = { - template_id: this.getNodeParameter('imageTemplateId', i), - }; - - const body = { overrides: [] } as IDataObject; - - if (jsonParameters === false) { - const overrides = (this.getNodeParameter('overridesUi', i) as IDataObject || {}).overrideValues as IDataObject[] || []; - if (overrides.length !== 0) { - const data: IDataObject[] = []; - for (const override of overrides) { - const properties = (override.propertiesUi as IDataObject || {}).propertyValues as IDataObject[] || []; - data.push(properties.reduce((obj, value) => Object.assign(obj, { [`${value.key}`]: value.value }), {})); - } - body.overrides = data; - } - } else { - const overrideJson = this.getNodeParameter('overridesJson', i) as string; - if (overrideJson !== '') { - const data = validateJSON(overrideJson); - if (data === undefined) { - throw new NodeOperationError(this.getNode(), 'A valid JSON must be provided.'); - } - body.overrides = data; - } - } - - responseData = await apiTemplateIoApiRequest.call(this, 'POST', '/create', qs, body); - - if (download === true) { - const binaryProperty = this.getNodeParameter('binaryProperty', i) as string; - const data = await downloadImage.call(this, responseData.download_url); - const fileName = responseData.download_url.split('/').pop(); - const binaryData = await this.helpers.prepareBinaryData(data, options.fileName || fileName); - responseData = { - json: responseData, - binary: { - [binaryProperty]: binaryData, - }, + const qs = { + template_id: this.getNodeParameter('imageTemplateId', i), }; + + const body = { overrides: [] } as IDataObject; + + if (jsonParameters === false) { + const overrides = (this.getNodeParameter('overridesUi', i) as IDataObject || {}).overrideValues as IDataObject[] || []; + if (overrides.length !== 0) { + const data: IDataObject[] = []; + for (const override of overrides) { + const properties = (override.propertiesUi as IDataObject || {}).propertyValues as IDataObject[] || []; + data.push(properties.reduce((obj, value) => Object.assign(obj, { [`${value.key}`]: value.value }), {})); + } + body.overrides = data; + } + } else { + const overrideJson = this.getNodeParameter('overridesJson', i) as string; + if (overrideJson !== '') { + const data = validateJSON(overrideJson); + if (data === undefined) { + throw new NodeOperationError(this.getNode(), 'A valid JSON must be provided.'); + } + body.overrides = data; + } + } + + responseData = await apiTemplateIoApiRequest.call(this, 'POST', '/create', qs, body); + + if (download === true) { + const binaryProperty = this.getNodeParameter('binaryProperty', i) as string; + const data = await downloadImage.call(this, responseData.download_url); + const fileName = responseData.download_url.split('/').pop(); + const binaryData = await this.helpers.prepareBinaryData(data, options.fileName || fileName); + responseData = { + json: responseData, + binary: { + [binaryProperty]: binaryData, + }, + }; + } + returnData.push(responseData); + } catch (error) { + if (this.continueOnFail()) { + returnData.push({json:{ error: error.message }}); + continue; + } + throw error; } - returnData.push(responseData); } if (download === true) { @@ -511,45 +526,53 @@ export class ApiTemplateIo implements INodeType { const download = this.getNodeParameter('download', 0) as boolean; for (let i = 0; i < length; i++) { - const jsonParameters = this.getNodeParameter('jsonParameters', i) as boolean; + try { + const jsonParameters = this.getNodeParameter('jsonParameters', i) as boolean; - const options = this.getNodeParameter('options', i) as IDataObject; + const options = this.getNodeParameter('options', i) as IDataObject; - const qs = { - template_id: this.getNodeParameter('pdfTemplateId', i), - }; - - let data; - - if (jsonParameters === false) { - const properties = (this.getNodeParameter('propertiesUi', i) as IDataObject || {}).propertyValues as IDataObject[] || []; - if (properties.length === 0) { - throw new NodeOperationError(this.getNode(), 'The parameter properties cannot be empty'); - } - data = properties.reduce((obj, value) => Object.assign(obj, { [`${value.key}`]: value.value }), {}); - } else { - const propertiesJson = this.getNodeParameter('propertiesJson', i) as string; - data = validateJSON(propertiesJson); - if (data === undefined) { - throw new NodeOperationError(this.getNode(), 'A valid JSON must be provided.'); - } - } - - responseData = await apiTemplateIoApiRequest.call(this, 'POST', '/create', qs, data); - - if (download === true) { - const binaryProperty = this.getNodeParameter('binaryProperty', i) as string; - const data = await downloadImage.call(this, responseData.download_url); - const fileName = responseData.download_url.split('/').pop(); - const binaryData = await this.helpers.prepareBinaryData(data, options.fileName || fileName); - responseData = { - json: responseData, - binary: { - [binaryProperty]: binaryData, - }, + const qs = { + template_id: this.getNodeParameter('pdfTemplateId', i), }; + + let data; + + if (jsonParameters === false) { + const properties = (this.getNodeParameter('propertiesUi', i) as IDataObject || {}).propertyValues as IDataObject[] || []; + if (properties.length === 0) { + throw new NodeOperationError(this.getNode(), 'The parameter properties cannot be empty'); + } + data = properties.reduce((obj, value) => Object.assign(obj, { [`${value.key}`]: value.value }), {}); + } else { + const propertiesJson = this.getNodeParameter('propertiesJson', i) as string; + data = validateJSON(propertiesJson); + if (data === undefined) { + throw new NodeOperationError(this.getNode(), 'A valid JSON must be provided.'); + } + } + + responseData = await apiTemplateIoApiRequest.call(this, 'POST', '/create', qs, data); + + if (download === true) { + const binaryProperty = this.getNodeParameter('binaryProperty', i) as string; + const data = await downloadImage.call(this, responseData.download_url); + const fileName = responseData.download_url.split('/').pop(); + const binaryData = await this.helpers.prepareBinaryData(data, options.fileName || fileName); + responseData = { + json: responseData, + binary: { + [binaryProperty]: binaryData, + }, + }; + } + returnData.push(responseData); + } catch (error) { + if (this.continueOnFail()) { + returnData.push({json:{ error: error.message }}); + continue; + } + throw error; } - returnData.push(responseData); } if (download === true) { return this.prepareOutputData(returnData as unknown as INodeExecutionData[]); diff --git a/packages/nodes-base/nodes/Asana/Asana.node.ts b/packages/nodes-base/nodes/Asana/Asana.node.ts index d7d1971dcf..644a9fae12 100644 --- a/packages/nodes-base/nodes/Asana/Asana.node.ts +++ b/packages/nodes-base/nodes/Asana/Asana.node.ts @@ -1842,417 +1842,425 @@ export class Asana implements INodeType { let responseData; for (let i = 0; i < items.length; i++) { - body = {}; - qs = {}; + try { + body = {}; + qs = {}; - if (resource === 'subtask') { - if (operation === 'create') { - // ---------------------------------- - // subtask:create - // ---------------------------------- + if (resource === 'subtask') { + if (operation === 'create') { + // ---------------------------------- + // subtask:create + // ---------------------------------- - const taskId = this.getNodeParameter('taskId', i) as string; + const taskId = this.getNodeParameter('taskId', i) as string; - requestMethod = 'POST'; - endpoint = `/tasks/${taskId}/subtasks`; + requestMethod = 'POST'; + endpoint = `/tasks/${taskId}/subtasks`; - body.name = this.getNodeParameter('name', i) as string; + body.name = this.getNodeParameter('name', i) as string; - const otherProperties = this.getNodeParameter('otherProperties', i) as IDataObject; - Object.assign(body, otherProperties); - - responseData = await asanaApiRequest.call(this, requestMethod, endpoint, body, qs); - - responseData = responseData.data; - } - - if (operation === 'getAll') { - // ---------------------------------- - // subtask:getAll - // ---------------------------------- - const taskId = this.getNodeParameter('taskId', i) as string; - - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - - const options = this.getNodeParameter('options', i) as IDataObject; - - requestMethod = 'GET'; - endpoint = `/tasks/${taskId}/subtasks`; - - Object.assign(qs, options); - - if (qs.opt_fields) { - const fields = qs.opt_fields as string[]; - if (fields.includes('*')) { - qs.opt_fields = getTaskFields().map((e) => snakeCase(e)).join(','); - } else { - qs.opt_fields = (qs.opt_fields as string[]).join(','); - } - } - - responseData = await asanaApiRequest.call(this, requestMethod, endpoint, body, qs); - - responseData = responseData.data; - - if (returnAll === false) { - const limit = this.getNodeParameter('limit', i) as boolean; - responseData = responseData.splice(0, limit); - } - } - } - if (resource === 'task') { - if (operation === 'create') { - // ---------------------------------- - // task:create - // ---------------------------------- - - requestMethod = 'POST'; - endpoint = '/tasks'; - - body.name = this.getNodeParameter('name', i) as string; - // body.notes = this.getNodeParameter('taskNotes', 0) as string; - body.workspace = this.getNodeParameter('workspace', i) as string; - - const otherProperties = this.getNodeParameter('otherProperties', i) as IDataObject; - Object.assign(body, otherProperties); - - responseData = await asanaApiRequest.call(this, requestMethod, endpoint, body, qs); - - responseData = responseData.data; - - } else if (operation === 'delete') { - // ---------------------------------- - // task:delete - // ---------------------------------- - - requestMethod = 'DELETE'; - - endpoint = '/tasks/' + this.getNodeParameter('id', i) as string; - - responseData = await asanaApiRequest.call(this, requestMethod, endpoint, body, qs); - - responseData = responseData.data; - - } else if (operation === 'get') { - // ---------------------------------- - // task:get - // ---------------------------------- - - requestMethod = 'GET'; - - endpoint = '/tasks/' + this.getNodeParameter('id', i) as string; - - responseData = await asanaApiRequest.call(this, requestMethod, endpoint, body, qs); - - responseData = responseData.data; - - } else if (operation === 'getAll') { - // ---------------------------------- - // task:getAll - // ---------------------------------- - - const filters = this.getNodeParameter('filters', i) as IDataObject; - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - - requestMethod = 'GET'; - endpoint = `/tasks`; - - Object.assign(qs, filters); - - if (qs.opt_fields) { - const fields = qs.opt_fields as string[]; - if (fields.includes('*')) { - qs.opt_fields = getTaskFields().map((e) => snakeCase(e)).join(','); - } else { - qs.opt_fields = (qs.opt_fields as string[]).join(','); - } - } - - if (qs.modified_since) { - qs.modified_since = moment.tz(qs.modified_since as string, timezone).format(); - } - - if (qs.completed_since) { - qs.completed_since = moment.tz(qs.completed_since as string, timezone).format(); - } - - if (returnAll) { - responseData = await asanaApiRequestAllItems.call(this, requestMethod, endpoint, body, qs); - - } else { - qs.limit = this.getNodeParameter('limit', i) as boolean; + const otherProperties = this.getNodeParameter('otherProperties', i) as IDataObject; + Object.assign(body, otherProperties); responseData = await asanaApiRequest.call(this, requestMethod, endpoint, body, qs); responseData = responseData.data; } - } else if (operation === 'move') { - // ---------------------------------- - // task:move - // ---------------------------------- + if (operation === 'getAll') { + // ---------------------------------- + // subtask:getAll + // ---------------------------------- + const taskId = this.getNodeParameter('taskId', i) as string; - const sectionId = this.getNodeParameter('section', i) as string; + const returnAll = this.getNodeParameter('returnAll', i) as boolean; - requestMethod = 'POST'; + const options = this.getNodeParameter('options', i) as IDataObject; - endpoint = `/sections/${sectionId}/addTask`; + requestMethod = 'GET'; + endpoint = `/tasks/${taskId}/subtasks`; - body.task = this.getNodeParameter('id', i) as string; + Object.assign(qs, options); - Object.assign(body); + if (qs.opt_fields) { + const fields = qs.opt_fields as string[]; + if (fields.includes('*')) { + qs.opt_fields = getTaskFields().map((e) => snakeCase(e)).join(','); + } else { + qs.opt_fields = (qs.opt_fields as string[]).join(','); + } + } - responseData = await asanaApiRequest.call(this, requestMethod, endpoint, body, qs); + responseData = await asanaApiRequest.call(this, requestMethod, endpoint, body, qs); - responseData = { success: true }; + responseData = responseData.data; - } else if (operation === 'update') { - // ---------------------------------- - // task:update - // ---------------------------------- - - requestMethod = 'PUT'; - endpoint = '/tasks/' + this.getNodeParameter('id', i) as string; - - const otherProperties = this.getNodeParameter('otherProperties', i) as IDataObject; - Object.assign(body, otherProperties); - - responseData = await asanaApiRequest.call(this, requestMethod, endpoint, body, qs); - - responseData = responseData.data; - - } else if (operation === 'search') { - // ---------------------------------- - // tasksearch - // ---------------------------------- - - const workspaceId = this.getNodeParameter('workspace', i) as string; - - requestMethod = 'GET'; - endpoint = `/workspaces/${workspaceId}/tasks/search`; - - const searchTaskProperties = this.getNodeParameter('searchTaskProperties', i) as IDataObject; - Object.assign(qs, searchTaskProperties); - - responseData = await asanaApiRequest.call(this, requestMethod, endpoint, body, qs); - - responseData = responseData.data; - } - } - if (resource === 'taskComment') { - if (operation === 'add') { - // ---------------------------------- - // taskComment:add - // ---------------------------------- - - const taskId = this.getNodeParameter('id', i) as string; - - const isTextHtml = this.getNodeParameter('isTextHtml', i) as boolean; - - if (!isTextHtml) { - body.text = this.getNodeParameter('text', i) as string; - } else { - body.html_text = this.getNodeParameter('text', i) as string; + if (returnAll === false) { + const limit = this.getNodeParameter('limit', i) as boolean; + responseData = responseData.splice(0, limit); + } } - - requestMethod = 'POST'; - - endpoint = `/tasks/${taskId}/stories`; - - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - - Object.assign(body, additionalFields); - - responseData = await asanaApiRequest.call(this, requestMethod, endpoint, body, qs); - - responseData = responseData.data; } + if (resource === 'task') { + if (operation === 'create') { + // ---------------------------------- + // task:create + // ---------------------------------- - if (operation === 'remove') { - // ---------------------------------- - // taskComment:remove - // ---------------------------------- + requestMethod = 'POST'; + endpoint = '/tasks'; - const commentId = this.getNodeParameter('id', i) as string; + body.name = this.getNodeParameter('name', i) as string; + // body.notes = this.getNodeParameter('taskNotes', 0) as string; + body.workspace = this.getNodeParameter('workspace', i) as string; - requestMethod = 'DELETE'; + const otherProperties = this.getNodeParameter('otherProperties', i) as IDataObject; + Object.assign(body, otherProperties); - endpoint = `/stories/${commentId}`; + responseData = await asanaApiRequest.call(this, requestMethod, endpoint, body, qs); - responseData = await asanaApiRequest.call(this, requestMethod, endpoint, body, qs); + responseData = responseData.data; - responseData = { success: true }; - } - } - if (resource === 'taskTag') { - if (operation === 'add') { + } else if (operation === 'delete') { + // ---------------------------------- + // task:delete + // ---------------------------------- - // ---------------------------------- - // taskTag:add - // ---------------------------------- + requestMethod = 'DELETE'; - const taskId = this.getNodeParameter('id', i) as string; + endpoint = '/tasks/' + this.getNodeParameter('id', i) as string; - requestMethod = 'POST'; + responseData = await asanaApiRequest.call(this, requestMethod, endpoint, body, qs); - endpoint = `/tasks/${taskId}/addTag`; + responseData = responseData.data; - body.tag = this.getNodeParameter('tag', i) as string; + } else if (operation === 'get') { + // ---------------------------------- + // task:get + // ---------------------------------- - responseData = await asanaApiRequest.call(this, requestMethod, endpoint, body, qs); + requestMethod = 'GET'; - responseData = { success: true }; - } + endpoint = '/tasks/' + this.getNodeParameter('id', i) as string; - if (operation === 'remove') { + responseData = await asanaApiRequest.call(this, requestMethod, endpoint, body, qs); - // ---------------------------------- - // taskTag:remove - // ---------------------------------- + responseData = responseData.data; - const taskId = this.getNodeParameter('id', i) as string; + } else if (operation === 'getAll') { + // ---------------------------------- + // task:getAll + // ---------------------------------- - requestMethod = 'POST'; + const filters = this.getNodeParameter('filters', i) as IDataObject; + const returnAll = this.getNodeParameter('returnAll', i) as boolean; - endpoint = `/tasks/${taskId}/removeTag`; + requestMethod = 'GET'; + endpoint = `/tasks`; - body.tag = this.getNodeParameter('tag', i) as string; + Object.assign(qs, filters); - responseData = await asanaApiRequest.call(this, requestMethod, endpoint, body, qs); + if (qs.opt_fields) { + const fields = qs.opt_fields as string[]; + if (fields.includes('*')) { + qs.opt_fields = getTaskFields().map((e) => snakeCase(e)).join(','); + } else { + qs.opt_fields = (qs.opt_fields as string[]).join(','); + } + } - responseData = { success: true }; - } - } - if (resource === 'taskProject') { - if (operation === 'add') { + if (qs.modified_since) { + qs.modified_since = moment.tz(qs.modified_since as string, timezone).format(); + } - // ---------------------------------- - // taskProject:add - // ---------------------------------- + if (qs.completed_since) { + qs.completed_since = moment.tz(qs.completed_since as string, timezone).format(); + } - const taskId = this.getNodeParameter('id', i) as string; + if (returnAll) { + responseData = await asanaApiRequestAllItems.call(this, requestMethod, endpoint, body, qs); - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + } else { + qs.limit = this.getNodeParameter('limit', i) as boolean; - requestMethod = 'POST'; + responseData = await asanaApiRequest.call(this, requestMethod, endpoint, body, qs); - endpoint = `/tasks/${taskId}/addProject`; + responseData = responseData.data; + } - body.project = this.getNodeParameter('project', i) as string; + } else if (operation === 'move') { + // ---------------------------------- + // task:move + // ---------------------------------- - Object.assign(body, additionalFields); + const sectionId = this.getNodeParameter('section', i) as string; - responseData = await asanaApiRequest.call(this, requestMethod, endpoint, body, qs); + requestMethod = 'POST'; - responseData = { success: true }; - } + endpoint = `/sections/${sectionId}/addTask`; - if (operation === 'remove') { + body.task = this.getNodeParameter('id', i) as string; - // ---------------------------------- - // taskProject:remove - // ---------------------------------- + Object.assign(body); - const taskId = this.getNodeParameter('id', i) as string; + responseData = await asanaApiRequest.call(this, requestMethod, endpoint, body, qs); - requestMethod = 'POST'; + responseData = { success: true }; - endpoint = `/tasks/${taskId}/removeProject`; + } else if (operation === 'update') { + // ---------------------------------- + // task:update + // ---------------------------------- - body.project = this.getNodeParameter('project', i) as string; + requestMethod = 'PUT'; + endpoint = '/tasks/' + this.getNodeParameter('id', i) as string; - responseData = await asanaApiRequest.call(this, requestMethod, endpoint, body, qs); + const otherProperties = this.getNodeParameter('otherProperties', i) as IDataObject; + Object.assign(body, otherProperties); - responseData = { success: true }; - } - } - if (resource === 'user') { - if (operation === 'get') { - // ---------------------------------- - // get - // ---------------------------------- + responseData = await asanaApiRequest.call(this, requestMethod, endpoint, body, qs); - const userId = this.getNodeParameter('userId', i) as string; + responseData = responseData.data; - requestMethod = 'GET'; - endpoint = `/users/${userId}`; + } else if (operation === 'search') { + // ---------------------------------- + // tasksearch + // ---------------------------------- - responseData = await asanaApiRequest.call(this, requestMethod, endpoint, body, qs); - responseData = responseData.data; + const workspaceId = this.getNodeParameter('workspace', i) as string; - } else if (operation === 'getAll') { - // ---------------------------------- - // getAll - // ---------------------------------- + requestMethod = 'GET'; + endpoint = `/workspaces/${workspaceId}/tasks/search`; - const workspaceId = this.getNodeParameter('workspace', i) as string; - - requestMethod = 'GET'; - endpoint = `/workspaces/${workspaceId}/users`; - - responseData = await asanaApiRequest.call(this, requestMethod, endpoint, body, qs); - responseData = responseData.data; - - } - } - if (resource === 'project') { - - if (operation === 'get') { - // ---------------------------------- - // project:get - // ---------------------------------- - const projectId = this.getNodeParameter('id', i) as string; - - requestMethod = 'GET'; - - endpoint = `/projects/${projectId}`; - - responseData = await asanaApiRequest.call(this, requestMethod, endpoint, body, qs); - - responseData = responseData.data; - - } - - if (operation === 'getAll') { - // ---------------------------------- - // project:getAll - // ---------------------------------- - const workspaceId = this.getNodeParameter('workspace', i) as string; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - - requestMethod = 'GET'; - endpoint = `/projects`; - - if (additionalFields.team) { - qs.team = additionalFields.team; - } else { - qs.workspace = workspaceId; - } - - if (additionalFields.archived) { - qs.archived = additionalFields.archived as boolean; - } - - if (returnAll) { - - responseData = await asanaApiRequestAllItems.call(this, requestMethod, endpoint, body, qs); - - } else { - - qs.limit = this.getNodeParameter('limit', i) as boolean; + const searchTaskProperties = this.getNodeParameter('searchTaskProperties', i) as IDataObject; + Object.assign(qs, searchTaskProperties); responseData = await asanaApiRequest.call(this, requestMethod, endpoint, body, qs); responseData = responseData.data; } } - } + if (resource === 'taskComment') { + if (operation === 'add') { + // ---------------------------------- + // taskComment:add + // ---------------------------------- - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else { - returnData.push(responseData); + const taskId = this.getNodeParameter('id', i) as string; + + const isTextHtml = this.getNodeParameter('isTextHtml', i) as boolean; + + if (!isTextHtml) { + body.text = this.getNodeParameter('text', i) as string; + } else { + body.html_text = this.getNodeParameter('text', i) as string; + } + + requestMethod = 'POST'; + + endpoint = `/tasks/${taskId}/stories`; + + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + + Object.assign(body, additionalFields); + + responseData = await asanaApiRequest.call(this, requestMethod, endpoint, body, qs); + + responseData = responseData.data; + } + + if (operation === 'remove') { + // ---------------------------------- + // taskComment:remove + // ---------------------------------- + + const commentId = this.getNodeParameter('id', i) as string; + + requestMethod = 'DELETE'; + + endpoint = `/stories/${commentId}`; + + responseData = await asanaApiRequest.call(this, requestMethod, endpoint, body, qs); + + responseData = { success: true }; + } + } + if (resource === 'taskTag') { + if (operation === 'add') { + + // ---------------------------------- + // taskTag:add + // ---------------------------------- + + const taskId = this.getNodeParameter('id', i) as string; + + requestMethod = 'POST'; + + endpoint = `/tasks/${taskId}/addTag`; + + body.tag = this.getNodeParameter('tag', i) as string; + + responseData = await asanaApiRequest.call(this, requestMethod, endpoint, body, qs); + + responseData = { success: true }; + } + + if (operation === 'remove') { + + // ---------------------------------- + // taskTag:remove + // ---------------------------------- + + const taskId = this.getNodeParameter('id', i) as string; + + requestMethod = 'POST'; + + endpoint = `/tasks/${taskId}/removeTag`; + + body.tag = this.getNodeParameter('tag', i) as string; + + responseData = await asanaApiRequest.call(this, requestMethod, endpoint, body, qs); + + responseData = { success: true }; + } + } + if (resource === 'taskProject') { + if (operation === 'add') { + + // ---------------------------------- + // taskProject:add + // ---------------------------------- + + const taskId = this.getNodeParameter('id', i) as string; + + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + + requestMethod = 'POST'; + + endpoint = `/tasks/${taskId}/addProject`; + + body.project = this.getNodeParameter('project', i) as string; + + Object.assign(body, additionalFields); + + responseData = await asanaApiRequest.call(this, requestMethod, endpoint, body, qs); + + responseData = { success: true }; + } + + if (operation === 'remove') { + + // ---------------------------------- + // taskProject:remove + // ---------------------------------- + + const taskId = this.getNodeParameter('id', i) as string; + + requestMethod = 'POST'; + + endpoint = `/tasks/${taskId}/removeProject`; + + body.project = this.getNodeParameter('project', i) as string; + + responseData = await asanaApiRequest.call(this, requestMethod, endpoint, body, qs); + + responseData = { success: true }; + } + } + if (resource === 'user') { + if (operation === 'get') { + // ---------------------------------- + // get + // ---------------------------------- + + const userId = this.getNodeParameter('userId', i) as string; + + requestMethod = 'GET'; + endpoint = `/users/${userId}`; + + responseData = await asanaApiRequest.call(this, requestMethod, endpoint, body, qs); + responseData = responseData.data; + + } else if (operation === 'getAll') { + // ---------------------------------- + // getAll + // ---------------------------------- + + const workspaceId = this.getNodeParameter('workspace', i) as string; + + requestMethod = 'GET'; + endpoint = `/workspaces/${workspaceId}/users`; + + responseData = await asanaApiRequest.call(this, requestMethod, endpoint, body, qs); + responseData = responseData.data; + + } + } + if (resource === 'project') { + + if (operation === 'get') { + // ---------------------------------- + // project:get + // ---------------------------------- + const projectId = this.getNodeParameter('id', i) as string; + + requestMethod = 'GET'; + + endpoint = `/projects/${projectId}`; + + responseData = await asanaApiRequest.call(this, requestMethod, endpoint, body, qs); + + responseData = responseData.data; + + } + + if (operation === 'getAll') { + // ---------------------------------- + // project:getAll + // ---------------------------------- + const workspaceId = this.getNodeParameter('workspace', i) as string; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + + requestMethod = 'GET'; + endpoint = `/projects`; + + if (additionalFields.team) { + qs.team = additionalFields.team; + } else { + qs.workspace = workspaceId; + } + + if (additionalFields.archived) { + qs.archived = additionalFields.archived as boolean; + } + + if (returnAll) { + + responseData = await asanaApiRequestAllItems.call(this, requestMethod, endpoint, body, qs); + + } else { + + qs.limit = this.getNodeParameter('limit', i) as boolean; + + responseData = await asanaApiRequest.call(this, requestMethod, endpoint, body, qs); + + responseData = responseData.data; + } + } + } + + if (Array.isArray(responseData)) { + returnData.push.apply(returnData, responseData as IDataObject[]); + } else { + returnData.push(responseData); + } + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } } diff --git a/packages/nodes-base/nodes/Aws/AwsLambda.node.ts b/packages/nodes-base/nodes/Aws/AwsLambda.node.ts index 72de2d530f..24fbb095dc 100644 --- a/packages/nodes-base/nodes/Aws/AwsLambda.node.ts +++ b/packages/nodes-base/nodes/Aws/AwsLambda.node.ts @@ -172,39 +172,46 @@ export class AwsLambda implements INodeType { const returnData: IDataObject[] = []; for (let i = 0; i < items.length; i++) { - const params = { - FunctionName: this.getNodeParameter('function', i) as string, - InvocationType: this.getNodeParameter('invocationType', i) as string, - Payload: this.getNodeParameter('payload', i) as string, - Qualifier: this.getNodeParameter('qualifier', i) as string, - }; + try { + const params = { + FunctionName: this.getNodeParameter('function', i) as string, + InvocationType: this.getNodeParameter('invocationType', i) as string, + Payload: this.getNodeParameter('payload', i) as string, + Qualifier: this.getNodeParameter('qualifier', i) as string, + }; - const responseData = await awsApiRequestREST.call( - this, - 'lambda', - 'POST', - `/2015-03-31/functions/${params.FunctionName}/invocations?Qualifier=${params.Qualifier}`, - params.Payload, - { - 'X-Amz-Invocation-Type': params.InvocationType, - 'Content-Type': 'application/x-amz-json-1.0', - }, - ); + const responseData = await awsApiRequestREST.call( + this, + 'lambda', + 'POST', + `/2015-03-31/functions/${params.FunctionName}/invocations?Qualifier=${params.Qualifier}`, + params.Payload, + { + 'X-Amz-Invocation-Type': params.InvocationType, + 'Content-Type': 'application/x-amz-json-1.0', + }, + ); - if (responseData !== null && responseData.errorMessage !== undefined) { - let errorMessage = responseData.errorMessage; + if (responseData !== null && responseData.errorMessage !== undefined) { + let errorMessage = responseData.errorMessage; - if (responseData.stackTrace) { - errorMessage += `\n\nStack trace:\n${responseData.stackTrace}`; + if (responseData.stackTrace) { + errorMessage += `\n\nStack trace:\n${responseData.stackTrace}`; + } + + throw new NodeApiError(this.getNode(), responseData); + } else { + returnData.push({ + result: responseData, + } as IDataObject); } - - throw new NodeApiError(this.getNode(), responseData); - } else { - returnData.push({ - result: responseData, - } as IDataObject); + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } - } return [this.helpers.returnJsonArray(returnData)]; diff --git a/packages/nodes-base/nodes/Aws/AwsSns.node.ts b/packages/nodes-base/nodes/Aws/AwsSns.node.ts index 9b7e61191f..d43ac2932d 100644 --- a/packages/nodes-base/nodes/Aws/AwsSns.node.ts +++ b/packages/nodes-base/nodes/Aws/AwsSns.node.ts @@ -140,15 +140,23 @@ export class AwsSns implements INodeType { const returnData: IDataObject[] = []; for (let i = 0; i < items.length; i++) { - const params = [ - 'TopicArn=' + this.getNodeParameter('topic', i) as string, - 'Subject=' + this.getNodeParameter('subject', i) as string, - 'Message=' + this.getNodeParameter('message', i) as string, - ]; + try { + const params = [ + 'TopicArn=' + this.getNodeParameter('topic', i) as string, + 'Subject=' + this.getNodeParameter('subject', i) as string, + 'Message=' + this.getNodeParameter('message', i) as string, + ]; - const responseData = await awsApiRequestSOAP.call(this, 'sns', 'GET', '/?Action=Publish&' + params.join('&')); - returnData.push({MessageId: responseData.PublishResponse.PublishResult.MessageId} as IDataObject); + const responseData = await awsApiRequestSOAP.call(this, 'sns', 'GET', '/?Action=Publish&' + params.join('&')); + returnData.push({MessageId: responseData.PublishResponse.PublishResult.MessageId} as IDataObject); + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; + } } return [this.helpers.returnJsonArray(returnData)]; diff --git a/packages/nodes-base/nodes/Aws/Comprehend/AwsComprehend.node.ts b/packages/nodes-base/nodes/Aws/Comprehend/AwsComprehend.node.ts index e611586aa9..f8d3b68447 100644 --- a/packages/nodes-base/nodes/Aws/Comprehend/AwsComprehend.node.ts +++ b/packages/nodes-base/nodes/Aws/Comprehend/AwsComprehend.node.ts @@ -213,63 +213,71 @@ export class AwsComprehend implements INodeType { const resource = this.getNodeParameter('resource', 0) as string; const operation = this.getNodeParameter('operation', 0) as string; for (let i = 0; i < items.length; i++) { - if (resource === 'text') { - //https://docs.aws.amazon.com/comprehend/latest/dg/API_DetectDominantLanguage.html - if (operation === 'detectDominantLanguage') { - const text = this.getNodeParameter('text', i) as string; - const simple = this.getNodeParameter('simple', i) as boolean; + try { + if (resource === 'text') { + //https://docs.aws.amazon.com/comprehend/latest/dg/API_DetectDominantLanguage.html + if (operation === 'detectDominantLanguage') { + const text = this.getNodeParameter('text', i) as string; + const simple = this.getNodeParameter('simple', i) as boolean; - const body: IDataObject = { - Text: text, - }; - const action = 'Comprehend_20171127.DetectDominantLanguage'; - responseData = await awsApiRequestREST.call(this, 'comprehend', 'POST', '', JSON.stringify(body), { 'x-amz-target': action, 'Content-Type': 'application/x-amz-json-1.1' }); + const body: IDataObject = { + Text: text, + }; + const action = 'Comprehend_20171127.DetectDominantLanguage'; + responseData = await awsApiRequestREST.call(this, 'comprehend', 'POST', '', JSON.stringify(body), { 'x-amz-target': action, 'Content-Type': 'application/x-amz-json-1.1' }); - if (simple === true) { - responseData = responseData.Languages.reduce((accumulator: { [key: string]: number }, currentValue: IDataObject) => { - accumulator[currentValue.LanguageCode as string] = currentValue.Score as number; - return accumulator; - }, {}); + if (simple === true) { + responseData = responseData.Languages.reduce((accumulator: { [key: string]: number }, currentValue: IDataObject) => { + accumulator[currentValue.LanguageCode as string] = currentValue.Score as number; + return accumulator; + }, {}); + } + } + + //https://docs.aws.amazon.com/comprehend/latest/dg/API_DetectSentiment.html + if (operation === 'detectSentiment') { + const action = 'Comprehend_20171127.DetectSentiment'; + const text = this.getNodeParameter('text', i) as string; + const languageCode = this.getNodeParameter('languageCode', i) as string; + const body: IDataObject = { + Text: text, + LanguageCode: languageCode, + }; + responseData = await awsApiRequestREST.call(this, 'comprehend', 'POST', '', JSON.stringify(body), { 'x-amz-target': action, 'Content-Type': 'application/x-amz-json-1.1' }); + } + + //https://docs.aws.amazon.com/comprehend/latest/dg/API_DetectEntities.html + if (operation === 'detectEntities') { + const action = 'Comprehend_20171127.DetectEntities'; + const text = this.getNodeParameter('text', i) as string; + const languageCode = this.getNodeParameter('languageCode', i) as string; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + + const body: IDataObject = { + Text: text, + LanguageCode: languageCode, + }; + + if (additionalFields.endpointArn) { + body.EndpointArn = additionalFields.endpointArn; + } + + responseData = await awsApiRequestREST.call(this, 'comprehend', 'POST', '', JSON.stringify(body), { 'x-amz-target': action, 'Content-Type': 'application/x-amz-json-1.1' }); + responseData = responseData.Entities; } } - //https://docs.aws.amazon.com/comprehend/latest/dg/API_DetectSentiment.html - if (operation === 'detectSentiment') { - const action = 'Comprehend_20171127.DetectSentiment'; - const text = this.getNodeParameter('text', i) as string; - const languageCode = this.getNodeParameter('languageCode', i) as string; - const body: IDataObject = { - Text: text, - LanguageCode: languageCode, - }; - responseData = await awsApiRequestREST.call(this, 'comprehend', 'POST', '', JSON.stringify(body), { 'x-amz-target': action, 'Content-Type': 'application/x-amz-json-1.1' }); + if (Array.isArray(responseData)) { + returnData.push.apply(returnData, responseData as IDataObject[]); + } else { + returnData.push(responseData as IDataObject); } - - //https://docs.aws.amazon.com/comprehend/latest/dg/API_DetectEntities.html - if (operation === 'detectEntities') { - const action = 'Comprehend_20171127.DetectEntities'; - const text = this.getNodeParameter('text', i) as string; - const languageCode = this.getNodeParameter('languageCode', i) as string; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - - const body: IDataObject = { - Text: text, - LanguageCode: languageCode, - }; - - if (additionalFields.endpointArn) { - body.EndpointArn = additionalFields.endpointArn; - } - - responseData = await awsApiRequestREST.call(this, 'comprehend', 'POST', '', JSON.stringify(body), { 'x-amz-target': action, 'Content-Type': 'application/x-amz-json-1.1' }); - responseData = responseData.Entities; + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; } - } - - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else { - returnData.push(responseData as IDataObject); + throw error; } } return [this.helpers.returnJsonArray(returnData)]; diff --git a/packages/nodes-base/nodes/Aws/Rekognition/AwsRekognition.node.ts b/packages/nodes-base/nodes/Aws/Rekognition/AwsRekognition.node.ts index afc5dfe875..6583321926 100644 --- a/packages/nodes-base/nodes/Aws/Rekognition/AwsRekognition.node.ts +++ b/packages/nodes-base/nodes/Aws/Rekognition/AwsRekognition.node.ts @@ -383,129 +383,137 @@ export class AwsRekognition implements INodeType { const resource = this.getNodeParameter('resource', 0) as string; const operation = this.getNodeParameter('operation', 0) as string; for (let i = 0; i < items.length; i++) { - if (resource === 'image') { - //https://docs.aws.amazon.com/rekognition/latest/dg/API_DetectModerationLabels.html#API_DetectModerationLabels_RequestSyntax - if (operation === 'analyze') { - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + try { + if (resource === 'image') { + //https://docs.aws.amazon.com/rekognition/latest/dg/API_DetectModerationLabels.html#API_DetectModerationLabels_RequestSyntax + if (operation === 'analyze') { + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - let action = undefined; + let action = undefined; - const body: IDataObject = {}; + const body: IDataObject = {}; - const type = this.getNodeParameter('type', 0) as string; + const type = this.getNodeParameter('type', 0) as string; - if (type === 'detectModerationLabels') { - action = 'RekognitionService.DetectModerationLabels'; + if (type === 'detectModerationLabels') { + action = 'RekognitionService.DetectModerationLabels'; - // property = 'ModerationLabels'; + // property = 'ModerationLabels'; - if (additionalFields.minConfidence) { - body['MinConfidence'] = additionalFields.minConfidence as number; - } - } - - if (type === 'detectFaces') { - action = 'RekognitionService.DetectFaces'; - - // TODO: Add a later point make it possible to activate via option. - // If activated add an index to each of the found faces/tages/... - // to not loose the reference to the image it got found on if - // multilpe ones got supplied. - // property = 'FaceDetails'; - - if (additionalFields.attributes) { - body['Attributes'] = additionalFields.attributes as string; - } - } - - if (type === 'detectLabels') { - action = 'RekognitionService.DetectLabels'; - - if (additionalFields.minConfidence) { - body['MinConfidence'] = additionalFields.minConfidence as number; + if (additionalFields.minConfidence) { + body['MinConfidence'] = additionalFields.minConfidence as number; + } } - if (additionalFields.maxLabels) { - body['MaxLabels'] = additionalFields.maxLabels as number; - } - } + if (type === 'detectFaces') { + action = 'RekognitionService.DetectFaces'; - if (type === 'recognizeCelebrity') { - action = 'RekognitionService.RecognizeCelebrities'; - } + // TODO: Add a later point make it possible to activate via option. + // If activated add an index to each of the found faces/tages/... + // to not loose the reference to the image it got found on if + // multilpe ones got supplied. + // property = 'FaceDetails'; - if (type === 'detectText') { - action = 'RekognitionService.DetectText'; - - body.Filters = {}; - - const box = (additionalFields.regionsOfInterestUi as IDataObject || {}).regionsOfInterestValues as IDataObject[] || []; - - if (box.length !== 0) { - //@ts-ignore - body.Filters.RegionsOfInterest = box.map((box: IDataObject) => { - return { BoundingBox: keysTPascalCase(box) }; - }); + if (additionalFields.attributes) { + body['Attributes'] = additionalFields.attributes as string; + } } - const wordFilter = additionalFields.wordFilterUi as IDataObject || {}; - if (Object.keys(wordFilter).length !== 0) { - //@ts-ignore - body.Filters.WordFilter = keysTPascalCase(wordFilter); - } + if (type === 'detectLabels') { + action = 'RekognitionService.DetectLabels'; - const binaryData = this.getNodeParameter('binaryData', 0) as boolean; - - if (binaryData) { - - const binaryPropertyName = this.getNodeParameter('binaryPropertyName', 0) as string; - - if (items[i].binary === undefined) { - throw new NodeOperationError(this.getNode(), 'No binary data exists on item!'); + if (additionalFields.minConfidence) { + body['MinConfidence'] = additionalFields.minConfidence as number; } - if ((items[i].binary as IBinaryKeyData)[binaryPropertyName] === undefined) { - throw new NodeOperationError(this.getNode(), `No binary data property "${binaryPropertyName}" does not exists on item!`); + if (additionalFields.maxLabels) { + body['MaxLabels'] = additionalFields.maxLabels as number; } + } - const binaryPropertyData = (items[i].binary as IBinaryKeyData)[binaryPropertyName]; + if (type === 'recognizeCelebrity') { + action = 'RekognitionService.RecognizeCelebrities'; + } - Object.assign(body, { - Image: { - Bytes: binaryPropertyData.data, - }, - }); + if (type === 'detectText') { + action = 'RekognitionService.DetectText'; - } else { + body.Filters = {}; - const bucket = this.getNodeParameter('bucket', i) as string; + const box = (additionalFields.regionsOfInterestUi as IDataObject || {}).regionsOfInterestValues as IDataObject[] || []; - const name = this.getNodeParameter('name', i) as string; - - Object.assign(body, { - Image: { - S3Object: { - Bucket: bucket, - Name: name, - }, - }, - }); - - if (additionalFields.version) { + if (box.length !== 0) { //@ts-ignore - body.Image.S3Object.Version = additionalFields.version as string; + body.Filters.RegionsOfInterest = box.map((box: IDataObject) => { + return { BoundingBox: keysTPascalCase(box) }; + }); } + + const wordFilter = additionalFields.wordFilterUi as IDataObject || {}; + if (Object.keys(wordFilter).length !== 0) { + //@ts-ignore + body.Filters.WordFilter = keysTPascalCase(wordFilter); + } + + const binaryData = this.getNodeParameter('binaryData', 0) as boolean; + + if (binaryData) { + + const binaryPropertyName = this.getNodeParameter('binaryPropertyName', 0) as string; + + if (items[i].binary === undefined) { + throw new NodeOperationError(this.getNode(), 'No binary data exists on item!'); + } + + if ((items[i].binary as IBinaryKeyData)[binaryPropertyName] === undefined) { + throw new NodeOperationError(this.getNode(), `No binary data property "${binaryPropertyName}" does not exists on item!`); + } + + const binaryPropertyData = (items[i].binary as IBinaryKeyData)[binaryPropertyName]; + + Object.assign(body, { + Image: { + Bytes: binaryPropertyData.data, + }, + }); + + } else { + + const bucket = this.getNodeParameter('bucket', i) as string; + + const name = this.getNodeParameter('name', i) as string; + + Object.assign(body, { + Image: { + S3Object: { + Bucket: bucket, + Name: name, + }, + }, + }); + + if (additionalFields.version) { + //@ts-ignore + body.Image.S3Object.Version = additionalFields.version as string; + } + } + + responseData = await awsApiRequestREST.call(this, 'rekognition', 'POST', '', JSON.stringify(body), {}, { 'X-Amz-Target': action, 'Content-Type': 'application/x-amz-json-1.1' }); + } - - responseData = await awsApiRequestREST.call(this, 'rekognition', 'POST', '', JSON.stringify(body), {}, { 'X-Amz-Target': action, 'Content-Type': 'application/x-amz-json-1.1' }); - } } - } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else { - returnData.push(responseData); + if (Array.isArray(responseData)) { + returnData.push.apply(returnData, responseData as IDataObject[]); + } else { + returnData.push(responseData); + } + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } } return [this.helpers.returnJsonArray(returnData)]; diff --git a/packages/nodes-base/nodes/Aws/S3/AwsS3.node.ts b/packages/nodes-base/nodes/Aws/S3/AwsS3.node.ts index c20a37da2c..65cc1f3c1c 100644 --- a/packages/nodes-base/nodes/Aws/S3/AwsS3.node.ts +++ b/packages/nodes-base/nodes/Aws/S3/AwsS3.node.ts @@ -111,524 +111,532 @@ export class AwsS3 implements INodeType { const operation = this.getNodeParameter('operation', 0) as string; for (let i = 0; i < items.length; i++) { const headers: IDataObject = {}; - if (resource === 'bucket') { - //https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateBucket.html - if (operation === 'create') { - const credentials = this.getCredentials('aws'); - const name = this.getNodeParameter('name', i) as string; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - if (additionalFields.acl) { - headers['x-amz-acl'] = paramCase(additionalFields.acl as string); - } - if (additionalFields.bucketObjectLockEnabled) { - headers['x-amz-bucket-object-lock-enabled'] = additionalFields.bucketObjectLockEnabled as boolean; - } - if (additionalFields.grantFullControl) { - headers['x-amz-grant-full-control'] = ''; - } - if (additionalFields.grantRead) { - headers['x-amz-grant-read'] = ''; - } - if (additionalFields.grantReadAcp) { - headers['x-amz-grant-read-acp'] = ''; - } - if (additionalFields.grantWrite) { - headers['x-amz-grant-write'] = ''; - } - if (additionalFields.grantWriteAcp) { - headers['x-amz-grant-write-acp'] = ''; - } - let region = credentials!.region as string; + try { + if (resource === 'bucket') { + //https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateBucket.html + if (operation === 'create') { + const credentials = this.getCredentials('aws'); + const name = this.getNodeParameter('name', i) as string; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + if (additionalFields.acl) { + headers['x-amz-acl'] = paramCase(additionalFields.acl as string); + } + if (additionalFields.bucketObjectLockEnabled) { + headers['x-amz-bucket-object-lock-enabled'] = additionalFields.bucketObjectLockEnabled as boolean; + } + if (additionalFields.grantFullControl) { + headers['x-amz-grant-full-control'] = ''; + } + if (additionalFields.grantRead) { + headers['x-amz-grant-read'] = ''; + } + if (additionalFields.grantReadAcp) { + headers['x-amz-grant-read-acp'] = ''; + } + if (additionalFields.grantWrite) { + headers['x-amz-grant-write'] = ''; + } + if (additionalFields.grantWriteAcp) { + headers['x-amz-grant-write-acp'] = ''; + } + let region = credentials!.region as string; - if (additionalFields.region) { - region = additionalFields.region as string; - } + if (additionalFields.region) { + region = additionalFields.region as string; + } - const body: IDataObject = { - CreateBucketConfiguration: { - '$': { - xmlns: 'http://s3.amazonaws.com/doc/2006-03-01/', - }, - }, - }; - let data = ''; - // if credentials has the S3 defaul region (us-east-1) the body (XML) does not have to be sent. - if (region !== 'us-east-1') { - // @ts-ignore - body.CreateBucketConfiguration.LocationConstraint = [region]; - const builder = new Builder(); - data = builder.buildObject(body); - } - responseData = await awsApiRequestSOAP.call(this, `${name}.s3`, 'PUT', '', data, qs, headers); - - returnData.push({ success: true }); - } - - // https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucket.html - if (operation === 'delete') { - const name = this.getNodeParameter('name', i) as string; - - responseData = await awsApiRequestSOAP.call(this, `${name}.s3`, 'DELETE', '', '', {}, headers); - returnData.push({ success: true }); - } - - //https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListBuckets.html - if (operation === 'getAll') { - const returnAll = this.getNodeParameter('returnAll', 0) as boolean; - if (returnAll) { - responseData = await awsApiRequestSOAPAllItems.call(this, 'ListAllMyBucketsResult.Buckets.Bucket', 's3', 'GET', ''); - } else { - qs.limit = this.getNodeParameter('limit', 0) as number; - responseData = await awsApiRequestSOAPAllItems.call(this, 'ListAllMyBucketsResult.Buckets.Bucket', 's3', 'GET', '', '', qs); - responseData = responseData.slice(0, qs.limit); - } - returnData.push.apply(returnData, responseData); - } - - //https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListObjectsV2.html - if (operation === 'search') { - const bucketName = this.getNodeParameter('bucketName', i) as string; - const returnAll = this.getNodeParameter('returnAll', 0) as boolean; - const additionalFields = this.getNodeParameter('additionalFields', 0) as IDataObject; - - if (additionalFields.prefix) { - qs['prefix'] = additionalFields.prefix as string; - } - - if (additionalFields.encodingType) { - qs['encoding-type'] = additionalFields.encodingType as string; - } - - if (additionalFields.delmiter) { - qs['delimiter'] = additionalFields.delmiter as string; - } - - if (additionalFields.fetchOwner) { - qs['fetch-owner'] = additionalFields.fetchOwner as string; - } - - if (additionalFields.startAfter) { - qs['start-after'] = additionalFields.startAfter as string; - } - - if (additionalFields.requesterPays) { - qs['x-amz-request-payer'] = 'requester'; - } - - qs['list-type'] = 2; - - - responseData = await awsApiRequestSOAP.call(this, `${bucketName}.s3`, 'GET', '', '', { location: '' }); - - const region = responseData.LocationConstraint._ as string; - - if (returnAll) { - responseData = await awsApiRequestSOAPAllItems.call(this, 'ListBucketResult.Contents', `${bucketName}.s3`, 'GET', '', '', qs, {}, {}, region); - } else { - qs['max-keys'] = this.getNodeParameter('limit', 0) as number; - responseData = await awsApiRequestSOAP.call(this, `${bucketName}.s3`, 'GET', '', '', qs, {}, {}, region); - responseData = responseData.ListBucketResult.Contents; - } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData); - } else { - returnData.push(responseData); - } - } - } - if (resource === 'folder') { - //https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html - if (operation === 'create') { - const bucketName = this.getNodeParameter('bucketName', i) as string; - const folderName = this.getNodeParameter('folderName', i) as string; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - let path = `/${folderName}/`; - - if (additionalFields.requesterPays) { - headers['x-amz-request-payer'] = 'requester'; - } - if (additionalFields.parentFolderKey) { - path = `/${additionalFields.parentFolderKey}${folderName}/`; - } - if (additionalFields.storageClass) { - headers['x-amz-storage-class'] = (snakeCase(additionalFields.storageClass as string)).toUpperCase(); - } - responseData = await awsApiRequestSOAP.call(this, `${bucketName}.s3`, 'GET', '', '', { location: '' }); - - const region = responseData.LocationConstraint._; - - responseData = await awsApiRequestSOAP.call(this, `${bucketName}.s3`, 'PUT', path, '', qs, headers, {}, region); - returnData.push({ success: true }); - } - //https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteObjects.html - if (operation === 'delete') { - const bucketName = this.getNodeParameter('bucketName', i) as string; - const folderKey = this.getNodeParameter('folderKey', i) as string; - - responseData = await awsApiRequestSOAP.call(this, `${bucketName}.s3`, 'GET', '', '', { location: '' }); - - const region = responseData.LocationConstraint._; - - responseData = await awsApiRequestSOAPAllItems.call(this, 'ListBucketResult.Contents', `${bucketName}.s3`, 'GET', '/', '', { 'list-type': 2, prefix: folderKey }, {}, {}, region); - - // folder empty then just delete it - if (responseData.length === 0) { - - responseData = await awsApiRequestSOAP.call(this, `${bucketName}.s3`, 'DELETE', `/${folderKey}`, '', qs, {}, {}, region); - - responseData = { deleted: [ { 'Key': folderKey } ] }; - - } else { - // delete everything inside the folder const body: IDataObject = { - Delete: { + CreateBucketConfiguration: { '$': { xmlns: 'http://s3.amazonaws.com/doc/2006-03-01/', }, - Object: [], }, }; - - for (const childObject of responseData) { - //@ts-ignore - (body.Delete.Object as IDataObject[]).push({ - Key: childObject.Key as string, - }); + let data = ''; + // if credentials has the S3 defaul region (us-east-1) the body (XML) does not have to be sent. + if (region !== 'us-east-1') { + // @ts-ignore + body.CreateBucketConfiguration.LocationConstraint = [region]; + const builder = new Builder(); + data = builder.buildObject(body); } + responseData = await awsApiRequestSOAP.call(this, `${name}.s3`, 'PUT', '', data, qs, headers); - const builder = new Builder(); - const data = builder.buildObject(body); - - headers['Content-MD5'] = createHash('md5').update(data).digest('base64'); - - headers['Content-Type'] = 'application/xml'; - - responseData = await awsApiRequestSOAP.call(this, `${bucketName}.s3`, 'POST', '/', data, { delete: '' } , headers, {}, region); - - responseData = { deleted: responseData.DeleteResult.Deleted }; - } - returnData.push(responseData); - } - //https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListObjectsV2.html - if (operation === 'getAll') { - const bucketName = this.getNodeParameter('bucketName', i) as string; - const returnAll = this.getNodeParameter('returnAll', 0) as boolean; - const options = this.getNodeParameter('options', 0) as IDataObject; - - if (options.folderKey) { - qs['prefix'] = options.folderKey as string; + returnData.push({ success: true }); } - if (options.fetchOwner) { - qs['fetch-owner'] = options.fetchOwner as string; + // https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucket.html + if (operation === 'delete') { + const name = this.getNodeParameter('name', i) as string; + + responseData = await awsApiRequestSOAP.call(this, `${name}.s3`, 'DELETE', '', '', {}, headers); + returnData.push({ success: true }); } - qs['list-type'] = 2; - - responseData = await awsApiRequestSOAP.call(this, `${bucketName}.s3`, 'GET', '', '', { location: '' }); - - const region = responseData.LocationConstraint._; - - if (returnAll) { - responseData = await awsApiRequestSOAPAllItems.call(this, 'ListBucketResult.Contents', `${bucketName}.s3`, 'GET', '', '', qs, {}, {}, region); - } else { - qs.limit = this.getNodeParameter('limit', 0) as number; - responseData = await awsApiRequestSOAPAllItems.call(this, 'ListBucketResult.Contents', `${bucketName}.s3`, 'GET', '', '', qs, {}, {}, region); - } - if (Array.isArray(responseData)) { - responseData = responseData.filter((e: IDataObject) => (e.Key as string).endsWith('/') && e.Size === '0' && e.Key !== options.folderKey); - if (qs.limit) { - responseData = responseData.splice(0, qs.limit as number); + //https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListBuckets.html + if (operation === 'getAll') { + const returnAll = this.getNodeParameter('returnAll', 0) as boolean; + if (returnAll) { + responseData = await awsApiRequestSOAPAllItems.call(this, 'ListAllMyBucketsResult.Buckets.Bucket', 's3', 'GET', ''); + } else { + qs.limit = this.getNodeParameter('limit', 0) as number; + responseData = await awsApiRequestSOAPAllItems.call(this, 'ListAllMyBucketsResult.Buckets.Bucket', 's3', 'GET', '', '', qs); + responseData = responseData.slice(0, qs.limit); } returnData.push.apply(returnData, responseData); } - } - } - if (resource === 'file') { - //https://docs.aws.amazon.com/AmazonS3/latest/API/API_CopyObject.html - if (operation === 'copy') { - const sourcePath = this.getNodeParameter('sourcePath', i) as string; - const destinationPath = this.getNodeParameter('destinationPath', i) as string; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - headers['x-amz-copy-source'] = sourcePath; + //https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListObjectsV2.html + if (operation === 'search') { + const bucketName = this.getNodeParameter('bucketName', i) as string; + const returnAll = this.getNodeParameter('returnAll', 0) as boolean; + const additionalFields = this.getNodeParameter('additionalFields', 0) as IDataObject; - if (additionalFields.requesterPays) { - headers['x-amz-request-payer'] = 'requester'; - } - if (additionalFields.storageClass) { - headers['x-amz-storage-class'] = (snakeCase(additionalFields.storageClass as string)).toUpperCase(); - } - if (additionalFields.acl) { - headers['x-amz-acl'] = paramCase(additionalFields.acl as string); - } - if (additionalFields.grantFullControl) { - headers['x-amz-grant-full-control'] = ''; - } - if (additionalFields.grantRead) { - headers['x-amz-grant-read'] = ''; - } - if (additionalFields.grantReadAcp) { - headers['x-amz-grant-read-acp'] = ''; - } - if (additionalFields.grantWriteAcp) { - headers['x-amz-grant-write-acp'] = ''; - } - if (additionalFields.lockLegalHold) { - headers['x-amz-object-lock-legal-hold'] = (additionalFields.lockLegalHold as boolean) ? 'ON' : 'OFF'; - } - if (additionalFields.lockMode) { - headers['x-amz-object-lock-mode'] = (additionalFields.lockMode as string).toUpperCase(); - } - if (additionalFields.lockRetainUntilDate) { - headers['x-amz-object-lock-retain-until-date'] = additionalFields.lockRetainUntilDate as string; - } - if (additionalFields.serverSideEncryption) { - headers['x-amz-server-side-encryption'] = additionalFields.serverSideEncryption as string; - } - if (additionalFields.encryptionAwsKmsKeyId) { - headers['x-amz-server-side-encryption-aws-kms-key-id'] = additionalFields.encryptionAwsKmsKeyId as string; - } - if (additionalFields.serverSideEncryptionContext) { - headers['x-amz-server-side-encryption-context'] = additionalFields.serverSideEncryptionContext as string; - } - if (additionalFields.serversideEncryptionCustomerAlgorithm) { - headers['x-amz-server-side-encryption-customer-algorithm'] = additionalFields.serversideEncryptionCustomerAlgorithm as string; - } - if (additionalFields.serversideEncryptionCustomerKey) { - headers['x-amz-server-side-encryption-customer-key'] = additionalFields.serversideEncryptionCustomerKey as string; - } - if (additionalFields.serversideEncryptionCustomerKeyMD5) { - headers['x-amz-server-side-encryption-customer-key-MD5'] = additionalFields.serversideEncryptionCustomerKeyMD5 as string; - } - if (additionalFields.taggingDirective) { - headers['x-amz-tagging-directive'] = (additionalFields.taggingDirective as string).toUpperCase(); - } - if (additionalFields.metadataDirective) { - headers['x-amz-metadata-directive'] = (additionalFields.metadataDirective as string).toUpperCase(); - } - - const destinationParts = destinationPath.split('/'); - - const bucketName = destinationParts[1]; - - const destination = `/${destinationParts.slice(2, destinationParts.length).join('/')}`; - - responseData = await awsApiRequestSOAP.call(this, `${bucketName}.s3`, 'GET', '', '', { location: '' }); - - const region = responseData.LocationConstraint._; - - responseData = await awsApiRequestSOAP.call(this, `${bucketName}.s3`, 'PUT', destination, '', qs, headers, {}, region); - returnData.push(responseData.CopyObjectResult); - - } - //https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObject.html - if (operation === 'download') { - - const bucketName = this.getNodeParameter('bucketName', i) as string; - - const fileKey = this.getNodeParameter('fileKey', i) as string; - - const fileName = fileKey.split('/')[fileKey.split('/').length - 1]; - - if (fileKey.substring(fileKey.length - 1) === '/') { - throw new NodeOperationError(this.getNode(), 'Downloding a whole directory is not yet supported, please provide a file key'); - } - - let region = await awsApiRequestSOAP.call(this, `${bucketName}.s3`, 'GET', '', '', { location: '' }); - - region = region.LocationConstraint._; - - const response = await awsApiRequestREST.call(this, `${bucketName}.s3`, 'GET', `/${fileKey}`, '', qs, {}, { encoding: null, resolveWithFullResponse: true }, region); - - let mimeType: string | undefined; - if (response.headers['content-type']) { - mimeType = response.headers['content-type']; - } - - const newItem: INodeExecutionData = { - json: items[i].json, - binary: {}, - }; - - if (items[i].binary !== undefined) { - // Create a shallow copy of the binary data so that the old - // data references which do not get changed still stay behind - // but the incoming data does not get changed. - Object.assign(newItem.binary, items[i].binary); - } - - items[i] = newItem; - - const dataPropertyNameDownload = this.getNodeParameter('binaryPropertyName', i) as string; - - const data = Buffer.from(response.body as string, 'utf8'); - - items[i].binary![dataPropertyNameDownload] = await this.helpers.prepareBinaryData(data as unknown as Buffer, fileName, mimeType); - } - //https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteObject.html - if (operation === 'delete') { - const bucketName = this.getNodeParameter('bucketName', i) as string; - - const fileKey = this.getNodeParameter('fileKey', i) as string; - - const options = this.getNodeParameter('options', i) as IDataObject; - - if (options.versionId) { - qs.versionId = options.versionId as string; - } - - responseData = await awsApiRequestSOAP.call(this, `${bucketName}.s3`, 'GET', '', '', { location: '' }); - - const region = responseData.LocationConstraint._; - - responseData = await awsApiRequestSOAP.call(this, `${bucketName}.s3`, 'DELETE', `/${fileKey}`, '', qs, {}, {}, region); - - returnData.push({ success: true }); - } - //https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListObjectsV2.html - if (operation === 'getAll') { - const bucketName = this.getNodeParameter('bucketName', i) as string; - const returnAll = this.getNodeParameter('returnAll', 0) as boolean; - const options = this.getNodeParameter('options', 0) as IDataObject; - - if (options.folderKey) { - qs['prefix'] = options.folderKey as string; - } - - if (options.fetchOwner) { - qs['fetch-owner'] = options.fetchOwner as string; - } - - qs['delimiter'] = '/'; - - qs['list-type'] = 2; - - responseData = await awsApiRequestSOAP.call(this, `${bucketName}.s3`, 'GET', '', '', { location: '' }); - - const region = responseData.LocationConstraint._; - - if (returnAll) { - responseData = await awsApiRequestSOAPAllItems.call(this, 'ListBucketResult.Contents', `${bucketName}.s3`, 'GET', '', '', qs, {}, {}, region); - } else { - qs.limit = this.getNodeParameter('limit', 0) as number; - responseData = await awsApiRequestSOAPAllItems.call(this, 'ListBucketResult.Contents', `${bucketName}.s3`, 'GET', '', '', qs, {}, {}, region); - responseData = responseData.splice(0, qs.limit); - } - if (Array.isArray(responseData)) { - responseData = responseData.filter((e: IDataObject) => !(e.Key as string).endsWith('/') && e.Size !== '0'); - if (qs.limit) { - responseData = responseData.splice(0, qs.limit as number); - } - returnData.push.apply(returnData, responseData); - } - } - //https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html - if (operation === 'upload') { - const bucketName = this.getNodeParameter('bucketName', i) as string; - const fileName = this.getNodeParameter('fileName', i) as string; - const isBinaryData = this.getNodeParameter('binaryData', i) as boolean; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const tagsValues = (this.getNodeParameter('tagsUi', i) as IDataObject).tagsValues as IDataObject[]; - let path = '/'; - let body; - - if (additionalFields.requesterPays) { - headers['x-amz-request-payer'] = 'requester'; - } - if (additionalFields.parentFolderKey) { - path = `/${additionalFields.parentFolderKey}/`; - } - if (additionalFields.storageClass) { - headers['x-amz-storage-class'] = (snakeCase(additionalFields.storageClass as string)).toUpperCase(); - } - if (additionalFields.acl) { - headers['x-amz-acl'] = paramCase(additionalFields.acl as string); - } - if (additionalFields.grantFullControl) { - headers['x-amz-grant-full-control'] = ''; - } - if (additionalFields.grantRead) { - headers['x-amz-grant-read'] = ''; - } - if (additionalFields.grantReadAcp) { - headers['x-amz-grant-read-acp'] = ''; - } - if (additionalFields.grantWriteAcp) { - headers['x-amz-grant-write-acp'] = ''; - } - if (additionalFields.lockLegalHold) { - headers['x-amz-object-lock-legal-hold'] = (additionalFields.lockLegalHold as boolean) ? 'ON' : 'OFF'; - } - if (additionalFields.lockMode) { - headers['x-amz-object-lock-mode'] = (additionalFields.lockMode as string).toUpperCase(); - } - if (additionalFields.lockRetainUntilDate) { - headers['x-amz-object-lock-retain-until-date'] = additionalFields.lockRetainUntilDate as string; - } - if (additionalFields.serverSideEncryption) { - headers['x-amz-server-side-encryption'] = additionalFields.serverSideEncryption as string; - } - if (additionalFields.encryptionAwsKmsKeyId) { - headers['x-amz-server-side-encryption-aws-kms-key-id'] = additionalFields.encryptionAwsKmsKeyId as string; - } - if (additionalFields.serverSideEncryptionContext) { - headers['x-amz-server-side-encryption-context'] = additionalFields.serverSideEncryptionContext as string; - } - if (additionalFields.serversideEncryptionCustomerAlgorithm) { - headers['x-amz-server-side-encryption-customer-algorithm'] = additionalFields.serversideEncryptionCustomerAlgorithm as string; - } - if (additionalFields.serversideEncryptionCustomerKey) { - headers['x-amz-server-side-encryption-customer-key'] = additionalFields.serversideEncryptionCustomerKey as string; - } - if (additionalFields.serversideEncryptionCustomerKeyMD5) { - headers['x-amz-server-side-encryption-customer-key-MD5'] = additionalFields.serversideEncryptionCustomerKeyMD5 as string; - } - if (tagsValues) { - const tags: string[] = []; - tagsValues.forEach((o: IDataObject) => { tags.push(`${o.key}=${o.value}`); }); - headers['x-amz-tagging'] = tags.join('&'); - } - - responseData = await awsApiRequestSOAP.call(this, `${bucketName}.s3`, 'GET', '', '', { location: '' }); - - const region = responseData.LocationConstraint._; - - if (isBinaryData) { - const binaryPropertyName = this.getNodeParameter('binaryPropertyName', 0) as string; - - if (items[i].binary === undefined) { - throw new NodeOperationError(this.getNode(), 'No binary data exists on item!'); + if (additionalFields.prefix) { + qs['prefix'] = additionalFields.prefix as string; } - if ((items[i].binary as IBinaryKeyData)[binaryPropertyName] === undefined) { - throw new NodeOperationError(this.getNode(), `No binary data property "${binaryPropertyName}" does not exists on item!`); + if (additionalFields.encodingType) { + qs['encoding-type'] = additionalFields.encodingType as string; } - const binaryData = (items[i].binary as IBinaryKeyData)[binaryPropertyName]; + if (additionalFields.delmiter) { + qs['delimiter'] = additionalFields.delmiter as string; + } - body = Buffer.from(binaryData.data, BINARY_ENCODING) as Buffer; + if (additionalFields.fetchOwner) { + qs['fetch-owner'] = additionalFields.fetchOwner as string; + } - headers['Content-Type'] = binaryData.mimeType; + if (additionalFields.startAfter) { + qs['start-after'] = additionalFields.startAfter as string; + } - headers['Content-MD5'] = createHash('md5').update(body).digest('base64'); + if (additionalFields.requesterPays) { + qs['x-amz-request-payer'] = 'requester'; + } - responseData = await awsApiRequestSOAP.call(this, `${bucketName}.s3`, 'PUT', `${path}${fileName || binaryData.fileName}`, body, qs, headers, {}, region); + qs['list-type'] = 2; - } else { - const fileContent = this.getNodeParameter('fileContent', i) as string; + responseData = await awsApiRequestSOAP.call(this, `${bucketName}.s3`, 'GET', '', '', { location: '' }); - body = Buffer.from(fileContent, 'utf8'); + const region = responseData.LocationConstraint._ as string; - headers['Content-Type'] = 'text/html'; - - headers['Content-MD5'] = createHash('md5').update(fileContent).digest('base64'); - - responseData = await awsApiRequestSOAP.call(this, `${bucketName}.s3`, 'PUT', `${path}${fileName}`, body, qs, headers, {}, region); + if (returnAll) { + responseData = await awsApiRequestSOAPAllItems.call(this, 'ListBucketResult.Contents', `${bucketName}.s3`, 'GET', '', '', qs, {}, {}, region); + } else { + qs['max-keys'] = this.getNodeParameter('limit', 0) as number; + responseData = await awsApiRequestSOAP.call(this, `${bucketName}.s3`, 'GET', '', '', qs, {}, {}, region); + responseData = responseData.ListBucketResult.Contents; + } + if (Array.isArray(responseData)) { + returnData.push.apply(returnData, responseData); + } else { + returnData.push(responseData); + } } - returnData.push({ success: true }); } + if (resource === 'folder') { + //https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html + if (operation === 'create') { + const bucketName = this.getNodeParameter('bucketName', i) as string; + const folderName = this.getNodeParameter('folderName', i) as string; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + let path = `/${folderName}/`; + + if (additionalFields.requesterPays) { + headers['x-amz-request-payer'] = 'requester'; + } + if (additionalFields.parentFolderKey) { + path = `/${additionalFields.parentFolderKey}${folderName}/`; + } + if (additionalFields.storageClass) { + headers['x-amz-storage-class'] = (snakeCase(additionalFields.storageClass as string)).toUpperCase(); + } + responseData = await awsApiRequestSOAP.call(this, `${bucketName}.s3`, 'GET', '', '', { location: '' }); + + const region = responseData.LocationConstraint._; + + responseData = await awsApiRequestSOAP.call(this, `${bucketName}.s3`, 'PUT', path, '', qs, headers, {}, region); + returnData.push({ success: true }); + } + //https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteObjects.html + if (operation === 'delete') { + const bucketName = this.getNodeParameter('bucketName', i) as string; + const folderKey = this.getNodeParameter('folderKey', i) as string; + + responseData = await awsApiRequestSOAP.call(this, `${bucketName}.s3`, 'GET', '', '', { location: '' }); + + const region = responseData.LocationConstraint._; + + responseData = await awsApiRequestSOAPAllItems.call(this, 'ListBucketResult.Contents', `${bucketName}.s3`, 'GET', '/', '', { 'list-type': 2, prefix: folderKey }, {}, {}, region); + + // folder empty then just delete it + if (responseData.length === 0) { + + responseData = await awsApiRequestSOAP.call(this, `${bucketName}.s3`, 'DELETE', `/${folderKey}`, '', qs, {}, {}, region); + + responseData = { deleted: [ { 'Key': folderKey } ] }; + + } else { + // delete everything inside the folder + const body: IDataObject = { + Delete: { + '$': { + xmlns: 'http://s3.amazonaws.com/doc/2006-03-01/', + }, + Object: [], + }, + }; + + for (const childObject of responseData) { + //@ts-ignore + (body.Delete.Object as IDataObject[]).push({ + Key: childObject.Key as string, + }); + } + + const builder = new Builder(); + const data = builder.buildObject(body); + + headers['Content-MD5'] = createHash('md5').update(data).digest('base64'); + + headers['Content-Type'] = 'application/xml'; + + responseData = await awsApiRequestSOAP.call(this, `${bucketName}.s3`, 'POST', '/', data, { delete: '' } , headers, {}, region); + + responseData = { deleted: responseData.DeleteResult.Deleted }; + } + returnData.push(responseData); + } + //https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListObjectsV2.html + if (operation === 'getAll') { + const bucketName = this.getNodeParameter('bucketName', i) as string; + const returnAll = this.getNodeParameter('returnAll', 0) as boolean; + const options = this.getNodeParameter('options', 0) as IDataObject; + + if (options.folderKey) { + qs['prefix'] = options.folderKey as string; + } + + if (options.fetchOwner) { + qs['fetch-owner'] = options.fetchOwner as string; + } + + qs['list-type'] = 2; + + responseData = await awsApiRequestSOAP.call(this, `${bucketName}.s3`, 'GET', '', '', { location: '' }); + + const region = responseData.LocationConstraint._; + + if (returnAll) { + responseData = await awsApiRequestSOAPAllItems.call(this, 'ListBucketResult.Contents', `${bucketName}.s3`, 'GET', '', '', qs, {}, {}, region); + } else { + qs.limit = this.getNodeParameter('limit', 0) as number; + responseData = await awsApiRequestSOAPAllItems.call(this, 'ListBucketResult.Contents', `${bucketName}.s3`, 'GET', '', '', qs, {}, {}, region); + } + if (Array.isArray(responseData)) { + responseData = responseData.filter((e: IDataObject) => (e.Key as string).endsWith('/') && e.Size === '0' && e.Key !== options.folderKey); + if (qs.limit) { + responseData = responseData.splice(0, qs.limit as number); + } + returnData.push.apply(returnData, responseData); + } + } + } + if (resource === 'file') { + //https://docs.aws.amazon.com/AmazonS3/latest/API/API_CopyObject.html + if (operation === 'copy') { + const sourcePath = this.getNodeParameter('sourcePath', i) as string; + const destinationPath = this.getNodeParameter('destinationPath', i) as string; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + + headers['x-amz-copy-source'] = sourcePath; + + if (additionalFields.requesterPays) { + headers['x-amz-request-payer'] = 'requester'; + } + if (additionalFields.storageClass) { + headers['x-amz-storage-class'] = (snakeCase(additionalFields.storageClass as string)).toUpperCase(); + } + if (additionalFields.acl) { + headers['x-amz-acl'] = paramCase(additionalFields.acl as string); + } + if (additionalFields.grantFullControl) { + headers['x-amz-grant-full-control'] = ''; + } + if (additionalFields.grantRead) { + headers['x-amz-grant-read'] = ''; + } + if (additionalFields.grantReadAcp) { + headers['x-amz-grant-read-acp'] = ''; + } + if (additionalFields.grantWriteAcp) { + headers['x-amz-grant-write-acp'] = ''; + } + if (additionalFields.lockLegalHold) { + headers['x-amz-object-lock-legal-hold'] = (additionalFields.lockLegalHold as boolean) ? 'ON' : 'OFF'; + } + if (additionalFields.lockMode) { + headers['x-amz-object-lock-mode'] = (additionalFields.lockMode as string).toUpperCase(); + } + if (additionalFields.lockRetainUntilDate) { + headers['x-amz-object-lock-retain-until-date'] = additionalFields.lockRetainUntilDate as string; + } + if (additionalFields.serverSideEncryption) { + headers['x-amz-server-side-encryption'] = additionalFields.serverSideEncryption as string; + } + if (additionalFields.encryptionAwsKmsKeyId) { + headers['x-amz-server-side-encryption-aws-kms-key-id'] = additionalFields.encryptionAwsKmsKeyId as string; + } + if (additionalFields.serverSideEncryptionContext) { + headers['x-amz-server-side-encryption-context'] = additionalFields.serverSideEncryptionContext as string; + } + if (additionalFields.serversideEncryptionCustomerAlgorithm) { + headers['x-amz-server-side-encryption-customer-algorithm'] = additionalFields.serversideEncryptionCustomerAlgorithm as string; + } + if (additionalFields.serversideEncryptionCustomerKey) { + headers['x-amz-server-side-encryption-customer-key'] = additionalFields.serversideEncryptionCustomerKey as string; + } + if (additionalFields.serversideEncryptionCustomerKeyMD5) { + headers['x-amz-server-side-encryption-customer-key-MD5'] = additionalFields.serversideEncryptionCustomerKeyMD5 as string; + } + if (additionalFields.taggingDirective) { + headers['x-amz-tagging-directive'] = (additionalFields.taggingDirective as string).toUpperCase(); + } + if (additionalFields.metadataDirective) { + headers['x-amz-metadata-directive'] = (additionalFields.metadataDirective as string).toUpperCase(); + } + + const destinationParts = destinationPath.split('/'); + + const bucketName = destinationParts[1]; + + const destination = `/${destinationParts.slice(2, destinationParts.length).join('/')}`; + + responseData = await awsApiRequestSOAP.call(this, `${bucketName}.s3`, 'GET', '', '', { location: '' }); + + const region = responseData.LocationConstraint._; + + responseData = await awsApiRequestSOAP.call(this, `${bucketName}.s3`, 'PUT', destination, '', qs, headers, {}, region); + returnData.push(responseData.CopyObjectResult); + + } + //https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObject.html + if (operation === 'download') { + + const bucketName = this.getNodeParameter('bucketName', i) as string; + + const fileKey = this.getNodeParameter('fileKey', i) as string; + + const fileName = fileKey.split('/')[fileKey.split('/').length - 1]; + + if (fileKey.substring(fileKey.length - 1) === '/') { + throw new NodeOperationError(this.getNode(), 'Downloding a whole directory is not yet supported, please provide a file key'); + } + + let region = await awsApiRequestSOAP.call(this, `${bucketName}.s3`, 'GET', '', '', { location: '' }); + + region = region.LocationConstraint._; + + const response = await awsApiRequestREST.call(this, `${bucketName}.s3`, 'GET', `/${fileKey}`, '', qs, {}, { encoding: null, resolveWithFullResponse: true }, region); + + let mimeType: string | undefined; + if (response.headers['content-type']) { + mimeType = response.headers['content-type']; + } + + const newItem: INodeExecutionData = { + json: items[i].json, + binary: {}, + }; + + if (items[i].binary !== undefined) { + // Create a shallow copy of the binary data so that the old + // data references which do not get changed still stay behind + // but the incoming data does not get changed. + Object.assign(newItem.binary, items[i].binary); + } + + items[i] = newItem; + + const dataPropertyNameDownload = this.getNodeParameter('binaryPropertyName', i) as string; + + const data = Buffer.from(response.body as string, 'utf8'); + + items[i].binary![dataPropertyNameDownload] = await this.helpers.prepareBinaryData(data as unknown as Buffer, fileName, mimeType); + } + //https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteObject.html + if (operation === 'delete') { + const bucketName = this.getNodeParameter('bucketName', i) as string; + + const fileKey = this.getNodeParameter('fileKey', i) as string; + + const options = this.getNodeParameter('options', i) as IDataObject; + + if (options.versionId) { + qs.versionId = options.versionId as string; + } + + responseData = await awsApiRequestSOAP.call(this, `${bucketName}.s3`, 'GET', '', '', { location: '' }); + + const region = responseData.LocationConstraint._; + + responseData = await awsApiRequestSOAP.call(this, `${bucketName}.s3`, 'DELETE', `/${fileKey}`, '', qs, {}, {}, region); + + returnData.push({ success: true }); + } + //https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListObjectsV2.html + if (operation === 'getAll') { + const bucketName = this.getNodeParameter('bucketName', i) as string; + const returnAll = this.getNodeParameter('returnAll', 0) as boolean; + const options = this.getNodeParameter('options', 0) as IDataObject; + + if (options.folderKey) { + qs['prefix'] = options.folderKey as string; + } + + if (options.fetchOwner) { + qs['fetch-owner'] = options.fetchOwner as string; + } + + qs['delimiter'] = '/'; + + qs['list-type'] = 2; + + responseData = await awsApiRequestSOAP.call(this, `${bucketName}.s3`, 'GET', '', '', { location: '' }); + + const region = responseData.LocationConstraint._; + + if (returnAll) { + responseData = await awsApiRequestSOAPAllItems.call(this, 'ListBucketResult.Contents', `${bucketName}.s3`, 'GET', '', '', qs, {}, {}, region); + } else { + qs.limit = this.getNodeParameter('limit', 0) as number; + responseData = await awsApiRequestSOAPAllItems.call(this, 'ListBucketResult.Contents', `${bucketName}.s3`, 'GET', '', '', qs, {}, {}, region); + responseData = responseData.splice(0, qs.limit); + } + if (Array.isArray(responseData)) { + responseData = responseData.filter((e: IDataObject) => !(e.Key as string).endsWith('/') && e.Size !== '0'); + if (qs.limit) { + responseData = responseData.splice(0, qs.limit as number); + } + returnData.push.apply(returnData, responseData); + } + } + //https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html + if (operation === 'upload') { + const bucketName = this.getNodeParameter('bucketName', i) as string; + const fileName = this.getNodeParameter('fileName', i) as string; + const isBinaryData = this.getNodeParameter('binaryData', i) as boolean; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const tagsValues = (this.getNodeParameter('tagsUi', i) as IDataObject).tagsValues as IDataObject[]; + let path = '/'; + let body; + + if (additionalFields.requesterPays) { + headers['x-amz-request-payer'] = 'requester'; + } + if (additionalFields.parentFolderKey) { + path = `/${additionalFields.parentFolderKey}/`; + } + if (additionalFields.storageClass) { + headers['x-amz-storage-class'] = (snakeCase(additionalFields.storageClass as string)).toUpperCase(); + } + if (additionalFields.acl) { + headers['x-amz-acl'] = paramCase(additionalFields.acl as string); + } + if (additionalFields.grantFullControl) { + headers['x-amz-grant-full-control'] = ''; + } + if (additionalFields.grantRead) { + headers['x-amz-grant-read'] = ''; + } + if (additionalFields.grantReadAcp) { + headers['x-amz-grant-read-acp'] = ''; + } + if (additionalFields.grantWriteAcp) { + headers['x-amz-grant-write-acp'] = ''; + } + if (additionalFields.lockLegalHold) { + headers['x-amz-object-lock-legal-hold'] = (additionalFields.lockLegalHold as boolean) ? 'ON' : 'OFF'; + } + if (additionalFields.lockMode) { + headers['x-amz-object-lock-mode'] = (additionalFields.lockMode as string).toUpperCase(); + } + if (additionalFields.lockRetainUntilDate) { + headers['x-amz-object-lock-retain-until-date'] = additionalFields.lockRetainUntilDate as string; + } + if (additionalFields.serverSideEncryption) { + headers['x-amz-server-side-encryption'] = additionalFields.serverSideEncryption as string; + } + if (additionalFields.encryptionAwsKmsKeyId) { + headers['x-amz-server-side-encryption-aws-kms-key-id'] = additionalFields.encryptionAwsKmsKeyId as string; + } + if (additionalFields.serverSideEncryptionContext) { + headers['x-amz-server-side-encryption-context'] = additionalFields.serverSideEncryptionContext as string; + } + if (additionalFields.serversideEncryptionCustomerAlgorithm) { + headers['x-amz-server-side-encryption-customer-algorithm'] = additionalFields.serversideEncryptionCustomerAlgorithm as string; + } + if (additionalFields.serversideEncryptionCustomerKey) { + headers['x-amz-server-side-encryption-customer-key'] = additionalFields.serversideEncryptionCustomerKey as string; + } + if (additionalFields.serversideEncryptionCustomerKeyMD5) { + headers['x-amz-server-side-encryption-customer-key-MD5'] = additionalFields.serversideEncryptionCustomerKeyMD5 as string; + } + if (tagsValues) { + const tags: string[] = []; + tagsValues.forEach((o: IDataObject) => { tags.push(`${o.key}=${o.value}`); }); + headers['x-amz-tagging'] = tags.join('&'); + } + + responseData = await awsApiRequestSOAP.call(this, `${bucketName}.s3`, 'GET', '', '', { location: '' }); + + const region = responseData.LocationConstraint._; + + if (isBinaryData) { + const binaryPropertyName = this.getNodeParameter('binaryPropertyName', 0) as string; + + if (items[i].binary === undefined) { + throw new NodeOperationError(this.getNode(), 'No binary data exists on item!'); + } + + if ((items[i].binary as IBinaryKeyData)[binaryPropertyName] === undefined) { + throw new NodeOperationError(this.getNode(), `No binary data property "${binaryPropertyName}" does not exists on item!`); + } + + const binaryData = (items[i].binary as IBinaryKeyData)[binaryPropertyName]; + + body = Buffer.from(binaryData.data, BINARY_ENCODING) as Buffer; + + headers['Content-Type'] = binaryData.mimeType; + + headers['Content-MD5'] = createHash('md5').update(body).digest('base64'); + + responseData = await awsApiRequestSOAP.call(this, `${bucketName}.s3`, 'PUT', `${path}${fileName || binaryData.fileName}`, body, qs, headers, {}, region); + + } else { + + const fileContent = this.getNodeParameter('fileContent', i) as string; + + body = Buffer.from(fileContent, 'utf8'); + + headers['Content-Type'] = 'text/html'; + + headers['Content-MD5'] = createHash('md5').update(fileContent).digest('base64'); + + responseData = await awsApiRequestSOAP.call(this, `${bucketName}.s3`, 'PUT', `${path}${fileName}`, body, qs, headers, {}, region); + } + returnData.push({ success: true }); + } + } + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } } if (resource === 'file' && operation === 'download') { diff --git a/packages/nodes-base/nodes/Aws/SES/AwsSes.node.ts b/packages/nodes-base/nodes/Aws/SES/AwsSes.node.ts index 251b9b0e8e..959608b79d 100644 --- a/packages/nodes-base/nodes/Aws/SES/AwsSes.node.ts +++ b/packages/nodes-base/nodes/Aws/SES/AwsSes.node.ts @@ -934,376 +934,383 @@ export class AwsSes implements INodeType { const operation = this.getNodeParameter('operation', 0) as string; for (let i = 0; i < items.length; i++) { + try { + if (resource === 'customVerificationEmail') { - if (resource === 'customVerificationEmail') { + if (operation === 'create') { - if (operation === 'create') { + const failureRedirectionURL = this.getNodeParameter('failureRedirectionURL', i) as string; - const failureRedirectionURL = this.getNodeParameter('failureRedirectionURL', i) as string; + const email = this.getNodeParameter('fromEmailAddress', i) as string; - const email = this.getNodeParameter('fromEmailAddress', i) as string; + const successRedirectionURL = this.getNodeParameter('successRedirectionURL', i) as string; - const successRedirectionURL = this.getNodeParameter('successRedirectionURL', i) as string; + const templateContent = this.getNodeParameter('templateContent', i) as string; - const templateContent = this.getNodeParameter('templateContent', i) as string; + const templateName = this.getNodeParameter('templateName', i) as string; - const templateName = this.getNodeParameter('templateName', i) as string; + const templateSubject = this.getNodeParameter('templateSubject', i) as string; - const templateSubject = this.getNodeParameter('templateSubject', i) as string; + const params = [ + `Action=CreateCustomVerificationEmailTemplate`, + `FailureRedirectionURL=${failureRedirectionURL}`, + `FromEmailAddress=${email}`, + `SuccessRedirectionURL=${successRedirectionURL}`, + `TemplateContent=${templateContent}`, + `TemplateName=${templateName}`, + `TemplateSubject=${templateSubject}`, + ]; - const params = [ - `Action=CreateCustomVerificationEmailTemplate`, - `FailureRedirectionURL=${failureRedirectionURL}`, - `FromEmailAddress=${email}`, - `SuccessRedirectionURL=${successRedirectionURL}`, - `TemplateContent=${templateContent}`, - `TemplateName=${templateName}`, - `TemplateSubject=${templateSubject}`, - ]; + responseData = await awsApiRequestSOAP.call(this, 'email', 'POST', '', params.join('&')); - responseData = await awsApiRequestSOAP.call(this, 'email', 'POST', '', params.join('&')); - - responseData = responseData.CreateCustomVerificationEmailTemplateResponse; - } - - if (operation === 'delete') { - - const templateName = this.getNodeParameter('templateName', i) as string; - - const params = [ - `Action=DeleteCustomVerificationEmailTemplate`, - `TemplateName=${templateName}`, - ]; - - responseData = await awsApiRequestSOAP.call(this, 'email', 'POST', '', params.join('&')); - - responseData = responseData.DeleteCustomVerificationEmailTemplateResponse; - } - - if (operation === 'get') { - - const templateName = this.getNodeParameter('templateName', i) as string; - - const params = [ - `TemplateName=${templateName}`, - ]; - - responseData = await awsApiRequestSOAP.call(this, 'email', 'POST', '/?Action=GetCustomVerificationEmailTemplate&' + params.join('&')); - - responseData = responseData.GetCustomVerificationEmailTemplateResponse; - } - - if (operation === 'getAll') { - - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - - if (returnAll === true) { - responseData = await awsApiRequestSOAPAllItems.call(this, 'ListCustomVerificationEmailTemplatesResponse.ListCustomVerificationEmailTemplatesResult.CustomVerificationEmailTemplates.member', 'email', 'POST', '/?Action=ListCustomVerificationEmailTemplates'); - - } else { - const limit = this.getNodeParameter('limit', i) as number; - - responseData = await awsApiRequestSOAP.call(this, 'email', 'GET', `/?Action=ListCustomVerificationEmailTemplates&MaxResults=${limit}`); - - responseData = responseData.ListCustomVerificationEmailTemplatesResponse.ListCustomVerificationEmailTemplatesResult.CustomVerificationEmailTemplates.member; - } - } - - if (operation === 'send') { - - const email = this.getNodeParameter('email', i) as string[]; - - const templateName = this.getNodeParameter('templateName', i) as string; - - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - - const params = [ - `Action=SendCustomVerificationEmail`, - `TemplateName=${templateName}`, - `EmailAddress=${email}`, - ]; - - if (additionalFields.configurationSetName) { - params.push(`ConfigurationSetName=${additionalFields.configurationSetName}`); + responseData = responseData.CreateCustomVerificationEmailTemplateResponse; } - responseData = await awsApiRequestSOAP.call(this, 'email', 'POST', '', params.join('&')); + if (operation === 'delete') { - responseData = responseData.SendCustomVerificationEmailResponse; - } + const templateName = this.getNodeParameter('templateName', i) as string; - if (operation === 'update') { + const params = [ + `Action=DeleteCustomVerificationEmailTemplate`, + `TemplateName=${templateName}`, + ]; - const templateName = this.getNodeParameter('templateName', i) as string; + responseData = await awsApiRequestSOAP.call(this, 'email', 'POST', '', params.join('&')); - const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; - - const params = [ - `Action=UpdateCustomVerificationEmailTemplate`, - `TemplateName=${templateName}`, - ]; - - if (updateFields.FailureRedirectionURL) { - params.push(`FailureRedirectionURL=${updateFields.FailureRedirectionURL}`); + responseData = responseData.DeleteCustomVerificationEmailTemplateResponse; } - if (updateFields.email) { - params.push(`FromEmailAddress=${updateFields.email}`); + if (operation === 'get') { + + const templateName = this.getNodeParameter('templateName', i) as string; + + const params = [ + `TemplateName=${templateName}`, + ]; + + responseData = await awsApiRequestSOAP.call(this, 'email', 'POST', '/?Action=GetCustomVerificationEmailTemplate&' + params.join('&')); + + responseData = responseData.GetCustomVerificationEmailTemplateResponse; } - if (updateFields.successRedirectionURL) { - params.push(`SuccessRedirectionURL=${updateFields.successRedirectionURL}`); - } + if (operation === 'getAll') { - if (updateFields.templateContent) { - params.push(`TemplateContent=${updateFields.templateContent}`); - } + const returnAll = this.getNodeParameter('returnAll', i) as boolean; - if (updateFields.templateSubject) { - params.push(`TemplateSubject=${updateFields.templateSubject}`); - } + if (returnAll === true) { + responseData = await awsApiRequestSOAPAllItems.call(this, 'ListCustomVerificationEmailTemplatesResponse.ListCustomVerificationEmailTemplatesResult.CustomVerificationEmailTemplates.member', 'email', 'POST', '/?Action=ListCustomVerificationEmailTemplates'); - responseData = await awsApiRequestSOAP.call(this, 'email', 'POST', '', params.join('&')); + } else { + const limit = this.getNodeParameter('limit', i) as number; - responseData = responseData.UpdateCustomVerificationEmailTemplateResponse; - } - } + responseData = await awsApiRequestSOAP.call(this, 'email', 'GET', `/?Action=ListCustomVerificationEmailTemplates&MaxResults=${limit}`); - if (resource === 'email') { - - if (operation === 'send') { - - const toAddresses = this.getNodeParameter('toAddresses', i) as string[]; - - const message = this.getNodeParameter('body', i) as string; - - const subject = this.getNodeParameter('subject', i) as string; - - const fromEmail = this.getNodeParameter('fromEmail', i) as string; - - const isBodyHtml = this.getNodeParameter('isBodyHtml', i) as boolean; - - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - - const params = [ - `Message.Subject.Data=${subject}`, - `Source=${fromEmail}`, - ]; - - if (isBodyHtml) { - params.push(`Message.Body.Html.Data=${encodeURI(message)}`); - } else { - params.push(`Message.Body.Text.Data=${encodeURI(message)}`); - } - - if (toAddresses.length) { - setParameter(params, 'Destination.ToAddresses.member', toAddresses); - } else { - throw new NodeOperationError(this.getNode(), 'At least one "To Address" has to be added!'); - } - - if (additionalFields.configurationSetName) { - params.push(`ConfigurationSetName=${additionalFields.configurationSetName}`); - } - - if (additionalFields.returnPath) { - params.push(`ReturnPath=${additionalFields.returnPath}`); - } - - if (additionalFields.returnPathArn) { - params.push(`ReturnPathArn=${additionalFields.returnPathArn}`); - } - - if (additionalFields.sourceArn) { - params.push(`SourceArn=${additionalFields.sourceArn}`); - } - - if (additionalFields.replyToAddresses) { - setParameter(params, 'ReplyToAddresses.member', additionalFields.replyToAddresses as string[]); - } - - if (additionalFields.bccAddresses) { - setParameter(params, 'Destination.BccAddresses.member', additionalFields.bccAddresses as string[]); - } - - if (additionalFields.ccAddresses) { - setParameter(params, 'Destination.CcAddresses.member', additionalFields.ccAddresses as string[]); - } - responseData = await awsApiRequestSOAP.call(this, 'email', 'POST', '/?Action=SendEmail&' + params.join('&')); - } - - if (operation === 'sendTemplate') { - - const toAddresses = this.getNodeParameter('toAddresses', i) as string[]; - - const template = this.getNodeParameter('templateName', i) as string; - - const fromEmail = this.getNodeParameter('fromEmail', i) as string; - - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - - const templateDataUi = this.getNodeParameter('templateDataUi', i) as IDataObject; - - const params = [ - `Template=${template}`, - `Source=${fromEmail}`, - ]; - - if (toAddresses.length) { - setParameter(params, 'Destination.ToAddresses.member', toAddresses); - } else { - throw new NodeOperationError(this.getNode(), 'At least one "To Address" has to be added!'); - } - - if (additionalFields.configurationSetName) { - params.push(`ConfigurationSetName=${additionalFields.configurationSetName}`); - } - - if (additionalFields.returnPath) { - params.push(`ReturnPath=${additionalFields.returnPath}`); - } - - if (additionalFields.returnPathArn) { - params.push(`ReturnPathArn=${additionalFields.returnPathArn}`); - } - - if (additionalFields.sourceArn) { - params.push(`SourceArn=${additionalFields.sourceArn}`); - } - - if (additionalFields.replyToAddresses) { - setParameter(params, 'ReplyToAddresses.member', additionalFields.replyToAddresses as string[]); - } - - if (additionalFields.bccAddresses) { - setParameter(params, 'Destination.BccAddresses.member', additionalFields.bccAddresses as string[]); - } - - if (additionalFields.ccAddresses) { - setParameter(params, 'Destination.CcAddresses.member', additionalFields.ccAddresses as string[]); - } - - if (templateDataUi) { - const templateDataValues = (templateDataUi as IDataObject).templateDataValues as IDataObject[]; - const templateData: IDataObject = {}; - if (templateDataValues !== undefined) { - for (const templateDataValue of templateDataValues) { - //@ts-ignore - templateData[templateDataValue.key] = templateDataValue.value; - } - params.push(`TemplateData=${JSON.stringify(templateData)}`); + responseData = responseData.ListCustomVerificationEmailTemplatesResponse.ListCustomVerificationEmailTemplatesResult.CustomVerificationEmailTemplates.member; } } - responseData = await awsApiRequestSOAP.call(this, 'email', 'POST', '/?Action=SendTemplatedEmail&' + params.join('&')); + if (operation === 'send') { - responseData = responseData.SendTemplatedEmailResponse; - } - } + const email = this.getNodeParameter('email', i) as string[]; - if (resource === 'template') { + const templateName = this.getNodeParameter('templateName', i) as string; - if (operation === 'create') { + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const templateName = this.getNodeParameter('templateName', i) as string; + const params = [ + `Action=SendCustomVerificationEmail`, + `TemplateName=${templateName}`, + `EmailAddress=${email}`, + ]; - const subjectPart = this.getNodeParameter('subjectPart', i) as string; + if (additionalFields.configurationSetName) { + params.push(`ConfigurationSetName=${additionalFields.configurationSetName}`); + } - const htmlPart = this.getNodeParameter('htmlPart', i) as string; + responseData = await awsApiRequestSOAP.call(this, 'email', 'POST', '', params.join('&')); - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - - const params = [ - `Template.TemplateName=${templateName}`, - `Template.SubjectPart=${subjectPart}`, - `Template.HtmlPart=

${htmlPart}

`, - ]; - - if (additionalFields.textPart) { - params.push(`Template.TextPart=${additionalFields.textPart}`); + responseData = responseData.SendCustomVerificationEmailResponse; } - responseData = await awsApiRequestSOAP.call(this, 'email', 'POST', '/?Action=CreateTemplate&' + params.join('&')); + if (operation === 'update') { - responseData = responseData.CreateTemplateResponse; - } + const templateName = this.getNodeParameter('templateName', i) as string; - if (operation === 'delete') { + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; - const templateName = this.getNodeParameter('templateName', i) as string; + const params = [ + `Action=UpdateCustomVerificationEmailTemplate`, + `TemplateName=${templateName}`, + ]; - const params = [ - `TemplateName=${templateName}`, - ]; + if (updateFields.FailureRedirectionURL) { + params.push(`FailureRedirectionURL=${updateFields.FailureRedirectionURL}`); + } - responseData = await awsApiRequestSOAP.call(this, 'email', 'POST', '/?Action=DeleteTemplate&' + params.join('&')); + if (updateFields.email) { + params.push(`FromEmailAddress=${updateFields.email}`); + } - responseData = responseData.DeleteTemplateResponse; - } + if (updateFields.successRedirectionURL) { + params.push(`SuccessRedirectionURL=${updateFields.successRedirectionURL}`); + } - if (operation === 'get') { + if (updateFields.templateContent) { + params.push(`TemplateContent=${updateFields.templateContent}`); + } - const templateName = this.getNodeParameter('templateName', i) as string; + if (updateFields.templateSubject) { + params.push(`TemplateSubject=${updateFields.templateSubject}`); + } - const params = [ - `TemplateName=${templateName}`, - ]; + responseData = await awsApiRequestSOAP.call(this, 'email', 'POST', '', params.join('&')); - responseData = await awsApiRequestSOAP.call(this, 'email', 'POST', '/?Action=GetTemplate&' + params.join('&')); - - responseData = responseData.GetTemplateResponse; - } - - if (operation === 'getAll') { - - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - - if (returnAll === true) { - responseData = await awsApiRequestSOAPAllItems.call(this, 'ListTemplatesResponse.ListTemplatesResult.TemplatesMetadata.member', 'email', 'POST', '/?Action=ListTemplates'); - - } else { - const limit = this.getNodeParameter('limit', i) as number; - - responseData = await awsApiRequestSOAP.call(this, 'email', 'GET', `/?Action=ListTemplates&MaxItems=${limit}`); - - responseData = responseData.ListTemplatesResponse.ListTemplatesResult.TemplatesMetadata.member; + responseData = responseData.UpdateCustomVerificationEmailTemplateResponse; } } - if (operation === 'update') { + if (resource === 'email') { - const templateName = this.getNodeParameter('templateName', i) as string; + if (operation === 'send') { - const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + const toAddresses = this.getNodeParameter('toAddresses', i) as string[]; - const params = [ - `Template.TemplateName=${templateName}`, - ]; + const message = this.getNodeParameter('body', i) as string; - if (updateFields.textPart) { - params.push(`Template.TextPart=${updateFields.textPart}`); + const subject = this.getNodeParameter('subject', i) as string; + + const fromEmail = this.getNodeParameter('fromEmail', i) as string; + + const isBodyHtml = this.getNodeParameter('isBodyHtml', i) as boolean; + + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + + const params = [ + `Message.Subject.Data=${subject}`, + `Source=${fromEmail}`, + ]; + + if (isBodyHtml) { + params.push(`Message.Body.Html.Data=${encodeURI(message)}`); + } else { + params.push(`Message.Body.Text.Data=${encodeURI(message)}`); + } + + if (toAddresses.length) { + setParameter(params, 'Destination.ToAddresses.member', toAddresses); + } else { + throw new NodeOperationError(this.getNode(), 'At least one "To Address" has to be added!'); + } + + if (additionalFields.configurationSetName) { + params.push(`ConfigurationSetName=${additionalFields.configurationSetName}`); + } + + if (additionalFields.returnPath) { + params.push(`ReturnPath=${additionalFields.returnPath}`); + } + + if (additionalFields.returnPathArn) { + params.push(`ReturnPathArn=${additionalFields.returnPathArn}`); + } + + if (additionalFields.sourceArn) { + params.push(`SourceArn=${additionalFields.sourceArn}`); + } + + if (additionalFields.replyToAddresses) { + setParameter(params, 'ReplyToAddresses.member', additionalFields.replyToAddresses as string[]); + } + + if (additionalFields.bccAddresses) { + setParameter(params, 'Destination.BccAddresses.member', additionalFields.bccAddresses as string[]); + } + + if (additionalFields.ccAddresses) { + setParameter(params, 'Destination.CcAddresses.member', additionalFields.ccAddresses as string[]); + } + responseData = await awsApiRequestSOAP.call(this, 'email', 'POST', '/?Action=SendEmail&' + params.join('&')); } - if (updateFields.subjectPart) { - params.push(`Template.SubjectPart=${updateFields.subjectPart}`); + if (operation === 'sendTemplate') { + + const toAddresses = this.getNodeParameter('toAddresses', i) as string[]; + + const template = this.getNodeParameter('templateName', i) as string; + + const fromEmail = this.getNodeParameter('fromEmail', i) as string; + + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + + const templateDataUi = this.getNodeParameter('templateDataUi', i) as IDataObject; + + const params = [ + `Template=${template}`, + `Source=${fromEmail}`, + ]; + + if (toAddresses.length) { + setParameter(params, 'Destination.ToAddresses.member', toAddresses); + } else { + throw new NodeOperationError(this.getNode(), 'At least one "To Address" has to be added!'); + } + + if (additionalFields.configurationSetName) { + params.push(`ConfigurationSetName=${additionalFields.configurationSetName}`); + } + + if (additionalFields.returnPath) { + params.push(`ReturnPath=${additionalFields.returnPath}`); + } + + if (additionalFields.returnPathArn) { + params.push(`ReturnPathArn=${additionalFields.returnPathArn}`); + } + + if (additionalFields.sourceArn) { + params.push(`SourceArn=${additionalFields.sourceArn}`); + } + + if (additionalFields.replyToAddresses) { + setParameter(params, 'ReplyToAddresses.member', additionalFields.replyToAddresses as string[]); + } + + if (additionalFields.bccAddresses) { + setParameter(params, 'Destination.BccAddresses.member', additionalFields.bccAddresses as string[]); + } + + if (additionalFields.ccAddresses) { + setParameter(params, 'Destination.CcAddresses.member', additionalFields.ccAddresses as string[]); + } + + if (templateDataUi) { + const templateDataValues = (templateDataUi as IDataObject).templateDataValues as IDataObject[]; + const templateData: IDataObject = {}; + if (templateDataValues !== undefined) { + for (const templateDataValue of templateDataValues) { + //@ts-ignore + templateData[templateDataValue.key] = templateDataValue.value; + } + params.push(`TemplateData=${JSON.stringify(templateData)}`); + } + } + + responseData = await awsApiRequestSOAP.call(this, 'email', 'POST', '/?Action=SendTemplatedEmail&' + params.join('&')); + + responseData = responseData.SendTemplatedEmailResponse; } - - if (updateFields.subjectPart) { - params.push(`Template.HtmlPart=${updateFields.htmlPart}`); - } - - responseData = await awsApiRequestSOAP.call(this, 'email', 'POST', '/?Action=UpdateTemplate&' + params.join('&')); - - responseData = responseData.UpdateTemplateResponse; } - } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else { - if (responseData !== undefined) { - returnData.push(responseData as IDataObject); + if (resource === 'template') { + + if (operation === 'create') { + + const templateName = this.getNodeParameter('templateName', i) as string; + + const subjectPart = this.getNodeParameter('subjectPart', i) as string; + + const htmlPart = this.getNodeParameter('htmlPart', i) as string; + + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + + const params = [ + `Template.TemplateName=${templateName}`, + `Template.SubjectPart=${subjectPart}`, + `Template.HtmlPart=

${htmlPart}

`, + ]; + + if (additionalFields.textPart) { + params.push(`Template.TextPart=${additionalFields.textPart}`); + } + + responseData = await awsApiRequestSOAP.call(this, 'email', 'POST', '/?Action=CreateTemplate&' + params.join('&')); + + responseData = responseData.CreateTemplateResponse; + } + + if (operation === 'delete') { + + const templateName = this.getNodeParameter('templateName', i) as string; + + const params = [ + `TemplateName=${templateName}`, + ]; + + responseData = await awsApiRequestSOAP.call(this, 'email', 'POST', '/?Action=DeleteTemplate&' + params.join('&')); + + responseData = responseData.DeleteTemplateResponse; + } + + if (operation === 'get') { + + const templateName = this.getNodeParameter('templateName', i) as string; + + const params = [ + `TemplateName=${templateName}`, + ]; + + responseData = await awsApiRequestSOAP.call(this, 'email', 'POST', '/?Action=GetTemplate&' + params.join('&')); + + responseData = responseData.GetTemplateResponse; + } + + if (operation === 'getAll') { + + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + + if (returnAll === true) { + responseData = await awsApiRequestSOAPAllItems.call(this, 'ListTemplatesResponse.ListTemplatesResult.TemplatesMetadata.member', 'email', 'POST', '/?Action=ListTemplates'); + + } else { + const limit = this.getNodeParameter('limit', i) as number; + + responseData = await awsApiRequestSOAP.call(this, 'email', 'GET', `/?Action=ListTemplates&MaxItems=${limit}`); + + responseData = responseData.ListTemplatesResponse.ListTemplatesResult.TemplatesMetadata.member; + } + } + + if (operation === 'update') { + + const templateName = this.getNodeParameter('templateName', i) as string; + + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + + const params = [ + `Template.TemplateName=${templateName}`, + ]; + + if (updateFields.textPart) { + params.push(`Template.TextPart=${updateFields.textPart}`); + } + + if (updateFields.subjectPart) { + params.push(`Template.SubjectPart=${updateFields.subjectPart}`); + } + + if (updateFields.subjectPart) { + params.push(`Template.HtmlPart=${updateFields.htmlPart}`); + } + + responseData = await awsApiRequestSOAP.call(this, 'email', 'POST', '/?Action=UpdateTemplate&' + params.join('&')); + + responseData = responseData.UpdateTemplateResponse; + } } + + if (Array.isArray(responseData)) { + returnData.push.apply(returnData, responseData as IDataObject[]); + } else { + if (responseData !== undefined) { + returnData.push(responseData as IDataObject); + } + } + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } } diff --git a/packages/nodes-base/nodes/Aws/SQS/AwsSqs.node.ts b/packages/nodes-base/nodes/Aws/SQS/AwsSqs.node.ts index 38d02abf43..2cef3ad6b2 100644 --- a/packages/nodes-base/nodes/Aws/SQS/AwsSqs.node.ts +++ b/packages/nodes-base/nodes/Aws/SQS/AwsSqs.node.ts @@ -316,84 +316,92 @@ export class AwsSqs implements INodeType { const operation = this.getNodeParameter('operation', 0) as string; for (let i = 0; i < items.length; i++) { - const queueUrl = this.getNodeParameter('queue', i) as string; - const queuePath = new URL(queueUrl).pathname; - - const params = [ - 'Version=2012-11-05', - `Action=${pascalCase(operation)}`, - ]; - - const options = this.getNodeParameter('options', i, {}) as IDataObject; - const sendInputData = this.getNodeParameter('sendInputData', i) as boolean; - - const message = sendInputData ? JSON.stringify(items[i].json) : this.getNodeParameter('message', i) as string; - params.push(`MessageBody=${message}`); - - if (options.delaySeconds) { - params.push(`DelaySeconds=${options.delaySeconds}`); - } - - const queueType = this.getNodeParameter('queueType', i, {}) as string; - if (queueType === 'fifo') { - const messageDeduplicationId = this.getNodeParameter('options.messageDeduplicationId', i, '') as string; - if (messageDeduplicationId) { - params.push(`MessageDeduplicationId=${messageDeduplicationId}`); - } - - const messageGroupId = this.getNodeParameter('messageGroupId', i) as string; - if (messageGroupId) { - params.push(`MessageGroupId=${messageGroupId}`); - } - } - - let attributeCount = 0; - // Add string values - (this.getNodeParameter('options.messageAttributes.string', i, []) as INodeParameters[]).forEach((attribute) => { - attributeCount++; - params.push(`MessageAttribute.${attributeCount}.Name=${attribute.name}`); - params.push(`MessageAttribute.${attributeCount}.Value.StringValue=${attribute.value}`); - params.push(`MessageAttribute.${attributeCount}.Value.DataType=String`); - }); - - // Add binary values - (this.getNodeParameter('options.messageAttributes.binary', i, []) as INodeParameters[]).forEach((attribute) => { - attributeCount++; - const dataPropertyName = attribute.dataPropertyName as string; - const item = items[i]; - - if (item.binary === undefined) { - throw new NodeOperationError(this.getNode(), 'No binary data set. So message attribute cannot be added!'); - } - - if (item.binary[dataPropertyName] === undefined) { - throw new NodeOperationError(this.getNode(), `The binary property "${dataPropertyName}" does not exist. So message attribute cannot be added!`); - } - - const binaryData = item.binary[dataPropertyName].data; - - params.push(`MessageAttribute.${attributeCount}.Name=${attribute.name}`); - params.push(`MessageAttribute.${attributeCount}.Value.BinaryValue=${binaryData}`); - params.push(`MessageAttribute.${attributeCount}.Value.DataType=Binary`); - }); - - // Add number values - (this.getNodeParameter('options.messageAttributes.number', i, []) as INodeParameters[]).forEach((attribute) => { - attributeCount++; - params.push(`MessageAttribute.${attributeCount}.Name=${attribute.name}`); - params.push(`MessageAttribute.${attributeCount}.Value.StringValue=${attribute.value}`); - params.push(`MessageAttribute.${attributeCount}.Value.DataType=Number`); - }); - - let responseData; try { - responseData = await awsApiRequestSOAP.call(this, 'sqs', 'GET', `${queuePath}?${params.join('&')}`); - } catch (error) { - throw new NodeApiError(this.getNode(), error); - } + const queueUrl = this.getNodeParameter('queue', i) as string; + const queuePath = new URL(queueUrl).pathname; - const result = responseData.SendMessageResponse.SendMessageResult; - returnData.push(result as IDataObject); + const params = [ + 'Version=2012-11-05', + `Action=${pascalCase(operation)}`, + ]; + + const options = this.getNodeParameter('options', i, {}) as IDataObject; + const sendInputData = this.getNodeParameter('sendInputData', i) as boolean; + + const message = sendInputData ? JSON.stringify(items[i].json) : this.getNodeParameter('message', i) as string; + params.push(`MessageBody=${message}`); + + if (options.delaySeconds) { + params.push(`DelaySeconds=${options.delaySeconds}`); + } + + const queueType = this.getNodeParameter('queueType', i, {}) as string; + if (queueType === 'fifo') { + const messageDeduplicationId = this.getNodeParameter('options.messageDeduplicationId', i, '') as string; + if (messageDeduplicationId) { + params.push(`MessageDeduplicationId=${messageDeduplicationId}`); + } + + const messageGroupId = this.getNodeParameter('messageGroupId', i) as string; + if (messageGroupId) { + params.push(`MessageGroupId=${messageGroupId}`); + } + } + + let attributeCount = 0; + // Add string values + (this.getNodeParameter('options.messageAttributes.string', i, []) as INodeParameters[]).forEach((attribute) => { + attributeCount++; + params.push(`MessageAttribute.${attributeCount}.Name=${attribute.name}`); + params.push(`MessageAttribute.${attributeCount}.Value.StringValue=${attribute.value}`); + params.push(`MessageAttribute.${attributeCount}.Value.DataType=String`); + }); + + // Add binary values + (this.getNodeParameter('options.messageAttributes.binary', i, []) as INodeParameters[]).forEach((attribute) => { + attributeCount++; + const dataPropertyName = attribute.dataPropertyName as string; + const item = items[i]; + + if (item.binary === undefined) { + throw new NodeOperationError(this.getNode(), 'No binary data set. So message attribute cannot be added!'); + } + + if (item.binary[dataPropertyName] === undefined) { + throw new NodeOperationError(this.getNode(), `The binary property "${dataPropertyName}" does not exist. So message attribute cannot be added!`); + } + + const binaryData = item.binary[dataPropertyName].data; + + params.push(`MessageAttribute.${attributeCount}.Name=${attribute.name}`); + params.push(`MessageAttribute.${attributeCount}.Value.BinaryValue=${binaryData}`); + params.push(`MessageAttribute.${attributeCount}.Value.DataType=Binary`); + }); + + // Add number values + (this.getNodeParameter('options.messageAttributes.number', i, []) as INodeParameters[]).forEach((attribute) => { + attributeCount++; + params.push(`MessageAttribute.${attributeCount}.Name=${attribute.name}`); + params.push(`MessageAttribute.${attributeCount}.Value.StringValue=${attribute.value}`); + params.push(`MessageAttribute.${attributeCount}.Value.DataType=Number`); + }); + + let responseData; + try { + responseData = await awsApiRequestSOAP.call(this, 'sqs', 'GET', `${queuePath}?${params.join('&')}`); + } catch (error) { + throw new NodeApiError(this.getNode(), error); + } + + const result = responseData.SendMessageResponse.SendMessageResult; + returnData.push(result as IDataObject); + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.description }); + continue; + } + throw error; + } } return [this.helpers.returnJsonArray(returnData)]; diff --git a/packages/nodes-base/nodes/Beeminder/Beeminder.node.ts b/packages/nodes-base/nodes/Beeminder/Beeminder.node.ts index 435e1ecb30..490d134af7 100644 --- a/packages/nodes-base/nodes/Beeminder/Beeminder.node.ts +++ b/packages/nodes-base/nodes/Beeminder/Beeminder.node.ts @@ -340,60 +340,66 @@ export class Beeminder implements INodeType { for (let i = 0; i < length; i++) { + try { + if (resource === 'datapoint') { + const goalName = this.getNodeParameter('goalName', i) as string; + if (operation === 'create') { + const value = this.getNodeParameter('value', i) as number; + const options = this.getNodeParameter('additionalFields', i) as INodeParameters; + const data: IDataObject = { + value, + goalName, + }; + Object.assign(data, options); - if (resource === 'datapoint') { - const goalName = this.getNodeParameter('goalName', i) as string; - if (operation === 'create') { - const value = this.getNodeParameter('value', i) as number; - const options = this.getNodeParameter('additionalFields', i) as INodeParameters; - const data: IDataObject = { - value, - goalName, - }; - Object.assign(data, options); - - if (data.timestamp) { - data.timestamp = moment.tz(data.timestamp, timezone).unix(); + if (data.timestamp) { + data.timestamp = moment.tz(data.timestamp, timezone).unix(); + } + results = await createDatapoint.call(this, data); } - results = await createDatapoint.call(this, data); - } - else if (operation === 'getAll') { - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - const options = this.getNodeParameter('options', i) as INodeParameters; - const data: IDataObject = { - goalName, - }; - Object.assign(data, options); + else if (operation === 'getAll') { + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + const options = this.getNodeParameter('options', i) as INodeParameters; + const data: IDataObject = { + goalName, + }; + Object.assign(data, options); - if (returnAll === false) { - data.count = this.getNodeParameter('limit', 0) as number; - } + if (returnAll === false) { + data.count = this.getNodeParameter('limit', 0) as number; + } - results = await getAllDatapoints.call(this, data); - } - else if (operation === 'update') { - const datapointId = this.getNodeParameter('datapointId', i) as string; - const options = this.getNodeParameter('updateFields', i) as INodeParameters; - const data: IDataObject = { - goalName, - datapointId, - }; - Object.assign(data, options); - if (data.timestamp) { - data.timestamp = moment.tz(data.timestamp, timezone).unix(); + results = await getAllDatapoints.call(this, data); + } + else if (operation === 'update') { + const datapointId = this.getNodeParameter('datapointId', i) as string; + const options = this.getNodeParameter('updateFields', i) as INodeParameters; + const data: IDataObject = { + goalName, + datapointId, + }; + Object.assign(data, options); + if (data.timestamp) { + data.timestamp = moment.tz(data.timestamp, timezone).unix(); + } + results = await updateDatapoint.call(this, data); + } + else if (operation === 'delete') { + const datapointId = this.getNodeParameter('datapointId', i) as string; + const data: IDataObject = { + goalName, + datapointId, + }; + results = await deleteDatapoint.call(this, data); } - results = await updateDatapoint.call(this, data); } - else if (operation === 'delete') { - const datapointId = this.getNodeParameter('datapointId', i) as string; - const data: IDataObject = { - goalName, - datapointId, - }; - results = await deleteDatapoint.call(this, data); + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; } + throw error; } - if (Array.isArray(results)) { returnData.push.apply(returnData, results as IDataObject[]); } else { diff --git a/packages/nodes-base/nodes/Bitly/Bitly.node.ts b/packages/nodes-base/nodes/Bitly/Bitly.node.ts index 12d01ded4d..f21c75cbec 100644 --- a/packages/nodes-base/nodes/Bitly/Bitly.node.ts +++ b/packages/nodes-base/nodes/Bitly/Bitly.node.ts @@ -141,81 +141,89 @@ export class Bitly implements INodeType { 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 === 'link') { - if (operation === 'create') { - const longUrl = this.getNodeParameter('longUrl', i) as string; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const body: IDataObject = { - long_url: longUrl, - }; - if (additionalFields.title) { - body.title = additionalFields.title as string; - } - if (additionalFields.domain) { - body.domain = additionalFields.domain as string; - } - if (additionalFields.group) { - body.group = additionalFields.group as string; - } - if (additionalFields.tags) { - body.tags = additionalFields.tags as string[]; - } - const deeplinks = (this.getNodeParameter('deeplink', i) as IDataObject).deeplinkUi as IDataObject[]; - if (deeplinks) { - for (const deeplink of deeplinks) { - //@ts-ignore - body.deeplinks.push({ - app_uri_path: deeplink.appUriPath, - install_type: deeplink.installType, - install_url: deeplink.installUrl, - app_id: deeplink.appId, - }); + try { + if (resource === 'link') { + if (operation === 'create') { + const longUrl = this.getNodeParameter('longUrl', i) as string; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const body: IDataObject = { + long_url: longUrl, + }; + if (additionalFields.title) { + body.title = additionalFields.title as string; } - } - responseData = await bitlyApiRequest.call(this, 'POST', '/bitlinks', body); - } - if (operation === 'update') { - const linkId = this.getNodeParameter('id', i) as string; - const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; - const body: IDataObject = {}; - if (updateFields.longUrl) { - body.long_url = updateFields.longUrl as string; - } - if (updateFields.title) { - body.title = updateFields.title as string; - } - if (updateFields.archived !== undefined) { - body.archived = updateFields.archived as boolean; - } - if (updateFields.group) { - body.group = updateFields.group as string; - } - if (updateFields.tags) { - body.tags = updateFields.tags as string[]; - } - const deeplinks = (this.getNodeParameter('deeplink', i) as IDataObject).deeplinkUi as IDataObject[]; - if (deeplinks) { - for (const deeplink of deeplinks) { - //@ts-ignore - body.deeplinks.push({ - app_uri_path: deeplink.appUriPath, - install_type: deeplink.installType, - install_url: deeplink.installUrl, - app_id: deeplink.appId, - }); + if (additionalFields.domain) { + body.domain = additionalFields.domain as string; } + if (additionalFields.group) { + body.group = additionalFields.group as string; + } + if (additionalFields.tags) { + body.tags = additionalFields.tags as string[]; + } + const deeplinks = (this.getNodeParameter('deeplink', i) as IDataObject).deeplinkUi as IDataObject[]; + if (deeplinks) { + for (const deeplink of deeplinks) { + //@ts-ignore + body.deeplinks.push({ + app_uri_path: deeplink.appUriPath, + install_type: deeplink.installType, + install_url: deeplink.installUrl, + app_id: deeplink.appId, + }); + } + } + responseData = await bitlyApiRequest.call(this, 'POST', '/bitlinks', body); + } + if (operation === 'update') { + const linkId = this.getNodeParameter('id', i) as string; + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + const body: IDataObject = {}; + if (updateFields.longUrl) { + body.long_url = updateFields.longUrl as string; + } + if (updateFields.title) { + body.title = updateFields.title as string; + } + if (updateFields.archived !== undefined) { + body.archived = updateFields.archived as boolean; + } + if (updateFields.group) { + body.group = updateFields.group as string; + } + if (updateFields.tags) { + body.tags = updateFields.tags as string[]; + } + const deeplinks = (this.getNodeParameter('deeplink', i) as IDataObject).deeplinkUi as IDataObject[]; + if (deeplinks) { + for (const deeplink of deeplinks) { + //@ts-ignore + body.deeplinks.push({ + app_uri_path: deeplink.appUriPath, + install_type: deeplink.installType, + install_url: deeplink.installUrl, + app_id: deeplink.appId, + }); + } + } + responseData = await bitlyApiRequest.call(this, 'PATCH', `/bitlinks/${linkId}`, body); + } + if (operation === 'get') { + const linkId = this.getNodeParameter('id', i) as string; + responseData = await bitlyApiRequest.call(this, 'GET', `/bitlinks/${linkId}`); } - responseData = await bitlyApiRequest.call(this, 'PATCH', `/bitlinks/${linkId}`, body); } - if (operation === 'get') { - const linkId = this.getNodeParameter('id', i) as string; - responseData = await bitlyApiRequest.call(this, 'GET', `/bitlinks/${linkId}`); + if (Array.isArray(responseData)) { + returnData.push.apply(returnData, responseData as IDataObject[]); + } else { + returnData.push(responseData as IDataObject); } - } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else { - returnData.push(responseData as IDataObject); + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } } return [this.helpers.returnJsonArray(returnData)]; diff --git a/packages/nodes-base/nodes/Box/Box.node.ts b/packages/nodes-base/nodes/Box/Box.node.ts index 9d462b60b7..00d19f596e 100644 --- a/packages/nodes-base/nodes/Box/Box.node.ts +++ b/packages/nodes-base/nodes/Box/Box.node.ts @@ -89,396 +89,404 @@ export class Box implements INodeType { 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 === 'file') { - // https://developer.box.com/reference/post-files-id-copy - if (operation === 'copy') { - const fileId = this.getNodeParameter('fileId', i) as string; - const parentId = this.getNodeParameter('parentId', i) as string; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const body: IDataObject = {}; - if (additionalFields.name) { - body.name = additionalFields.name as string; - } - if (parentId) { - body.parent = { id: parentId }; - } else { - body.parent = { id: 0 }; - } - if (additionalFields.fields) { - qs.fields = additionalFields.fields as string; - } - if (additionalFields.version) { - body.version = additionalFields.version as string; - } - responseData = await boxApiRequest.call(this, 'POST', `/files/${fileId}/copy`, body, qs); - - returnData.push(responseData as IDataObject); - } - // https://developer.box.com/reference/delete-files-id - if (operation === 'delete') { - const fileId = this.getNodeParameter('fileId', i) as string; - responseData = await boxApiRequest.call(this, 'DELETE', `/files/${fileId}`); - responseData = { success: true }; - returnData.push(responseData as IDataObject); - } - // https://developer.box.com/reference/get-files-id-content - if (operation === 'download') { - const fileId = this.getNodeParameter('fileId', i) as string; - const dataPropertyNameDownload = this.getNodeParameter('binaryPropertyName', i) as string; - responseData = await boxApiRequest.call(this, 'GET', `/files/${fileId}`); - - const fileName = responseData.name; - - let mimeType: string | undefined; - - responseData = await boxApiRequest.call(this, 'GET', `/files/${fileId}/content`, {}, {}, undefined, { resolveWithFullResponse: true }); - - const newItem: INodeExecutionData = { - json: items[i].json, - binary: {}, - }; - - if (mimeType === undefined && responseData.headers['content-type']) { - mimeType = responseData.headers['content-type']; - } - - if (items[i].binary !== undefined) { - // Create a shallow copy of the binary data so that the old - // data references which do not get changed still stay behind - // but the incoming data does not get changed. - Object.assign(newItem.binary, items[i].binary); - } - - items[i] = newItem; - - const data = Buffer.from(responseData.body); - - items[i].binary![dataPropertyNameDownload] = await this.helpers.prepareBinaryData(data as unknown as Buffer, fileName, mimeType); - } - // https://developer.box.com/reference/get-files-id - if (operation === 'get') { - const fileId = this.getNodeParameter('fileId', i) as string; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - if (additionalFields.fields) { - qs.fields = additionalFields.fields as string; - } - responseData = await boxApiRequest.call(this, 'GET', `/files/${fileId}`, {}, qs); - returnData.push(responseData as IDataObject); - } - // https://developer.box.com/reference/get-search/ - if (operation === 'search') { - const query = this.getNodeParameter('query', i) as string; - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const timezone = this.getTimezone(); - qs.type = 'file'; - qs.query = query; - Object.assign(qs, additionalFields); - - if (qs.content_types) { - qs.content_types = (qs.content_types as string).split(','); - } - - if (additionalFields.createdRangeUi) { - const createdRangeValues = (additionalFields.createdRangeUi as IDataObject).createdRangeValuesUi as IDataObject; - if (createdRangeValues) { - qs.created_at_range = `${moment.tz(createdRangeValues.from, timezone).format()},${moment.tz(createdRangeValues.to, timezone).format()}`; - } - delete qs.createdRangeUi; - } - - if (additionalFields.updatedRangeUi) { - const updateRangeValues = (additionalFields.updatedRangeUi as IDataObject).updatedRangeValuesUi as IDataObject; - if (updateRangeValues) { - qs.updated_at_range = `${moment.tz(updateRangeValues.from, timezone).format()},${moment.tz(updateRangeValues.to, timezone).format()}`; - } - delete qs.updatedRangeUi; - } - - if (returnAll) { - responseData = await boxApiRequestAllItems.call(this, 'entries', 'GET', `/search`, {}, qs); - } else { - qs.limit = this.getNodeParameter('limit', i) as number; - responseData = await boxApiRequest.call(this, 'GET', `/search`, {}, qs); - responseData = responseData.entries; - } - returnData.push.apply(returnData, responseData as IDataObject[]); - } - // https://developer.box.com/reference/post-collaborations/ - if (operation === 'share') { - const fileId = this.getNodeParameter('fileId', i) as string; - const role = this.getNodeParameter('role', i) as string; - const accessibleBy = this.getNodeParameter('accessibleBy', i) as string; - const options = this.getNodeParameter('options', i) as IDataObject; - // tslint:disable-next-line: no-any - const body: { accessible_by: IDataObject, [key: string]: any } = { - accessible_by: {}, - item: { - id: fileId, - type: 'file', - }, - role: (role === 'coOwner') ? 'co-owner' : noCase(role), - ...options, - }; - - if (body.fields) { - qs.fields = body.fields; - delete body.fields; - } - - if (body.expires_at) { - body.expires_at = moment.tz(body.expires_at, timezone).format(); - } - - if (body.notify) { - qs.notify = body.notify; - delete body.notify; - } - - if (accessibleBy === 'user') { - const useEmail = this.getNodeParameter('useEmail', i) as boolean; - if (useEmail) { - body.accessible_by['login'] = this.getNodeParameter('email', i) as string; - } else { - body.accessible_by['id'] = this.getNodeParameter('userId', i) as string; - } - } else { - body.accessible_by['id'] = this.getNodeParameter('groupId', i) as string; - } - - responseData = await boxApiRequest.call(this, 'POST', `/collaborations`, body, qs); - returnData.push(responseData as IDataObject); - } - // https://developer.box.com/reference/post-files-content - if (operation === 'upload') { - const parentId = this.getNodeParameter('parentId', i) as string; - const isBinaryData = this.getNodeParameter('binaryData', i) as boolean; - const fileName = this.getNodeParameter('fileName', i) as string; - - const attributes: IDataObject = {}; - - if (parentId !== '') { - attributes['parent'] = { id: parentId }; - } else { - // if not parent defined save it on the root directory - attributes['parent'] = { id: 0 }; - } - - if (isBinaryData) { - const binaryPropertyName = this.getNodeParameter('binaryPropertyName', 0) as string; - - if (items[i].binary === undefined) { - throw new NodeOperationError(this.getNode(), 'No binary data exists on item!'); - } - //@ts-ignore - if (items[i].binary[binaryPropertyName] === undefined) { - throw new NodeOperationError(this.getNode(), `No binary data property "${binaryPropertyName}" does not exists on item!`); - } - - const binaryData = (items[i].binary as IBinaryKeyData)[binaryPropertyName]; - + try { + if (resource === 'file') { + // https://developer.box.com/reference/post-files-id-copy + if (operation === 'copy') { + const fileId = this.getNodeParameter('fileId', i) as string; + const parentId = this.getNodeParameter('parentId', i) as string; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; const body: IDataObject = {}; - - attributes['name'] = fileName || binaryData.fileName; - - body['attributes'] = JSON.stringify(attributes); - - body['file'] = { - value: Buffer.from(binaryData.data, BINARY_ENCODING), - options: { - filename: binaryData.fileName, - contentType: binaryData.mimeType, - }, - }; - - responseData = await boxApiRequest.call(this, 'POST', '', {}, {}, 'https://upload.box.com/api/2.0/files/content', { formData: body }); - - returnData.push.apply(returnData, responseData.entries as IDataObject[]); - - } else { - const content = this.getNodeParameter('fileContent', i) as string; - - if (fileName === '') { - throw new NodeOperationError(this.getNode(), 'File name must be set!'); + if (additionalFields.name) { + body.name = additionalFields.name as string; } - - attributes['name'] = fileName; - - const body: IDataObject = {}; - - body['attributes'] = JSON.stringify(attributes); - - body['file'] = { - value: Buffer.from(content), - options: { - filename: fileName, - contentType: 'text/plain', - }, - }; - responseData = await boxApiRequest.call(this, 'POST', '', {}, {}, 'https://upload.box.com/api/2.0/files/content', { formData: body }); - - returnData.push.apply(returnData, responseData.entries as IDataObject[]); - } - } - } - if (resource === 'folder') { - // https://developer.box.com/reference/post-folders - if (operation === 'create') { - const name = this.getNodeParameter('name', i) as string; - const parentId = this.getNodeParameter('parentId', i) as string; - const options = this.getNodeParameter('options', i) as IDataObject; - const body: IDataObject = { - name, - }; - - if (parentId) { - body.parent = { id: parentId }; - } else { - body.parent = { id: 0 }; - } - - if (options.access) { - body.folder_upload_email = { - access: options.access as string, - }; - } - - if (options.fields) { - qs.fields = options.fields as string; - } - - responseData = await boxApiRequest.call(this, 'POST', '/folders', body, qs); - - returnData.push(responseData); - } - // https://developer.box.com/reference/delete-folders-id - if (operation === 'delete') { - const folderId = this.getNodeParameter('folderId', i) as string; - const recursive = this.getNodeParameter('recursive', i) as boolean; - qs.recursive = recursive; - - responseData = await boxApiRequest.call(this, 'DELETE', `/folders/${folderId}`, qs); - responseData = { success: true }; - returnData.push(responseData as IDataObject); - } - // https://developer.box.com/reference/get-folders-id/ - if (operation === 'get') { - const folderId = this.getNodeParameter('folderId', i) as string; - responseData = await boxApiRequest.call(this, 'GET', `/folders/${folderId}`, qs); - returnData.push(responseData as IDataObject); - } - // https://developer.box.com/reference/get-search/ - if (operation === 'search') { - const query = this.getNodeParameter('query', i) as string; - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const timezone = this.getTimezone(); - qs.type = 'folder'; - qs.query = query; - Object.assign(qs, additionalFields); - - if (qs.content_types) { - qs.content_types = (qs.content_types as string).split(','); - } - - if (additionalFields.createdRangeUi) { - const createdRangeValues = (additionalFields.createdRangeUi as IDataObject).createdRangeValuesUi as IDataObject; - if (createdRangeValues) { - qs.created_at_range = `${moment.tz(createdRangeValues.from, timezone).format()},${moment.tz(createdRangeValues.to, timezone).format()}`; - } - delete qs.createdRangeUi; - } - - if (additionalFields.updatedRangeUi) { - const updateRangeValues = (additionalFields.updatedRangeUi as IDataObject).updatedRangeValuesUi as IDataObject; - if (updateRangeValues) { - qs.updated_at_range = `${moment.tz(updateRangeValues.from, timezone).format()},${moment.tz(updateRangeValues.to, timezone).format()}`; - } - delete qs.updatedRangeUi; - } - - if (returnAll) { - responseData = await boxApiRequestAllItems.call(this, 'entries', 'GET', `/search`, {}, qs); - } else { - qs.limit = this.getNodeParameter('limit', i) as number; - responseData = await boxApiRequest.call(this, 'GET', `/search`, {}, qs); - responseData = responseData.entries; - } - returnData.push.apply(returnData, responseData as IDataObject[]); - } - // https://developer.box.com/reference/post-collaborations/ - if (operation === 'share') { - const folderId = this.getNodeParameter('folderId', i) as string; - const role = this.getNodeParameter('role', i) as string; - const accessibleBy = this.getNodeParameter('accessibleBy', i) as string; - const options = this.getNodeParameter('options', i) as IDataObject; - // tslint:disable-next-line: no-any - const body: { accessible_by: IDataObject, [key: string]: any } = { - accessible_by: {}, - item: { - id: folderId, - type: 'folder', - }, - role: (role === 'coOwner') ? 'co-owner' : noCase(role), - ...options, - }; - - if (body.fields) { - qs.fields = body.fields; - delete body.fields; - } - - if (body.expires_at) { - body.expires_at = moment.tz(body.expires_at, timezone).format(); - } - - if (body.notify) { - qs.notify = body.notify; - delete body.notify; - } - - if (accessibleBy === 'user') { - const useEmail = this.getNodeParameter('useEmail', i) as boolean; - if (useEmail) { - body.accessible_by['login'] = this.getNodeParameter('email', i) as string; + if (parentId) { + body.parent = { id: parentId }; } else { - body.accessible_by['id'] = this.getNodeParameter('userId', i) as string; + body.parent = { id: 0 }; } - } else { - body.accessible_by['id'] = this.getNodeParameter('groupId', i) as string; + if (additionalFields.fields) { + qs.fields = additionalFields.fields as string; + } + if (additionalFields.version) { + body.version = additionalFields.version as string; + } + responseData = await boxApiRequest.call(this, 'POST', `/files/${fileId}/copy`, body, qs); + + returnData.push(responseData as IDataObject); } - - responseData = await boxApiRequest.call(this, 'POST', `/collaborations`, body, qs); - returnData.push(responseData as IDataObject); - } - //https://developer.box.com/guides/folders/single/move/ - if (operation === 'update') { - const folderId = this.getNodeParameter('folderId', i) as string; - const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; - - if (updateFields.fields) { - qs.fields = updateFields.fields; - delete updateFields.fields; + // https://developer.box.com/reference/delete-files-id + if (operation === 'delete') { + const fileId = this.getNodeParameter('fileId', i) as string; + responseData = await boxApiRequest.call(this, 'DELETE', `/files/${fileId}`); + responseData = { success: true }; + returnData.push(responseData as IDataObject); } + // https://developer.box.com/reference/get-files-id-content + if (operation === 'download') { + const fileId = this.getNodeParameter('fileId', i) as string; + const dataPropertyNameDownload = this.getNodeParameter('binaryPropertyName', i) as string; + responseData = await boxApiRequest.call(this, 'GET', `/files/${fileId}`); - const body = { - ...updateFields, - } as IDataObject; + const fileName = responseData.name; - if (body.parentId) { - body.parent = { - id: body.parentId, + let mimeType: string | undefined; + + responseData = await boxApiRequest.call(this, 'GET', `/files/${fileId}/content`, {}, {}, undefined, { resolveWithFullResponse: true }); + + const newItem: INodeExecutionData = { + json: items[i].json, + binary: {}, }; - delete body.parentId; - } - if (body.tags) { - body.tags = (body.tags as string).split(','); - } + if (mimeType === undefined && responseData.headers['content-type']) { + mimeType = responseData.headers['content-type']; + } - responseData = await boxApiRequest.call(this, 'PUT', `/folders/${folderId}`, body, qs); - returnData.push(responseData as IDataObject); + if (items[i].binary !== undefined) { + // Create a shallow copy of the binary data so that the old + // data references which do not get changed still stay behind + // but the incoming data does not get changed. + Object.assign(newItem.binary, items[i].binary); + } + + items[i] = newItem; + + const data = Buffer.from(responseData.body); + + items[i].binary![dataPropertyNameDownload] = await this.helpers.prepareBinaryData(data as unknown as Buffer, fileName, mimeType); + } + // https://developer.box.com/reference/get-files-id + if (operation === 'get') { + const fileId = this.getNodeParameter('fileId', i) as string; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + if (additionalFields.fields) { + qs.fields = additionalFields.fields as string; + } + responseData = await boxApiRequest.call(this, 'GET', `/files/${fileId}`, {}, qs); + returnData.push(responseData as IDataObject); + } + // https://developer.box.com/reference/get-search/ + if (operation === 'search') { + const query = this.getNodeParameter('query', i) as string; + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const timezone = this.getTimezone(); + qs.type = 'file'; + qs.query = query; + Object.assign(qs, additionalFields); + + if (qs.content_types) { + qs.content_types = (qs.content_types as string).split(','); + } + + if (additionalFields.createdRangeUi) { + const createdRangeValues = (additionalFields.createdRangeUi as IDataObject).createdRangeValuesUi as IDataObject; + if (createdRangeValues) { + qs.created_at_range = `${moment.tz(createdRangeValues.from, timezone).format()},${moment.tz(createdRangeValues.to, timezone).format()}`; + } + delete qs.createdRangeUi; + } + + if (additionalFields.updatedRangeUi) { + const updateRangeValues = (additionalFields.updatedRangeUi as IDataObject).updatedRangeValuesUi as IDataObject; + if (updateRangeValues) { + qs.updated_at_range = `${moment.tz(updateRangeValues.from, timezone).format()},${moment.tz(updateRangeValues.to, timezone).format()}`; + } + delete qs.updatedRangeUi; + } + + if (returnAll) { + responseData = await boxApiRequestAllItems.call(this, 'entries', 'GET', `/search`, {}, qs); + } else { + qs.limit = this.getNodeParameter('limit', i) as number; + responseData = await boxApiRequest.call(this, 'GET', `/search`, {}, qs); + responseData = responseData.entries; + } + returnData.push.apply(returnData, responseData as IDataObject[]); + } + // https://developer.box.com/reference/post-collaborations/ + if (operation === 'share') { + const fileId = this.getNodeParameter('fileId', i) as string; + const role = this.getNodeParameter('role', i) as string; + const accessibleBy = this.getNodeParameter('accessibleBy', i) as string; + const options = this.getNodeParameter('options', i) as IDataObject; + // tslint:disable-next-line: no-any + const body: { accessible_by: IDataObject, [key: string]: any } = { + accessible_by: {}, + item: { + id: fileId, + type: 'file', + }, + role: (role === 'coOwner') ? 'co-owner' : noCase(role), + ...options, + }; + + if (body.fields) { + qs.fields = body.fields; + delete body.fields; + } + + if (body.expires_at) { + body.expires_at = moment.tz(body.expires_at, timezone).format(); + } + + if (body.notify) { + qs.notify = body.notify; + delete body.notify; + } + + if (accessibleBy === 'user') { + const useEmail = this.getNodeParameter('useEmail', i) as boolean; + if (useEmail) { + body.accessible_by['login'] = this.getNodeParameter('email', i) as string; + } else { + body.accessible_by['id'] = this.getNodeParameter('userId', i) as string; + } + } else { + body.accessible_by['id'] = this.getNodeParameter('groupId', i) as string; + } + + responseData = await boxApiRequest.call(this, 'POST', `/collaborations`, body, qs); + returnData.push(responseData as IDataObject); + } + // https://developer.box.com/reference/post-files-content + if (operation === 'upload') { + const parentId = this.getNodeParameter('parentId', i) as string; + const isBinaryData = this.getNodeParameter('binaryData', i) as boolean; + const fileName = this.getNodeParameter('fileName', i) as string; + + const attributes: IDataObject = {}; + + if (parentId !== '') { + attributes['parent'] = { id: parentId }; + } else { + // if not parent defined save it on the root directory + attributes['parent'] = { id: 0 }; + } + + if (isBinaryData) { + const binaryPropertyName = this.getNodeParameter('binaryPropertyName', 0) as string; + + if (items[i].binary === undefined) { + throw new NodeOperationError(this.getNode(), 'No binary data exists on item!'); + } + //@ts-ignore + if (items[i].binary[binaryPropertyName] === undefined) { + throw new NodeOperationError(this.getNode(), `No binary data property "${binaryPropertyName}" does not exists on item!`); + } + + const binaryData = (items[i].binary as IBinaryKeyData)[binaryPropertyName]; + + const body: IDataObject = {}; + + attributes['name'] = fileName || binaryData.fileName; + + body['attributes'] = JSON.stringify(attributes); + + body['file'] = { + value: Buffer.from(binaryData.data, BINARY_ENCODING), + options: { + filename: binaryData.fileName, + contentType: binaryData.mimeType, + }, + }; + + responseData = await boxApiRequest.call(this, 'POST', '', {}, {}, 'https://upload.box.com/api/2.0/files/content', { formData: body }); + + returnData.push.apply(returnData, responseData.entries as IDataObject[]); + + } else { + const content = this.getNodeParameter('fileContent', i) as string; + + if (fileName === '') { + throw new NodeOperationError(this.getNode(), 'File name must be set!'); + } + + attributes['name'] = fileName; + + const body: IDataObject = {}; + + body['attributes'] = JSON.stringify(attributes); + + body['file'] = { + value: Buffer.from(content), + options: { + filename: fileName, + contentType: 'text/plain', + }, + }; + responseData = await boxApiRequest.call(this, 'POST', '', {}, {}, 'https://upload.box.com/api/2.0/files/content', { formData: body }); + + returnData.push.apply(returnData, responseData.entries as IDataObject[]); + } + } } + if (resource === 'folder') { + // https://developer.box.com/reference/post-folders + if (operation === 'create') { + const name = this.getNodeParameter('name', i) as string; + const parentId = this.getNodeParameter('parentId', i) as string; + const options = this.getNodeParameter('options', i) as IDataObject; + const body: IDataObject = { + name, + }; + + if (parentId) { + body.parent = { id: parentId }; + } else { + body.parent = { id: 0 }; + } + + if (options.access) { + body.folder_upload_email = { + access: options.access as string, + }; + } + + if (options.fields) { + qs.fields = options.fields as string; + } + + responseData = await boxApiRequest.call(this, 'POST', '/folders', body, qs); + + returnData.push(responseData); + } + // https://developer.box.com/reference/delete-folders-id + if (operation === 'delete') { + const folderId = this.getNodeParameter('folderId', i) as string; + const recursive = this.getNodeParameter('recursive', i) as boolean; + qs.recursive = recursive; + + responseData = await boxApiRequest.call(this, 'DELETE', `/folders/${folderId}`, qs); + responseData = { success: true }; + returnData.push(responseData as IDataObject); + } + // https://developer.box.com/reference/get-folders-id/ + if (operation === 'get') { + const folderId = this.getNodeParameter('folderId', i) as string; + responseData = await boxApiRequest.call(this, 'GET', `/folders/${folderId}`, qs); + returnData.push(responseData as IDataObject); + } + // https://developer.box.com/reference/get-search/ + if (operation === 'search') { + const query = this.getNodeParameter('query', i) as string; + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const timezone = this.getTimezone(); + qs.type = 'folder'; + qs.query = query; + Object.assign(qs, additionalFields); + + if (qs.content_types) { + qs.content_types = (qs.content_types as string).split(','); + } + + if (additionalFields.createdRangeUi) { + const createdRangeValues = (additionalFields.createdRangeUi as IDataObject).createdRangeValuesUi as IDataObject; + if (createdRangeValues) { + qs.created_at_range = `${moment.tz(createdRangeValues.from, timezone).format()},${moment.tz(createdRangeValues.to, timezone).format()}`; + } + delete qs.createdRangeUi; + } + + if (additionalFields.updatedRangeUi) { + const updateRangeValues = (additionalFields.updatedRangeUi as IDataObject).updatedRangeValuesUi as IDataObject; + if (updateRangeValues) { + qs.updated_at_range = `${moment.tz(updateRangeValues.from, timezone).format()},${moment.tz(updateRangeValues.to, timezone).format()}`; + } + delete qs.updatedRangeUi; + } + + if (returnAll) { + responseData = await boxApiRequestAllItems.call(this, 'entries', 'GET', `/search`, {}, qs); + } else { + qs.limit = this.getNodeParameter('limit', i) as number; + responseData = await boxApiRequest.call(this, 'GET', `/search`, {}, qs); + responseData = responseData.entries; + } + returnData.push.apply(returnData, responseData as IDataObject[]); + } + // https://developer.box.com/reference/post-collaborations/ + if (operation === 'share') { + const folderId = this.getNodeParameter('folderId', i) as string; + const role = this.getNodeParameter('role', i) as string; + const accessibleBy = this.getNodeParameter('accessibleBy', i) as string; + const options = this.getNodeParameter('options', i) as IDataObject; + // tslint:disable-next-line: no-any + const body: { accessible_by: IDataObject, [key: string]: any } = { + accessible_by: {}, + item: { + id: folderId, + type: 'folder', + }, + role: (role === 'coOwner') ? 'co-owner' : noCase(role), + ...options, + }; + + if (body.fields) { + qs.fields = body.fields; + delete body.fields; + } + + if (body.expires_at) { + body.expires_at = moment.tz(body.expires_at, timezone).format(); + } + + if (body.notify) { + qs.notify = body.notify; + delete body.notify; + } + + if (accessibleBy === 'user') { + const useEmail = this.getNodeParameter('useEmail', i) as boolean; + if (useEmail) { + body.accessible_by['login'] = this.getNodeParameter('email', i) as string; + } else { + body.accessible_by['id'] = this.getNodeParameter('userId', i) as string; + } + } else { + body.accessible_by['id'] = this.getNodeParameter('groupId', i) as string; + } + + responseData = await boxApiRequest.call(this, 'POST', `/collaborations`, body, qs); + returnData.push(responseData as IDataObject); + } + //https://developer.box.com/guides/folders/single/move/ + if (operation === 'update') { + const folderId = this.getNodeParameter('folderId', i) as string; + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + + if (updateFields.fields) { + qs.fields = updateFields.fields; + delete updateFields.fields; + } + + const body = { + ...updateFields, + } as IDataObject; + + if (body.parentId) { + body.parent = { + id: body.parentId, + }; + delete body.parentId; + } + + if (body.tags) { + body.tags = (body.tags as string).split(','); + } + + responseData = await boxApiRequest.call(this, 'PUT', `/folders/${folderId}`, body, qs); + returnData.push(responseData as IDataObject); + } + } + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } } if (resource === 'file' && operation === 'download') { diff --git a/packages/nodes-base/nodes/Brandfetch/Brandfetch.node.ts b/packages/nodes-base/nodes/Brandfetch/Brandfetch.node.ts index 6eafcf3c01..7f949b249b 100644 --- a/packages/nodes-base/nodes/Brandfetch/Brandfetch.node.ts +++ b/packages/nodes-base/nodes/Brandfetch/Brandfetch.node.ts @@ -167,97 +167,105 @@ export class Brandfetch implements INodeType { const operation = this.getNodeParameter('operation', 0) as string; const responseData = []; for (let i = 0; i < length; i++) { - if (operation === 'logo') { - const domain = this.getNodeParameter('domain', i) as string; - const download = this.getNodeParameter('download', i) as boolean; + try { + if (operation === 'logo') { + const domain = this.getNodeParameter('domain', i) as string; + const download = this.getNodeParameter('download', i) as boolean; - const body: IDataObject = { - domain, - }; - - const response = await brandfetchApiRequest.call(this, 'POST', `/logo`, body); - - if (download === true) { - - const imageTypes = this.getNodeParameter('imageTypes', i) as string[]; - - const imageFormats = this.getNodeParameter('imageFormats', i) as string[]; - - const newItem: INodeExecutionData = { - json: {}, - binary: {}, + const body: IDataObject = { + domain, }; - if (items[i].binary !== undefined) { - // Create a shallow copy of the binary data so that the old - // data references which do not get changed still stay behind - // but the incoming data does not get changed. - Object.assign(newItem.binary, items[i].binary); - } + const response = await brandfetchApiRequest.call(this, 'POST', `/logo`, body); - newItem.json = response.response; + if (download === true) { - for (const imageType of imageTypes) { - for (const imageFormat of imageFormats) { + const imageTypes = this.getNodeParameter('imageTypes', i) as string[]; - const url = response.response[imageType][(imageFormat === 'png') ? 'image' : imageFormat] as string; + const imageFormats = this.getNodeParameter('imageFormats', i) as string[]; - if (url !== null) { - const data = await brandfetchApiRequest.call(this, 'GET', '', {}, {}, url, { json: false, encoding: null }); + const newItem: INodeExecutionData = { + json: {}, + binary: {}, + }; - newItem.binary![`${imageType}_${imageFormat}`] = await this.helpers.prepareBinaryData(data, `${imageType}_${domain}.${imageFormat}`); + if (items[i].binary !== undefined) { + // Create a shallow copy of the binary data so that the old + // data references which do not get changed still stay behind + // but the incoming data does not get changed. + Object.assign(newItem.binary, items[i].binary); + } + newItem.json = response.response; + + for (const imageType of imageTypes) { + for (const imageFormat of imageFormats) { + + const url = response.response[imageType][(imageFormat === 'png') ? 'image' : imageFormat] as string; + + if (url !== null) { + const data = await brandfetchApiRequest.call(this, 'GET', '', {}, {}, url, { json: false, encoding: null }); + + newItem.binary![`${imageType}_${imageFormat}`] = await this.helpers.prepareBinaryData(data, `${imageType}_${domain}.${imageFormat}`); + + items[i] = newItem; + } items[i] = newItem; } - items[i] = newItem; } + if (Object.keys(items[i].binary!).length === 0) { + delete items[i].binary; + } + } else { + responseData.push(response.response); } - if (Object.keys(items[i].binary!).length === 0) { - delete items[i].binary; - } - } else { + } + if (operation === 'color') { + const domain = this.getNodeParameter('domain', i) as string; + + const body: IDataObject = { + domain, + }; + + const response = await brandfetchApiRequest.call(this, 'POST', `/color`, body); responseData.push(response.response); } - } - if (operation === 'color') { - const domain = this.getNodeParameter('domain', i) as string; + if (operation === 'font') { + const domain = this.getNodeParameter('domain', i) as string; - const body: IDataObject = { - domain, - }; + const body: IDataObject = { + domain, + }; - const response = await brandfetchApiRequest.call(this, 'POST', `/color`, body); - responseData.push(response.response); - } - if (operation === 'font') { - const domain = this.getNodeParameter('domain', i) as string; + const response = await brandfetchApiRequest.call(this, 'POST', `/font`, body); + responseData.push(response.response); + } + if (operation === 'company') { + const domain = this.getNodeParameter('domain', i) as string; - const body: IDataObject = { - domain, - }; + const body: IDataObject = { + domain, + }; - const response = await brandfetchApiRequest.call(this, 'POST', `/font`, body); - responseData.push(response.response); - } - if (operation === 'company') { - const domain = this.getNodeParameter('domain', i) as string; + const response = await brandfetchApiRequest.call(this, 'POST', `/company`, body); + responseData.push(response.response); + } + if (operation === 'industry') { + const domain = this.getNodeParameter('domain', i) as string; - const body: IDataObject = { - domain, - }; + const body: IDataObject = { + domain, + }; - const response = await brandfetchApiRequest.call(this, 'POST', `/company`, body); - responseData.push(response.response); - } - if (operation === 'industry') { - const domain = this.getNodeParameter('domain', i) as string; - - const body: IDataObject = { - domain, - }; - - const response = await brandfetchApiRequest.call(this, 'POST', `/industry`, body); - responseData.push.apply(responseData, response.response); + const response = await brandfetchApiRequest.call(this, 'POST', `/industry`, body); + responseData.push.apply(responseData, response.response); + } + } catch (error) { + if (this.continueOnFail()) { + responseData.push({ error: error.message }); + continue; + } + throw error; } } diff --git a/packages/nodes-base/nodes/Chargebee/Chargebee.node.ts b/packages/nodes-base/nodes/Chargebee/Chargebee.node.ts index ccbb19b65b..36aa052cfd 100644 --- a/packages/nodes-base/nodes/Chargebee/Chargebee.node.ts +++ b/packages/nodes-base/nodes/Chargebee/Chargebee.node.ts @@ -502,139 +502,146 @@ export class Chargebee implements INodeType { let qs: IDataObject; for (let i = 0; i < items.length; i++) { - - item = items[i]; - const resource = this.getNodeParameter('resource', i) as string; - const operation = this.getNodeParameter('operation', i) as string; - - let requestMethod = 'GET'; - let endpoint = ''; - body = {}; - qs = {}; - if (resource === 'customer') { - if (operation === 'create') { - // ---------------------------------- - // create - // ---------------------------------- - - requestMethod = 'POST'; - - const properties = this.getNodeParameter('properties', i, {}) as IDataObject; - - for (const key of Object.keys(properties)) { - if (key === 'customProperties' && (properties.customProperties as IDataObject).property !== undefined) { - for (const customProperty of (properties.customProperties as IDataObject)!.property! as CustomProperty[]) { - qs[customProperty.name] = customProperty.value; - } - } else { - qs[key] = properties[key]; - } - } - - endpoint = `customers`; - } else { - throw new NodeOperationError(this.getNode(), `The operation "${operation}" is not known!`); - } - - } else if (resource === 'invoice') { - if (operation === 'list') { - // ---------------------------------- - // list - // ---------------------------------- - - endpoint = 'invoices'; - // TODO: Make also sorting configurable - qs['sort_by[desc]'] = 'date'; - - qs.limit = this.getNodeParameter('maxResults', i, {}); - - const setFilters: FilterValues = this.getNodeParameter('filters', i, {}) as unknown as FilterValues; - - let filter: FilterValue; - let value: NodeParameterValue; - - for (const filterProperty of Object.keys(setFilters)) { - for (filter of setFilters[filterProperty]) { - value = filter.value; - if (filterProperty === 'date') { - value = Math.floor(new Date(value as string).getTime() / 1000); - } - qs[`${filterProperty}[${filter.operation}]`] = value; - } - } - } else if (operation === 'pdfUrl') { - // ---------------------------------- - // pdfUrl - // ---------------------------------- - - requestMethod = 'POST'; - const invoiceId = this.getNodeParameter('invoiceId', i) as string; - endpoint = `invoices/${invoiceId.trim()}/pdf`; - } else { - throw new NodeOperationError(this.getNode(), `The operation "${operation}" is not known!`); - } - - } else if (resource === 'subscription') { - if (operation === 'cancel') { - // ---------------------------------- - // cancel - // ---------------------------------- - - requestMethod = 'POST'; - - const subscriptionId = this.getNodeParameter('subscriptionId', i, '') as string; - body.end_of_term = this.getNodeParameter('endOfTerm', i, false) as boolean; - - endpoint = `subscriptions/${subscriptionId.trim()}/cancel`; - } else if (operation === 'delete') { - // ---------------------------------- - // delete - // ---------------------------------- - - requestMethod = 'POST'; - - const subscriptionId = this.getNodeParameter('subscriptionId', i, '') as string; - - endpoint = `subscriptions/${subscriptionId.trim()}/delete`; - } else { - throw new NodeOperationError(this.getNode(), `The operation "${operation}" is not known!`); - } - } else { - throw new NodeOperationError(this.getNode(), `The resource "${resource}" is not known!`); - } - - const options = { - method: requestMethod, - body, - qs, - uri: `${baseUrl}/${endpoint}`, - auth: { - user: credentials.apiKey as string, - pass: '', - }, - json: true, - }; - - let responseData; - try { - responseData = await this.helpers.request!(options); + item = items[i]; + const resource = this.getNodeParameter('resource', i) as string; + const operation = this.getNodeParameter('operation', i) as string; + + let requestMethod = 'GET'; + let endpoint = ''; + body = {}; + qs = {}; + if (resource === 'customer') { + if (operation === 'create') { + // ---------------------------------- + // create + // ---------------------------------- + + requestMethod = 'POST'; + + const properties = this.getNodeParameter('properties', i, {}) as IDataObject; + + for (const key of Object.keys(properties)) { + if (key === 'customProperties' && (properties.customProperties as IDataObject).property !== undefined) { + for (const customProperty of (properties.customProperties as IDataObject)!.property! as CustomProperty[]) { + qs[customProperty.name] = customProperty.value; + } + } else { + qs[key] = properties[key]; + } + } + + endpoint = `customers`; + } else { + throw new NodeOperationError(this.getNode(), `The operation "${operation}" is not known!`); + } + + } else if (resource === 'invoice') { + if (operation === 'list') { + // ---------------------------------- + // list + // ---------------------------------- + + endpoint = 'invoices'; + // TODO: Make also sorting configurable + qs['sort_by[desc]'] = 'date'; + + qs.limit = this.getNodeParameter('maxResults', i, {}); + + const setFilters: FilterValues = this.getNodeParameter('filters', i, {}) as unknown as FilterValues; + + let filter: FilterValue; + let value: NodeParameterValue; + + for (const filterProperty of Object.keys(setFilters)) { + for (filter of setFilters[filterProperty]) { + value = filter.value; + if (filterProperty === 'date') { + value = Math.floor(new Date(value as string).getTime() / 1000); + } + qs[`${filterProperty}[${filter.operation}]`] = value; + } + } + } else if (operation === 'pdfUrl') { + // ---------------------------------- + // pdfUrl + // ---------------------------------- + + requestMethod = 'POST'; + const invoiceId = this.getNodeParameter('invoiceId', i) as string; + endpoint = `invoices/${invoiceId.trim()}/pdf`; + } else { + throw new NodeOperationError(this.getNode(), `The operation "${operation}" is not known!`); + } + + } else if (resource === 'subscription') { + if (operation === 'cancel') { + // ---------------------------------- + // cancel + // ---------------------------------- + + requestMethod = 'POST'; + + const subscriptionId = this.getNodeParameter('subscriptionId', i, '') as string; + body.end_of_term = this.getNodeParameter('endOfTerm', i, false) as boolean; + + endpoint = `subscriptions/${subscriptionId.trim()}/cancel`; + } else if (operation === 'delete') { + // ---------------------------------- + // delete + // ---------------------------------- + + requestMethod = 'POST'; + + const subscriptionId = this.getNodeParameter('subscriptionId', i, '') as string; + + endpoint = `subscriptions/${subscriptionId.trim()}/delete`; + } else { + throw new NodeOperationError(this.getNode(), `The operation "${operation}" is not known!`); + } + } else { + throw new NodeOperationError(this.getNode(), `The resource "${resource}" is not known!`); + } + + const options = { + method: requestMethod, + body, + qs, + uri: `${baseUrl}/${endpoint}`, + auth: { + user: credentials.apiKey as string, + pass: '', + }, + json: true, + }; + + let responseData; + + try { + responseData = await this.helpers.request!(options); + } catch (error) { + throw new NodeApiError(this.getNode(), error); + } + + if (resource === 'invoice' && operation === 'list') { + responseData.list.forEach((data: IDataObject) => { + returnData.push(data.invoice as IDataObject); + }); + } else if (resource === 'invoice' && operation === 'pdfUrl') { + const data: IDataObject = {}; + Object.assign(data, items[i].json); + + data.pdfUrl = responseData.download.download_url; + returnData.push(data); + } else { + returnData.push(responseData); + } } catch (error) { - throw new NodeApiError(this.getNode(), error); - } - - if (resource === 'invoice' && operation === 'list') { - responseData.list.forEach((data: IDataObject) => { - returnData.push(data.invoice as IDataObject); - }); - } else if (resource === 'invoice' && operation === 'pdfUrl') { - const data: IDataObject = {}; - Object.assign(data, items[i].json); - - data.pdfUrl = responseData.download.download_url; - returnData.push(data); - } else { - returnData.push(responseData); + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } } diff --git a/packages/nodes-base/nodes/CircleCi/CircleCi.node.ts b/packages/nodes-base/nodes/CircleCi/CircleCi.node.ts index da04359539..20be7df4d3 100644 --- a/packages/nodes-base/nodes/CircleCi/CircleCi.node.ts +++ b/packages/nodes-base/nodes/CircleCi/CircleCi.node.ts @@ -69,70 +69,78 @@ export class CircleCi implements INodeType { const operation = this.getNodeParameter('operation', 0) as string; for (let i = 0; i < length; i++) { - if (resource === 'pipeline') { - if (operation === 'get') { - const vcs = this.getNodeParameter('vcs', i) as string; - let slug = this.getNodeParameter('projectSlug', i) as string; - const pipelineNumber = this.getNodeParameter('pipelineNumber', i) as number; + try { + if (resource === 'pipeline') { + if (operation === 'get') { + const vcs = this.getNodeParameter('vcs', i) as string; + let slug = this.getNodeParameter('projectSlug', i) as string; + const pipelineNumber = this.getNodeParameter('pipelineNumber', i) as number; - slug = slug.replace(new RegExp(/\//g), '%2F'); + slug = slug.replace(new RegExp(/\//g), '%2F'); - const endpoint = `/project/${vcs}/${slug}/pipeline/${pipelineNumber}`; + const endpoint = `/project/${vcs}/${slug}/pipeline/${pipelineNumber}`; - responseData = await circleciApiRequest.call(this, 'GET', endpoint, {}, qs); - } - if (operation === 'getAll') { - const vcs = this.getNodeParameter('vcs', i) as string; - const filters = this.getNodeParameter('filters', i) as IDataObject; - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - let slug = this.getNodeParameter('projectSlug', i) as string; - - slug = slug.replace(new RegExp(/\//g), '%2F'); - - if (filters.branch) { - qs.branch = filters.branch; - } - - const endpoint = `/project/${vcs}/${slug}/pipeline`; - - if (returnAll === true) { - responseData = await circleciApiRequestAllItems.call(this, 'items', 'GET', endpoint, {}, qs); - - } else { - qs.limit = this.getNodeParameter('limit', i) as number; responseData = await circleciApiRequest.call(this, 'GET', endpoint, {}, qs); - responseData = responseData.items; - responseData = responseData.splice(0, qs.limit); + } + if (operation === 'getAll') { + const vcs = this.getNodeParameter('vcs', i) as string; + const filters = this.getNodeParameter('filters', i) as IDataObject; + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + let slug = this.getNodeParameter('projectSlug', i) as string; + + slug = slug.replace(new RegExp(/\//g), '%2F'); + + if (filters.branch) { + qs.branch = filters.branch; + } + + const endpoint = `/project/${vcs}/${slug}/pipeline`; + + if (returnAll === true) { + responseData = await circleciApiRequestAllItems.call(this, 'items', 'GET', endpoint, {}, qs); + + } else { + qs.limit = this.getNodeParameter('limit', i) as number; + responseData = await circleciApiRequest.call(this, 'GET', endpoint, {}, qs); + responseData = responseData.items; + responseData = responseData.splice(0, qs.limit); + } + } + + if (operation === 'trigger') { + const vcs = this.getNodeParameter('vcs', i) as string; + let slug = this.getNodeParameter('projectSlug', i) as string; + + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + + slug = slug.replace(new RegExp(/\//g), '%2F'); + + const endpoint = `/project/${vcs}/${slug}/pipeline`; + + const body: IDataObject = {}; + + if (additionalFields.branch) { + body.branch = additionalFields.branch as string; + } + + if (additionalFields.tag) { + body.tag = additionalFields.tag as string; + } + + responseData = await circleciApiRequest.call(this, 'POST', endpoint, body, qs); } } - - if (operation === 'trigger') { - const vcs = this.getNodeParameter('vcs', i) as string; - let slug = this.getNodeParameter('projectSlug', i) as string; - - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - - slug = slug.replace(new RegExp(/\//g), '%2F'); - - const endpoint = `/project/${vcs}/${slug}/pipeline`; - - const body: IDataObject = {}; - - if (additionalFields.branch) { - body.branch = additionalFields.branch as string; - } - - if (additionalFields.tag) { - body.tag = additionalFields.tag as string; - } - - responseData = await circleciApiRequest.call(this, 'POST', endpoint, body, qs); + if (Array.isArray(responseData)) { + returnData.push.apply(returnData, responseData as IDataObject[]); + } else { + returnData.push(responseData as IDataObject); } - } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else { - returnData.push(responseData as IDataObject); + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } } return [this.helpers.returnJsonArray(returnData)]; diff --git a/packages/nodes-base/nodes/Clearbit/Clearbit.node.ts b/packages/nodes-base/nodes/Clearbit/Clearbit.node.ts index 2d5820c18b..447d99e319 100644 --- a/packages/nodes-base/nodes/Clearbit/Clearbit.node.ts +++ b/packages/nodes-base/nodes/Clearbit/Clearbit.node.ts @@ -81,70 +81,78 @@ export class Clearbit implements INodeType { 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 === 'person') { - if (operation === 'enrich') { - const email = this.getNodeParameter('email', i) as string; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - qs.email = email; - if (additionalFields.givenName) { - qs.given_name = additionalFields.givenName as string; + try { + if (resource === 'person') { + if (operation === 'enrich') { + const email = this.getNodeParameter('email', i) as string; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + qs.email = email; + if (additionalFields.givenName) { + qs.given_name = additionalFields.givenName as string; + } + if (additionalFields.familyName) { + qs.family_name = additionalFields.familyName as string; + } + if (additionalFields.ipAddress) { + qs.ip_address = additionalFields.ipAddress as string; + } + if (additionalFields.location) { + qs.location = additionalFields.location as string; + } + if (additionalFields.company) { + qs.company = additionalFields.company as string; + } + if (additionalFields.companyDomain) { + qs.company_domain = additionalFields.companyDomain as string; + } + if (additionalFields.linkedIn) { + qs.linkedin = additionalFields.linkedIn as string; + } + if (additionalFields.twitter) { + qs.twitter = additionalFields.twitter as string; + } + if (additionalFields.facebook) { + qs.facebook = additionalFields.facebook as string; + } + responseData = await clearbitApiRequest.call(this, 'GET', `${resource}-stream`, '/v2/people/find', {}, qs); } - if (additionalFields.familyName) { - qs.family_name = additionalFields.familyName as string; - } - if (additionalFields.ipAddress) { - qs.ip_address = additionalFields.ipAddress as string; - } - if (additionalFields.location) { - qs.location = additionalFields.location as string; - } - if (additionalFields.company) { - qs.company = additionalFields.company as string; - } - if (additionalFields.companyDomain) { - qs.company_domain = additionalFields.companyDomain as string; - } - if (additionalFields.linkedIn) { - qs.linkedin = additionalFields.linkedIn as string; - } - if (additionalFields.twitter) { - qs.twitter = additionalFields.twitter as string; - } - if (additionalFields.facebook) { - qs.facebook = additionalFields.facebook as string; - } - responseData = await clearbitApiRequest.call(this, 'GET', `${resource}-stream`, '/v2/people/find', {}, qs); } - } - if (resource === 'company') { - if (operation === 'enrich') { - const domain = this.getNodeParameter('domain', i) as string; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - qs.domain = domain; - if (additionalFields.companyName) { - qs.company_name = additionalFields.companyName as string; + if (resource === 'company') { + if (operation === 'enrich') { + const domain = this.getNodeParameter('domain', i) as string; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + qs.domain = domain; + if (additionalFields.companyName) { + qs.company_name = additionalFields.companyName as string; + } + if (additionalFields.linkedin) { + qs.linkedin = additionalFields.linkedin as string; + } + if (additionalFields.twitter) { + qs.twitter = additionalFields.twitter as string; + } + if (additionalFields.facebook) { + qs.facebook = additionalFields.facebook as string; + } + responseData = await clearbitApiRequest.call(this, 'GET', `${resource}-stream`, '/v2/companies/find', {}, qs); } - if (additionalFields.linkedin) { - qs.linkedin = additionalFields.linkedin as string; + if (operation === 'autocomplete') { + const name = this.getNodeParameter('name', i) as string; + qs.query = name; + responseData = await clearbitApiRequest.call(this, 'GET', 'autocomplete', '/v1/companies/suggest', {}, qs); } - if (additionalFields.twitter) { - qs.twitter = additionalFields.twitter as string; - } - if (additionalFields.facebook) { - qs.facebook = additionalFields.facebook as string; - } - responseData = await clearbitApiRequest.call(this, 'GET', `${resource}-stream`, '/v2/companies/find', {}, qs); } - if (operation === 'autocomplete') { - const name = this.getNodeParameter('name', i) as string; - qs.query = name; - responseData = await clearbitApiRequest.call(this, 'GET', 'autocomplete', '/v1/companies/suggest', {}, qs); + if (Array.isArray(responseData)) { + returnData.push.apply(returnData, responseData as IDataObject[]); + } else { + returnData.push(responseData as IDataObject); } - } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else { - returnData.push(responseData as IDataObject); + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } } return [this.helpers.returnJsonArray(returnData)]; diff --git a/packages/nodes-base/nodes/ClickUp/ClickUp.node.ts b/packages/nodes-base/nodes/ClickUp/ClickUp.node.ts index 09d4dfc97b..97c7e1d189 100644 --- a/packages/nodes-base/nodes/ClickUp/ClickUp.node.ts +++ b/packages/nodes-base/nodes/ClickUp/ClickUp.node.ts @@ -482,950 +482,958 @@ export class ClickUp implements INodeType { const operation = this.getNodeParameter('operation', 0) as string; for (let i = 0; i < length; i++) { - if (resource === 'checklist') { - if (operation === 'create') { - const taskId = this.getNodeParameter('task', i) as string; - const name = this.getNodeParameter('name', i) as string; - const body: IDataObject = { - name, - }; - responseData = await clickupApiRequest.call(this, 'POST', `/task/${taskId}/checklist`, body); - responseData = responseData.checklist; - } - if (operation === 'delete') { - const checklistId = this.getNodeParameter('checklist', i) as string; - responseData = await clickupApiRequest.call(this, 'DELETE', `/checklist/${checklistId}`); - responseData = { success: true }; - } - if (operation === 'update') { - const checklistId = this.getNodeParameter('checklist', i) as string; - const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; - const body: IDataObject = {}; - if (updateFields.name) { - body.name = updateFields.name as string; - } - if (updateFields.position) { - body.position = updateFields.position as number; - } - responseData = await clickupApiRequest.call(this, 'PUT', `/checklist/${checklistId}`, body); - responseData = responseData.checklist; - } - } - if (resource === 'checklistItem') { - if (operation === 'create') { - const checklistId = this.getNodeParameter('checklist', i) as string; - const name = this.getNodeParameter('name', i) as string; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const body: IDataObject = { - name, - }; - if (additionalFields.assignee) { - body.assignee = parseInt(additionalFields.assignee as string, 10); - } - responseData = await clickupApiRequest.call(this, 'POST', `/checklist/${checklistId}/checklist_item`, body); - responseData = responseData.checklist; - } - if (operation === 'delete') { - const checklistId = this.getNodeParameter('checklist', i) as string; - const checklistItemId = this.getNodeParameter('checklistItem', i) as string; - responseData = await clickupApiRequest.call(this, 'DELETE', `/checklist/${checklistId}/checklist_item/${checklistItemId}`); - responseData = { success: true }; - } - if (operation === 'update') { - const checklistId = this.getNodeParameter('checklist', i) as string; - const checklistItemId = this.getNodeParameter('checklistItem', i) as string; - const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; - const body: IDataObject = {}; - if (updateFields.name) { - body.name = updateFields.name as string; - } - if (updateFields.parent) { - body.parent = updateFields.parent as string; - } - if (updateFields.assignee) { - body.assignee = parseInt(updateFields.assignee as string, 10); - } - if (updateFields.resolved) { - body.resolved = updateFields.resolved as boolean; - } - responseData = await clickupApiRequest.call(this, 'PUT', `/checklist/${checklistId}/checklist_item/${checklistItemId}`, body); - responseData = responseData.checklist; - } - } - if (resource === 'comment') { - if (operation === 'create') { - const resource = this.getNodeParameter('commentOn', i) as string; - const id = this.getNodeParameter('id', i) as string; - const commentText = this.getNodeParameter('commentText', i) as string; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const body: IDataObject = { - comment_text: commentText, - }; - if (additionalFields.assignee) { - body.assignee = parseInt(additionalFields.assignee as string, 10); - } - if (additionalFields.notifyAll) { - body.notify_all = additionalFields.notifyAll as boolean; - } - responseData = await clickupApiRequest.call(this, 'POST', `/${resource}/${id}/comment`, body); - } - if (operation === 'delete') { - const commentId = this.getNodeParameter('comment', i) as string; - responseData = await clickupApiRequest.call(this, 'DELETE', `/comment/${commentId}`); - responseData = { success: true }; - } - if (operation === 'getAll') { - const resource = this.getNodeParameter('commentsOn', i) as string; - const id = this.getNodeParameter('id', i) as string; - qs.limit = this.getNodeParameter('limit', i) as number; - responseData = await clickupApiRequest.call(this, 'GET', `/${resource}/${id}/comment`, {}, qs); - responseData = responseData.comments; - responseData = responseData.splice(0, qs.limit); - } - if (operation === 'update') { - const commentId = this.getNodeParameter('comment', i) as string; - const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; - const body: IDataObject = {}; - if (updateFields.commentText) { - body.comment_text = updateFields.commentText as string; - } - if (updateFields.assignee) { - body.assignee = parseInt(updateFields.assignee as string, 10); - } - if (updateFields.resolved) { - body.resolved = updateFields.resolved as boolean; - } - responseData = await clickupApiRequest.call(this, 'PUT', `/comment/${commentId}`, body); - responseData = { success: true }; - } - } - if (resource === 'folder') { - if (operation === 'create') { - const spaceId = this.getNodeParameter('space', i) as string; - const name = this.getNodeParameter('name', i) as string; - const body: IDataObject = { - name, - }; - responseData = await clickupApiRequest.call(this, 'POST', `/space/${spaceId}/folder`, body); - } - if (operation === 'delete') { - const folderId = this.getNodeParameter('folder', i) as string; - responseData = await clickupApiRequest.call(this, 'DELETE', `/folder/${folderId}`); - responseData = { success: true }; - } - if (operation === 'get') { - const folderId = this.getNodeParameter('folder', i) as string; - responseData = await clickupApiRequest.call(this, 'GET', `/folder/${folderId}`); - } - if (operation === 'getAll') { - const filters = this.getNodeParameter('filters', i) as IDataObject; - const spaceId = this.getNodeParameter('space', i) as string; - if (filters.archived) { - qs.archived = filters.archived as boolean; - } - qs.limit = this.getNodeParameter('limit', i) as number; - responseData = await clickupApiRequest.call(this, 'GET', `/space/${spaceId}/folder`, {}, qs); - responseData = responseData.folders; - responseData = responseData.splice(0, qs.limit); - } - if (operation === 'update') { - const folderId = this.getNodeParameter('folder', i) as string; - const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; - const body: IDataObject = {}; - if (updateFields.name) { - body.name = updateFields.name as string; - } - responseData = await clickupApiRequest.call(this, 'PUT', `/folder/${folderId}`, body); - } - } - if (resource === 'goal') { - if (operation === 'create') { - const teamId = this.getNodeParameter('team', i) as string; - const name = this.getNodeParameter('name', i) as string; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const body: IDataObject = { - name, - }; - if (additionalFields.dueDate) { - body.due_date = new Date(additionalFields.dueDate as string).getTime(); - } - if (additionalFields.description) { - body.description = additionalFields.description as string; - } - if (additionalFields.multipleOwners) { - body.multiple_owners = additionalFields.multipleOwners as boolean; - } - if (additionalFields.color) { - body.color = additionalFields.color as string; - } - if (additionalFields.owners) { - body.owners = ((additionalFields.owners as string).split(',') as string[]).map((e: string) => parseInt(e, 10)); - } - responseData = await clickupApiRequest.call(this, 'POST', `/team/${teamId}/goal`, body); - responseData = responseData.goal; - } - if (operation === 'delete') { - const goalId = this.getNodeParameter('goal', i) as string; - responseData = await clickupApiRequest.call(this, 'DELETE', `/goal/${goalId}`); - responseData = { success: true }; - } - if (operation === 'get') { - const goalId = this.getNodeParameter('goal', i) as string; - responseData = await clickupApiRequest.call(this, 'GET', `/goal/${goalId}`); - responseData = responseData.goal; - } - if (operation === 'getAll') { - const teamId = this.getNodeParameter('team', i) as string; - qs.limit = this.getNodeParameter('limit', i) as number; - responseData = await clickupApiRequest.call(this, 'GET', `/team/${teamId}/goal`, {}, qs); - responseData = responseData.goals; - responseData = responseData.splice(0, qs.limit); - - } - if (operation === 'update') { - const goalId = this.getNodeParameter('goal', i) as string; - const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; - const body: IDataObject = {}; - if (updateFields.name) { - body.name = updateFields.name as string; - } - if (updateFields.dueDate) { - body.due_date = new Date(updateFields.dueDate as string).getTime(); - } - if (updateFields.description) { - body.description = updateFields.description as string; - } - if (updateFields.color) { - body.color = updateFields.color as string; - } - if (updateFields.addOwners) { - body.add_owners = ((updateFields.addOwners as string).split(',') as string[]).map((e: string) => parseInt(e, 10)) as number[]; - } - if (updateFields.removeOwners) { - body.rem_owners = ((updateFields.removeOwners as string).split(',') as string[]).map((e: string) => parseInt(e, 10)) as number[]; - } - responseData = await clickupApiRequest.call(this, 'PUT', `/goal/${goalId}`, body); - responseData = responseData.goal; - } - } - if (resource === 'goalKeyResult') { - if (operation === 'create') { - const goalId = this.getNodeParameter('goal', i) as string; - const name = this.getNodeParameter('name', i) as string; - const type = this.getNodeParameter('type', i) as string; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const body: IDataObject = { - name, - type, - }; - if (type === 'number' || type === 'currency') { - if (!additionalFields.unit) { - throw new NodeOperationError(this.getNode(), 'Unit field must be set'); - } - } - if (type === 'number' || type === 'percentaje' - || type === 'automatic' || type === 'currency') { - if (additionalFields.stepsStart === undefined - || !additionalFields.stepsEnd === undefined) { - throw new NodeOperationError(this.getNode(), 'Steps start and steps end fields must be set'); - } - } - if (additionalFields.unit) { - body.unit = additionalFields.unit as string; - } - if (additionalFields.stepsStart) { - body.steps_start = additionalFields.stepsStart as number; - } - if (additionalFields.stepsEnd) { - body.steps_end = additionalFields.stepsEnd as number; - } - if (additionalFields.taskIds) { - body.task_ids = (additionalFields.taskIds as string).split(','); - } - if (additionalFields.listIds) { - body.list_ids = (additionalFields.listIds as string).split(','); - } - if (additionalFields.owners) { - body.owners = ((additionalFields.owners as string).split(',') as string[]).map((e: string) => parseInt(e, 10)); - } - responseData = await clickupApiRequest.call(this, 'POST', `/goal/${goalId}/key_result`, body); - responseData = responseData.key_result; - } - if (operation === 'delete') { - const keyResultId = this.getNodeParameter('keyResult', i) as string; - responseData = await clickupApiRequest.call(this, 'DELETE', `/key_result/${keyResultId}`); - responseData = { success: true }; - } - if (operation === 'update') { - const keyResultId = this.getNodeParameter('keyResult', i) as string; - const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; - const body: IDataObject = {}; - if (updateFields.name) { - body.name = updateFields.name as string; - } - if (updateFields.note) { - body.note = updateFields.note as string; - } - if (updateFields.stepsCurrent) { - body.steps_current = updateFields.stepsCurrent as number; - } - if (updateFields.stepsStart) { - body.steps_start = updateFields.stepsStart as number; - } - if (updateFields.stepsEnd) { - body.steps_end = updateFields.stepsEnd as number; - } - if (updateFields.unit) { - body.unit = updateFields.unit as string; - } - responseData = await clickupApiRequest.call(this, 'PUT', `/key_result/${keyResultId}`, body); - responseData = responseData.key_result; - } - } - if (resource === 'guest') { - if (operation === 'create') { - const teamId = this.getNodeParameter('team', i) as string; - const email = this.getNodeParameter('email', i) as string; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const body: IDataObject = { - email, - }; - if (additionalFields.canEditTags) { - body.can_edit_tags = additionalFields.canEditTags as boolean; - } - if (additionalFields.canSeeTimeSpend) { - body.can_see_time_spend = additionalFields.canSeeTimeSpend as boolean; - } - if (additionalFields.canSeeTimeEstimated) { - body.can_see_time_estimated = additionalFields.canSeeTimeEstimated as boolean; - } - responseData = await clickupApiRequest.call(this, 'POST', `/team/${teamId}/guest`, body); - responseData = responseData.team; - } - if (operation === 'delete') { - const teamId = this.getNodeParameter('team', i) as string; - const guestId = this.getNodeParameter('guest', i) as string; - responseData = await clickupApiRequest.call(this, 'DELETE', `/team/${teamId}/guest/${guestId}`); - responseData = { success: true }; - } - if (operation === 'get') { - const teamId = this.getNodeParameter('team', i) as string; - const guestId = this.getNodeParameter('guest', i) as string; - responseData = await clickupApiRequest.call(this, 'GET', `/team/${teamId}/guest/${guestId}`); - responseData = responseData.team; - } - if (operation === 'update') { - const teamId = this.getNodeParameter('team', i) as string; - const guestId = this.getNodeParameter('guest', i) as string; - const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; - const body: IDataObject = {}; - if (updateFields.username) { - body.username = updateFields.username as string; - } - if (updateFields.canEditTags) { - body.can_edit_tags = updateFields.canEditTags as boolean; - } - if (updateFields.canSeeTimeSpend) { - body.can_see_time_spend = updateFields.canSeeTimeSpend as boolean; - } - if (updateFields.canSeeTimeEstimated) { - body.can_see_time_estimated = updateFields.canSeeTimeEstimated as boolean; - } - responseData = await clickupApiRequest.call(this, 'PUT', `/team/${teamId}/guest/${guestId}`, body); - responseData = responseData.team; - } - } - if (resource === 'task') { - if (operation === 'create') { - const listId = this.getNodeParameter('list', i) as string; - const name = this.getNodeParameter('name', i) as string; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const body: ITask = { - name, - }; - if (additionalFields.customFieldsJson) { - const customFields = validateJSON(additionalFields.customFieldsJson as string); - if (customFields === undefined) { - throw new NodeOperationError(this.getNode(), 'Custom Fields: Invalid JSON'); - } - body.custom_fields = customFields; - } - if (additionalFields.content) { - body.content = additionalFields.content as string; - } - if (additionalFields.assignees) { - body.assignees = additionalFields.assignees as string[]; - } - if (additionalFields.tags) { - body.tags = additionalFields.tags as string[]; - } - if (additionalFields.status) { - body.status = additionalFields.status as string; - } - if (additionalFields.priority) { - body.priority = additionalFields.priority as number; - } - if (additionalFields.dueDate) { - body.due_date = new Date(additionalFields.dueDate as string).getTime(); - } - if (additionalFields.dueDateTime) { - body.due_date_time = additionalFields.dueDateTime as boolean; - } - if (additionalFields.timeEstimate) { - body.time_estimate = (additionalFields.timeEstimate as number) * 6000; - } - if (additionalFields.startDate) { - body.start_date = new Date(additionalFields.startDate as string).getTime(); - } - if (additionalFields.startDateTime) { - body.start_date_time = additionalFields.startDateTime as boolean; - } - if (additionalFields.notifyAll) { - body.notify_all = additionalFields.notifyAll as boolean; - } - if (additionalFields.parentId) { - body.parent = additionalFields.parentId as string; - } - if (additionalFields.markdownContent) { - delete body.content; - body.markdown_content = additionalFields.content as string; - } - responseData = await clickupApiRequest.call(this, 'POST', `/list/${listId}/task`, body); - } - if (operation === 'update') { - const taskId = this.getNodeParameter('id', i) as string; - const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; - const body: ITask = { - assignees: { - add: [], - rem: [], - }, - }; - if (updateFields.content) { - body.content = updateFields.content as string; - } - if (updateFields.priority) { - body.priority = updateFields.priority as number; - } - if (updateFields.dueDate) { - body.due_date = new Date(updateFields.dueDate as string).getTime(); - } - if (updateFields.dueDateTime) { - body.due_date_time = updateFields.dueDateTime as boolean; - } - if (updateFields.timeEstimate) { - body.time_estimate = (updateFields.timeEstimate as number) * 6000; - } - if (updateFields.startDate) { - body.start_date = new Date(updateFields.startDate as string).getTime(); - } - if (updateFields.startDateTime) { - body.start_date_time = updateFields.startDateTime as boolean; - } - if (updateFields.notifyAll) { - body.notify_all = updateFields.notifyAll as boolean; - } - if (updateFields.name) { - body.name = updateFields.name as string; - } - if (updateFields.parentId) { - body.parent = updateFields.parentId as string; - } - if (updateFields.addAssignees) { - //@ts-ignore - body.assignees.add = ((updateFields.addAssignees as string).split(',') as string[]).map((e: string) => parseInt(e, 10)); - } - if (updateFields.removeAssignees) { - //@ts-ignore - body.assignees.rem = ((updateFields.removeAssignees as string).split(',') as string[]).map((e: string) => parseInt(e, 10)); - } - if (updateFields.status) { - body.status = updateFields.status as string; - } - if (updateFields.markdownContent) { - delete body.content; - body.markdown_content = updateFields.content as string; - } - responseData = await clickupApiRequest.call(this, 'PUT', `/task/${taskId}`, body); - } - if (operation === 'get') { - const taskId = this.getNodeParameter('id', i) as string; - responseData = await clickupApiRequest.call(this, 'GET', `/task/${taskId}`); - } - if (operation === 'getAll') { - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - const filters = this.getNodeParameter('filters', i) as IDataObject; - if (filters.archived) { - qs.archived = filters.archived as boolean; - } - if (filters.subtasks) { - qs.subtasks = filters.subtasks as boolean; - } - if (filters.includeClosed) { - qs.include_closed = filters.includeClosed as boolean; - } - if (filters.orderBy) { - qs.order_by = filters.orderBy as string; - } - if (filters.statuses) { - qs.statuses = filters.statuses as string[]; - } - if (filters.assignees) { - qs.assignees = filters.assignees as string[]; - } - if (filters.tags) { - qs.tags = filters.tags as string[]; - } - if (filters.dueDateGt) { - qs.due_date_gt = new Date(filters.dueDateGt as string).getTime(); - } - if (filters.dueDateLt) { - qs.due_date_lt = new Date(filters.dueDateLt as string).getTime(); - } - if (filters.dateCreatedGt) { - qs.date_created_gt = new Date(filters.dateCreatedGt as string).getTime(); - } - if (filters.dateCreatedLt) { - qs.date_created_lt = new Date(filters.dateCreatedLt as string).getTime(); - } - if (filters.dateUpdatedGt) { - qs.date_updated_gt = new Date(filters.dateUpdatedGt as string).getTime(); - } - if (filters.dateUpdatedLt) { - qs.date_updated_lt = new Date(filters.dateUpdatedLt as string).getTime(); - } - if (filters.customFieldsUi) { - const customFieldsValues = (filters.customFieldsUi as IDataObject).customFieldsValues as IDataObject[]; - if (customFieldsValues) { - const customFields: IDataObject[] = []; - for (const customFieldValue of customFieldsValues) { - customFields.push({ - field_id: customFieldValue.fieldId, - operator: (customFieldValue.operator === 'equal') ? '=' : customFieldValue.operator, - value: customFieldValue.value as string, - }); - } - - qs.custom_fields = JSON.stringify(customFields); - } - } - - const listId = this.getNodeParameter('list', i) as string; - if (returnAll === true) { - responseData = await clickupApiRequestAllItems.call(this, 'tasks', 'GET', `/list/${listId}/task`, {}, qs); - } else { - qs.limit = this.getNodeParameter('limit', i) as number; - responseData = await clickupApiRequestAllItems.call(this, 'tasks', 'GET', `/list/${listId}/task`, {}, qs); - responseData = responseData.splice(0, qs.limit); - } - } - if (operation === 'member') { - const taskId = this.getNodeParameter('id', i) as string; - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - if (returnAll === true) { - responseData = await clickupApiRequest.call(this, 'GET', `/task/${taskId}/member`, {}, qs); - responseData = responseData.members; - } else { - qs.limit = this.getNodeParameter('limit', i) as number; - responseData = await clickupApiRequest.call(this, 'GET', `/task/${taskId}/member`, {}, qs); - responseData = responseData.members; - responseData = responseData.splice(0, qs.limit); - } - } - if (operation === 'setCustomField') { - const taskId = this.getNodeParameter('task', i) as string; - const fieldId = this.getNodeParameter('field', i) as string; - const value = this.getNodeParameter('value', i) as string; - const jsonParse = this.getNodeParameter('jsonParse', i) as boolean; - - const body: IDataObject = {}; - body.value = value; - if (jsonParse === true) { - body.value = validateJSON(body.value); - if (body.value === undefined) { - throw new NodeOperationError(this.getNode(), 'Value is invalid JSON!'); - } - } else { - //@ts-ignore - if (!isNaN(body.value)) { - body.value = parseInt(body.value, 10); - } - } - responseData = await clickupApiRequest.call(this, 'POST', `/task/${taskId}/field/${fieldId}`, body); - } - if (operation === 'delete') { - const taskId = this.getNodeParameter('id', i) as string; - responseData = await clickupApiRequest.call(this, 'DELETE', `/task/${taskId}`, {}); - responseData = { success: true }; - } - } - if (resource === 'taskTag') { - if (operation === 'add') { - const taskId = this.getNodeParameter('taskId', i) as string; - const name = this.getNodeParameter('tagName', i) as string; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const qs: IDataObject = {}; - Object.assign(qs, additionalFields); - responseData = await clickupApiRequest.call(this, 'POST', `/task/${taskId}/tag/${name}`, {}, qs); - responseData = { success: true }; - } - if (operation === 'remove') { - const taskId = this.getNodeParameter('taskId', i) as string; - const name = this.getNodeParameter('tagName', i) as string; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const qs: IDataObject = {}; - Object.assign(qs, additionalFields); - responseData = await clickupApiRequest.call(this, 'DELETE', `/task/${taskId}/tag/${name}`, {}, qs); - responseData = { success: true }; - } - } - if (resource === 'taskList') { - if (operation === 'add') { - const taskId = this.getNodeParameter('taskId', i) as string; - const listId = this.getNodeParameter('listId', i) as string; - responseData = await clickupApiRequest.call(this, 'POST', `/list/${listId}/task/${taskId}`); - responseData = { success: true }; - } - if (operation === 'remove') { - const taskId = this.getNodeParameter('taskId', i) as string; - const listId = this.getNodeParameter('listId', i) as string; - responseData = await clickupApiRequest.call(this, 'DELETE', `/list/${listId}/task/${taskId}`); - responseData = { success: true }; - } - } - if (resource === 'taskDependency') { - if (operation === 'create') { - const taskId = this.getNodeParameter('task', i) as string; - const dependsOnTaskId = this.getNodeParameter('dependsOnTask', i) as string; - const body: IDataObject = {}; - - body.depends_on = dependsOnTaskId; - - responseData = await clickupApiRequest.call(this, 'POST', `/task/${taskId}/dependency`, body); - responseData = { success: true }; - } - if (operation === 'delete') { - const taskId = this.getNodeParameter('task', i) as string; - const dependsOnTaskId = this.getNodeParameter('dependsOnTask', i) as string; - - qs.depends_on = dependsOnTaskId; - - responseData = await clickupApiRequest.call(this, 'DELETE', `/task/${taskId}/dependency`, {}, qs); - responseData = { success: true }; - } - } - if (resource === 'timeEntry') { - if (operation === 'update') { - const teamId = this.getNodeParameter('team', i) as string; - const timeEntryId = this.getNodeParameter('timeEntry', i) as string; - const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; - const timezone = this.getTimezone(); - const body: IDataObject = {}; - Object.assign(body, updateFields); - - if (body.start) { - body.start = moment.tz(body.start, timezone).valueOf(); - } - - if (body.duration) { - body.duration = body.duration as number * 60000; - } - - if (body.task) { - body.tid = body.task; - body.custom_task_ids = true; - } - - responseData = await clickupApiRequest.call(this, 'PUT', `/team/${teamId}/time_entries/${timeEntryId}`, body); - responseData = responseData.data; - } - if (operation === 'getAll') { - const teamId = this.getNodeParameter('team', i) as string; - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - const filters = this.getNodeParameter('filters', i) as IDataObject; - const timezone = this.getTimezone(); - Object.assign(qs, filters); - - if (filters.start_date) { - qs.start_date = moment.tz(qs.start_date, timezone).valueOf(); - } - if (filters.end_date) { - qs.end_date = moment.tz(qs.end_date, timezone).valueOf(); - } - responseData = await clickupApiRequest.call(this, 'GET', `/team/${teamId}/time_entries`, {}, qs); - - responseData = responseData.data; - - if (returnAll === false) { - const limit = this.getNodeParameter('limit', i) as number; - responseData = responseData.splice(0, limit); - } - - } - if (operation === 'get') { - const teamId = this.getNodeParameter('team', i) as string; - const running = this.getNodeParameter('running', i) as boolean; - - let endpoint = `/team/${teamId}/time_entries/current`; - - if (running === false) { - const timeEntryId = this.getNodeParameter('timeEntry', i) as string; - endpoint = `/team/${teamId}/time_entries/${timeEntryId}`; - } - - responseData = await clickupApiRequest.call(this, 'GET', endpoint); - responseData = responseData.data; - } - if (operation === 'create') { - const teamId = this.getNodeParameter('team', i) as string; - const taskId = this.getNodeParameter('task', i) as string; - const start = this.getNodeParameter('start', i) as string; - const duration = this.getNodeParameter('duration', i) as number; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const timezone = this.getTimezone(); - const body: IDataObject = { - start: moment.tz(start, timezone).valueOf(), - duration: duration * 60000, - tid: taskId, - }; - Object.assign(body, additionalFields); - - if (body.tags) { - body.tags = (body.tags as string[]).map((tag) => (JSON.parse(tag))); - } - - responseData = await clickupApiRequest.call(this, 'POST', `/team/${teamId}/time_entries`, body); - responseData = responseData.data; - } - if (operation === 'start') { - const teamId = this.getNodeParameter('team', i) as string; - const taskId = this.getNodeParameter('task', i) as string; - const body: IDataObject = {}; - body.tid = taskId; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - Object.assign(body, additionalFields); - responseData = await clickupApiRequest.call(this, 'POST', `/team/${teamId}/time_entries/start`, body); - responseData = responseData.data; - } - if (operation === 'stop') { - const teamId = this.getNodeParameter('team', i) as string; - responseData = await clickupApiRequest.call(this, 'POST', `/team/${teamId}/time_entries/stop`); - - if (responseData.data) { - responseData = responseData.data; - } else { - throw new NodeOperationError(this.getNode(), 'There seems to be nothing to stop.'); - } - } - if (operation === 'delete') { - const teamId = this.getNodeParameter('team', i) as string; - const timeEntryId = this.getNodeParameter('timeEntry', i) as string; - responseData = await clickupApiRequest.call(this, 'DELETE', `/team/${teamId}/time_entries/${timeEntryId}`); - responseData = responseData.data; - } - } - if (resource === 'timeEntryTag') { - if (operation === 'add') { - const teamId = this.getNodeParameter('team', i) as string; - const timeEntryIds = this.getNodeParameter('timeEntryIds', i) as string; - const tagsUi = this.getNodeParameter('tagsUi', i) as IDataObject; - const body: IDataObject = {}; - body.time_entry_ids = timeEntryIds.split(','); - if (tagsUi) { - const tags = (tagsUi as IDataObject).tagsValues as IDataObject[]; - if (tags === undefined) { - throw new NodeOperationError(this.getNode(), 'At least one tag must be set'); - } - body.tags = tags; - } - responseData = await clickupApiRequest.call(this, 'POST', `/team/${teamId}/time_entries/tags`, body); - responseData = { success: true }; - } - if (operation === 'getAll') { - const teamId = this.getNodeParameter('team', i) as string; - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - responseData = await clickupApiRequest.call(this, 'GET', `/team/${teamId}/time_entries/tags`); - - responseData = responseData.data; - - if (returnAll === false) { - const limit = this.getNodeParameter('limit', i) as number; - responseData = responseData.splice(0, limit); - } - - } - if (operation === 'remove') { - const teamId = this.getNodeParameter('team', i) as string; - const timeEntryIds = this.getNodeParameter('timeEntryIds', i) as string; - const tagNames = this.getNodeParameter('tagNames', i) as string[]; - const body: IDataObject = {}; - body.time_entry_ids = timeEntryIds.split(','); - body.tags = tagNames.map((tag) => (JSON.parse(tag).name)); - responseData = await clickupApiRequest.call(this, 'DELETE', `/team/${teamId}/time_entries/tags`, body); - responseData = { success: true }; - } - - } - if (resource === 'spaceTag') { - if (operation === 'create') { - const spaceId = this.getNodeParameter('space', i) as string; - const name = this.getNodeParameter('name', i) as string; - const foregroundColor = this.getNodeParameter('foregroundColor', i) as string; - const backgroundColor = this.getNodeParameter('backgroundColor', i) as string; - const body: IDataObject = { - tag: { + try { + if (resource === 'checklist') { + if (operation === 'create') { + const taskId = this.getNodeParameter('task', i) as string; + const name = this.getNodeParameter('name', i) as string; + const body: IDataObject = { name, - tag_bg: backgroundColor, - tag_fg: foregroundColor, - }, - }; - responseData = await clickupApiRequest.call(this, 'POST', `/space/${spaceId}/tag`, body); - responseData = { success: true }; - } - if (operation === 'delete') { - const spaceId = this.getNodeParameter('space', i) as string; - const name = this.getNodeParameter('name', i) as string; - responseData = await clickupApiRequest.call(this, 'DELETE', `/space/${spaceId}/tag/${name}`); - responseData = { success: true }; - } - if (operation === 'getAll') { - const spaceId = this.getNodeParameter('space', i) as string; - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - responseData = await clickupApiRequest.call(this, 'GET', `/space/${spaceId}/tag`); - responseData = responseData.tags; - if (returnAll === false) { - const limit = this.getNodeParameter('limit', i) as number; - responseData = responseData.splice(0, limit); + }; + responseData = await clickupApiRequest.call(this, 'POST', `/task/${taskId}/checklist`, body); + responseData = responseData.checklist; + } + if (operation === 'delete') { + const checklistId = this.getNodeParameter('checklist', i) as string; + responseData = await clickupApiRequest.call(this, 'DELETE', `/checklist/${checklistId}`); + responseData = { success: true }; + } + if (operation === 'update') { + const checklistId = this.getNodeParameter('checklist', i) as string; + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + const body: IDataObject = {}; + if (updateFields.name) { + body.name = updateFields.name as string; + } + if (updateFields.position) { + body.position = updateFields.position as number; + } + responseData = await clickupApiRequest.call(this, 'PUT', `/checklist/${checklistId}`, body); + responseData = responseData.checklist; } } - if (operation === 'update') { - const spaceId = this.getNodeParameter('space', i) as string; - const tagName = this.getNodeParameter('name', i) as string; - const newTagName = this.getNodeParameter('newName', i) as string; - const foregroundColor = this.getNodeParameter('foregroundColor', i) as string; - const backgroundColor = this.getNodeParameter('backgroundColor', i) as string; - const body: IDataObject = { - tag: { - name: newTagName, - tag_bg: backgroundColor, - tag_fg: foregroundColor, - }, - }; - await clickupApiRequest.call(this, 'PUT', `/space/${spaceId}/tag/${tagName}`, body); - responseData = { success: true }; - } - } - if (resource === 'list') { - if (operation === 'create') { - const spaceId = this.getNodeParameter('space', i) as string; - const folderless = this.getNodeParameter('folderless', i) as string; - const name = this.getNodeParameter('name', i) as string; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const body: IList = { - name, - }; - if (additionalFields.content) { - body.content = additionalFields.content as string; + if (resource === 'checklistItem') { + if (operation === 'create') { + const checklistId = this.getNodeParameter('checklist', i) as string; + const name = this.getNodeParameter('name', i) as string; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const body: IDataObject = { + name, + }; + if (additionalFields.assignee) { + body.assignee = parseInt(additionalFields.assignee as string, 10); + } + responseData = await clickupApiRequest.call(this, 'POST', `/checklist/${checklistId}/checklist_item`, body); + responseData = responseData.checklist; } - if (additionalFields.dueDate) { - body.due_date = new Date(additionalFields.dueDate as string).getTime(); + if (operation === 'delete') { + const checklistId = this.getNodeParameter('checklist', i) as string; + const checklistItemId = this.getNodeParameter('checklistItem', i) as string; + responseData = await clickupApiRequest.call(this, 'DELETE', `/checklist/${checklistId}/checklist_item/${checklistItemId}`); + responseData = { success: true }; } - if (additionalFields.dueDateTime) { - body.due_date_time = additionalFields.dueDateTime as boolean; - } - if (additionalFields.priority) { - body.priority = additionalFields.priority as number; - } - if (additionalFields.assignee) { - body.assignee = parseInt(additionalFields.assignee as string, 10); - } - if (additionalFields.status) { - body.status = additionalFields.status as string; - } - if (folderless) { - responseData = await clickupApiRequest.call(this, 'POST', `/space/${spaceId}/list`, body); - } else { - const folderId = this.getNodeParameter('folder', i) as string; - responseData = await clickupApiRequest.call(this, 'POST', `/folder/${folderId}/list`, body); + if (operation === 'update') { + const checklistId = this.getNodeParameter('checklist', i) as string; + const checklistItemId = this.getNodeParameter('checklistItem', i) as string; + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + const body: IDataObject = {}; + if (updateFields.name) { + body.name = updateFields.name as string; + } + if (updateFields.parent) { + body.parent = updateFields.parent as string; + } + if (updateFields.assignee) { + body.assignee = parseInt(updateFields.assignee as string, 10); + } + if (updateFields.resolved) { + body.resolved = updateFields.resolved as boolean; + } + responseData = await clickupApiRequest.call(this, 'PUT', `/checklist/${checklistId}/checklist_item/${checklistItemId}`, body); + responseData = responseData.checklist; } } - if (operation === 'member') { - const listId = this.getNodeParameter('id', i) as string; - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - if (returnAll === true) { - responseData = await clickupApiRequest.call(this, 'GET', `/list/${listId}/member`, {}, qs); - responseData = responseData.members; - } else { + if (resource === 'comment') { + if (operation === 'create') { + const resource = this.getNodeParameter('commentOn', i) as string; + const id = this.getNodeParameter('id', i) as string; + const commentText = this.getNodeParameter('commentText', i) as string; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const body: IDataObject = { + comment_text: commentText, + }; + if (additionalFields.assignee) { + body.assignee = parseInt(additionalFields.assignee as string, 10); + } + if (additionalFields.notifyAll) { + body.notify_all = additionalFields.notifyAll as boolean; + } + responseData = await clickupApiRequest.call(this, 'POST', `/${resource}/${id}/comment`, body); + } + if (operation === 'delete') { + const commentId = this.getNodeParameter('comment', i) as string; + responseData = await clickupApiRequest.call(this, 'DELETE', `/comment/${commentId}`); + responseData = { success: true }; + } + if (operation === 'getAll') { + const resource = this.getNodeParameter('commentsOn', i) as string; + const id = this.getNodeParameter('id', i) as string; qs.limit = this.getNodeParameter('limit', i) as number; - responseData = await clickupApiRequest.call(this, 'GET', `/list/${listId}/member`, {}, qs); - responseData = responseData.members; + responseData = await clickupApiRequest.call(this, 'GET', `/${resource}/${id}/comment`, {}, qs); + responseData = responseData.comments; responseData = responseData.splice(0, qs.limit); } - } - if (operation === 'customFields') { - const listId = this.getNodeParameter('list', i) as string; - responseData = await clickupApiRequest.call(this, 'GET', `/list/${listId}/field`); - responseData = responseData.fields; - } - if (operation === 'delete') { - const listId = this.getNodeParameter('list', i) as string; - responseData = await clickupApiRequest.call(this, 'DELETE', `/list/${listId}`); - responseData = { success: true }; - } - if (operation === 'get') { - const listId = this.getNodeParameter('list', i) as string; - responseData = await clickupApiRequest.call(this, 'GET', `/list/${listId}`); - } - if (operation === 'getAll') { - const filters = this.getNodeParameter('filters', i) as IDataObject; - const spaceId = this.getNodeParameter('space', i) as string; - const folderless = this.getNodeParameter('folderless', i) as boolean; - if (filters.archived) { - qs.archived = filters.archived as boolean; + if (operation === 'update') { + const commentId = this.getNodeParameter('comment', i) as string; + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + const body: IDataObject = {}; + if (updateFields.commentText) { + body.comment_text = updateFields.commentText as string; + } + if (updateFields.assignee) { + body.assignee = parseInt(updateFields.assignee as string, 10); + } + if (updateFields.resolved) { + body.resolved = updateFields.resolved as boolean; + } + responseData = await clickupApiRequest.call(this, 'PUT', `/comment/${commentId}`, body); + responseData = { success: true }; } - let endpoint = `/space/${spaceId}/list`; - if (!folderless) { + } + if (resource === 'folder') { + if (operation === 'create') { + const spaceId = this.getNodeParameter('space', i) as string; + const name = this.getNodeParameter('name', i) as string; + const body: IDataObject = { + name, + }; + responseData = await clickupApiRequest.call(this, 'POST', `/space/${spaceId}/folder`, body); + } + if (operation === 'delete') { const folderId = this.getNodeParameter('folder', i) as string; - endpoint = `/folder/${folderId}/list`; + responseData = await clickupApiRequest.call(this, 'DELETE', `/folder/${folderId}`); + responseData = { success: true }; + } + if (operation === 'get') { + const folderId = this.getNodeParameter('folder', i) as string; + responseData = await clickupApiRequest.call(this, 'GET', `/folder/${folderId}`); + } + if (operation === 'getAll') { + const filters = this.getNodeParameter('filters', i) as IDataObject; + const spaceId = this.getNodeParameter('space', i) as string; + if (filters.archived) { + qs.archived = filters.archived as boolean; + } + qs.limit = this.getNodeParameter('limit', i) as number; + responseData = await clickupApiRequest.call(this, 'GET', `/space/${spaceId}/folder`, {}, qs); + responseData = responseData.folders; + responseData = responseData.splice(0, qs.limit); + } + if (operation === 'update') { + const folderId = this.getNodeParameter('folder', i) as string; + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + const body: IDataObject = {}; + if (updateFields.name) { + body.name = updateFields.name as string; + } + responseData = await clickupApiRequest.call(this, 'PUT', `/folder/${folderId}`, body); + } + } + if (resource === 'goal') { + if (operation === 'create') { + const teamId = this.getNodeParameter('team', i) as string; + const name = this.getNodeParameter('name', i) as string; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const body: IDataObject = { + name, + }; + if (additionalFields.dueDate) { + body.due_date = new Date(additionalFields.dueDate as string).getTime(); + } + if (additionalFields.description) { + body.description = additionalFields.description as string; + } + if (additionalFields.multipleOwners) { + body.multiple_owners = additionalFields.multipleOwners as boolean; + } + if (additionalFields.color) { + body.color = additionalFields.color as string; + } + if (additionalFields.owners) { + body.owners = ((additionalFields.owners as string).split(',') as string[]).map((e: string) => parseInt(e, 10)); + } + responseData = await clickupApiRequest.call(this, 'POST', `/team/${teamId}/goal`, body); + responseData = responseData.goal; + } + if (operation === 'delete') { + const goalId = this.getNodeParameter('goal', i) as string; + responseData = await clickupApiRequest.call(this, 'DELETE', `/goal/${goalId}`); + responseData = { success: true }; + } + if (operation === 'get') { + const goalId = this.getNodeParameter('goal', i) as string; + responseData = await clickupApiRequest.call(this, 'GET', `/goal/${goalId}`); + responseData = responseData.goal; + } + if (operation === 'getAll') { + const teamId = this.getNodeParameter('team', i) as string; + qs.limit = this.getNodeParameter('limit', i) as number; + responseData = await clickupApiRequest.call(this, 'GET', `/team/${teamId}/goal`, {}, qs); + responseData = responseData.goals; + responseData = responseData.splice(0, qs.limit); + + } + if (operation === 'update') { + const goalId = this.getNodeParameter('goal', i) as string; + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + const body: IDataObject = {}; + if (updateFields.name) { + body.name = updateFields.name as string; + } + if (updateFields.dueDate) { + body.due_date = new Date(updateFields.dueDate as string).getTime(); + } + if (updateFields.description) { + body.description = updateFields.description as string; + } + if (updateFields.color) { + body.color = updateFields.color as string; + } + if (updateFields.addOwners) { + body.add_owners = ((updateFields.addOwners as string).split(',') as string[]).map((e: string) => parseInt(e, 10)) as number[]; + } + if (updateFields.removeOwners) { + body.rem_owners = ((updateFields.removeOwners as string).split(',') as string[]).map((e: string) => parseInt(e, 10)) as number[]; + } + responseData = await clickupApiRequest.call(this, 'PUT', `/goal/${goalId}`, body); + responseData = responseData.goal; + } + } + if (resource === 'goalKeyResult') { + if (operation === 'create') { + const goalId = this.getNodeParameter('goal', i) as string; + const name = this.getNodeParameter('name', i) as string; + const type = this.getNodeParameter('type', i) as string; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const body: IDataObject = { + name, + type, + }; + if (type === 'number' || type === 'currency') { + if (!additionalFields.unit) { + throw new NodeOperationError(this.getNode(), 'Unit field must be set'); + } + } + if (type === 'number' || type === 'percentaje' + || type === 'automatic' || type === 'currency') { + if (additionalFields.stepsStart === undefined + || !additionalFields.stepsEnd === undefined) { + throw new NodeOperationError(this.getNode(), 'Steps start and steps end fields must be set'); + } + } + if (additionalFields.unit) { + body.unit = additionalFields.unit as string; + } + if (additionalFields.stepsStart) { + body.steps_start = additionalFields.stepsStart as number; + } + if (additionalFields.stepsEnd) { + body.steps_end = additionalFields.stepsEnd as number; + } + if (additionalFields.taskIds) { + body.task_ids = (additionalFields.taskIds as string).split(','); + } + if (additionalFields.listIds) { + body.list_ids = (additionalFields.listIds as string).split(','); + } + if (additionalFields.owners) { + body.owners = ((additionalFields.owners as string).split(',') as string[]).map((e: string) => parseInt(e, 10)); + } + responseData = await clickupApiRequest.call(this, 'POST', `/goal/${goalId}/key_result`, body); + responseData = responseData.key_result; + } + if (operation === 'delete') { + const keyResultId = this.getNodeParameter('keyResult', i) as string; + responseData = await clickupApiRequest.call(this, 'DELETE', `/key_result/${keyResultId}`); + responseData = { success: true }; + } + if (operation === 'update') { + const keyResultId = this.getNodeParameter('keyResult', i) as string; + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + const body: IDataObject = {}; + if (updateFields.name) { + body.name = updateFields.name as string; + } + if (updateFields.note) { + body.note = updateFields.note as string; + } + if (updateFields.stepsCurrent) { + body.steps_current = updateFields.stepsCurrent as number; + } + if (updateFields.stepsStart) { + body.steps_start = updateFields.stepsStart as number; + } + if (updateFields.stepsEnd) { + body.steps_end = updateFields.stepsEnd as number; + } + if (updateFields.unit) { + body.unit = updateFields.unit as string; + } + responseData = await clickupApiRequest.call(this, 'PUT', `/key_result/${keyResultId}`, body); + responseData = responseData.key_result; + } + } + if (resource === 'guest') { + if (operation === 'create') { + const teamId = this.getNodeParameter('team', i) as string; + const email = this.getNodeParameter('email', i) as string; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const body: IDataObject = { + email, + }; + if (additionalFields.canEditTags) { + body.can_edit_tags = additionalFields.canEditTags as boolean; + } + if (additionalFields.canSeeTimeSpend) { + body.can_see_time_spend = additionalFields.canSeeTimeSpend as boolean; + } + if (additionalFields.canSeeTimeEstimated) { + body.can_see_time_estimated = additionalFields.canSeeTimeEstimated as boolean; + } + responseData = await clickupApiRequest.call(this, 'POST', `/team/${teamId}/guest`, body); + responseData = responseData.team; + } + if (operation === 'delete') { + const teamId = this.getNodeParameter('team', i) as string; + const guestId = this.getNodeParameter('guest', i) as string; + responseData = await clickupApiRequest.call(this, 'DELETE', `/team/${teamId}/guest/${guestId}`); + responseData = { success: true }; + } + if (operation === 'get') { + const teamId = this.getNodeParameter('team', i) as string; + const guestId = this.getNodeParameter('guest', i) as string; + responseData = await clickupApiRequest.call(this, 'GET', `/team/${teamId}/guest/${guestId}`); + responseData = responseData.team; + } + if (operation === 'update') { + const teamId = this.getNodeParameter('team', i) as string; + const guestId = this.getNodeParameter('guest', i) as string; + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + const body: IDataObject = {}; + if (updateFields.username) { + body.username = updateFields.username as string; + } + if (updateFields.canEditTags) { + body.can_edit_tags = updateFields.canEditTags as boolean; + } + if (updateFields.canSeeTimeSpend) { + body.can_see_time_spend = updateFields.canSeeTimeSpend as boolean; + } + if (updateFields.canSeeTimeEstimated) { + body.can_see_time_estimated = updateFields.canSeeTimeEstimated as boolean; + } + responseData = await clickupApiRequest.call(this, 'PUT', `/team/${teamId}/guest/${guestId}`, body); + responseData = responseData.team; + } + } + if (resource === 'task') { + if (operation === 'create') { + const listId = this.getNodeParameter('list', i) as string; + const name = this.getNodeParameter('name', i) as string; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const body: ITask = { + name, + }; + if (additionalFields.customFieldsJson) { + const customFields = validateJSON(additionalFields.customFieldsJson as string); + if (customFields === undefined) { + throw new NodeOperationError(this.getNode(), 'Custom Fields: Invalid JSON'); + } + body.custom_fields = customFields; + } + if (additionalFields.content) { + body.content = additionalFields.content as string; + } + if (additionalFields.assignees) { + body.assignees = additionalFields.assignees as string[]; + } + if (additionalFields.tags) { + body.tags = additionalFields.tags as string[]; + } + if (additionalFields.status) { + body.status = additionalFields.status as string; + } + if (additionalFields.priority) { + body.priority = additionalFields.priority as number; + } + if (additionalFields.dueDate) { + body.due_date = new Date(additionalFields.dueDate as string).getTime(); + } + if (additionalFields.dueDateTime) { + body.due_date_time = additionalFields.dueDateTime as boolean; + } + if (additionalFields.timeEstimate) { + body.time_estimate = (additionalFields.timeEstimate as number) * 6000; + } + if (additionalFields.startDate) { + body.start_date = new Date(additionalFields.startDate as string).getTime(); + } + if (additionalFields.startDateTime) { + body.start_date_time = additionalFields.startDateTime as boolean; + } + if (additionalFields.notifyAll) { + body.notify_all = additionalFields.notifyAll as boolean; + } + if (additionalFields.parentId) { + body.parent = additionalFields.parentId as string; + } + if (additionalFields.markdownContent) { + delete body.content; + body.markdown_content = additionalFields.content as string; + } + responseData = await clickupApiRequest.call(this, 'POST', `/list/${listId}/task`, body); + } + if (operation === 'update') { + const taskId = this.getNodeParameter('id', i) as string; + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + const body: ITask = { + assignees: { + add: [], + rem: [], + }, + }; + if (updateFields.content) { + body.content = updateFields.content as string; + } + if (updateFields.priority) { + body.priority = updateFields.priority as number; + } + if (updateFields.dueDate) { + body.due_date = new Date(updateFields.dueDate as string).getTime(); + } + if (updateFields.dueDateTime) { + body.due_date_time = updateFields.dueDateTime as boolean; + } + if (updateFields.timeEstimate) { + body.time_estimate = (updateFields.timeEstimate as number) * 6000; + } + if (updateFields.startDate) { + body.start_date = new Date(updateFields.startDate as string).getTime(); + } + if (updateFields.startDateTime) { + body.start_date_time = updateFields.startDateTime as boolean; + } + if (updateFields.notifyAll) { + body.notify_all = updateFields.notifyAll as boolean; + } + if (updateFields.name) { + body.name = updateFields.name as string; + } + if (updateFields.parentId) { + body.parent = updateFields.parentId as string; + } + if (updateFields.addAssignees) { + //@ts-ignore + body.assignees.add = ((updateFields.addAssignees as string).split(',') as string[]).map((e: string) => parseInt(e, 10)); + } + if (updateFields.removeAssignees) { + //@ts-ignore + body.assignees.rem = ((updateFields.removeAssignees as string).split(',') as string[]).map((e: string) => parseInt(e, 10)); + } + if (updateFields.status) { + body.status = updateFields.status as string; + } + if (updateFields.markdownContent) { + delete body.content; + body.markdown_content = updateFields.content as string; + } + responseData = await clickupApiRequest.call(this, 'PUT', `/task/${taskId}`, body); + } + if (operation === 'get') { + const taskId = this.getNodeParameter('id', i) as string; + responseData = await clickupApiRequest.call(this, 'GET', `/task/${taskId}`); + } + if (operation === 'getAll') { + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + const filters = this.getNodeParameter('filters', i) as IDataObject; + if (filters.archived) { + qs.archived = filters.archived as boolean; + } + if (filters.subtasks) { + qs.subtasks = filters.subtasks as boolean; + } + if (filters.includeClosed) { + qs.include_closed = filters.includeClosed as boolean; + } + if (filters.orderBy) { + qs.order_by = filters.orderBy as string; + } + if (filters.statuses) { + qs.statuses = filters.statuses as string[]; + } + if (filters.assignees) { + qs.assignees = filters.assignees as string[]; + } + if (filters.tags) { + qs.tags = filters.tags as string[]; + } + if (filters.dueDateGt) { + qs.due_date_gt = new Date(filters.dueDateGt as string).getTime(); + } + if (filters.dueDateLt) { + qs.due_date_lt = new Date(filters.dueDateLt as string).getTime(); + } + if (filters.dateCreatedGt) { + qs.date_created_gt = new Date(filters.dateCreatedGt as string).getTime(); + } + if (filters.dateCreatedLt) { + qs.date_created_lt = new Date(filters.dateCreatedLt as string).getTime(); + } + if (filters.dateUpdatedGt) { + qs.date_updated_gt = new Date(filters.dateUpdatedGt as string).getTime(); + } + if (filters.dateUpdatedLt) { + qs.date_updated_lt = new Date(filters.dateUpdatedLt as string).getTime(); + } + if (filters.customFieldsUi) { + const customFieldsValues = (filters.customFieldsUi as IDataObject).customFieldsValues as IDataObject[]; + if (customFieldsValues) { + const customFields: IDataObject[] = []; + for (const customFieldValue of customFieldsValues) { + customFields.push({ + field_id: customFieldValue.fieldId, + operator: (customFieldValue.operator === 'equal') ? '=' : customFieldValue.operator, + value: customFieldValue.value as string, + }); + } + + qs.custom_fields = JSON.stringify(customFields); + } + } + + const listId = this.getNodeParameter('list', i) as string; + if (returnAll === true) { + responseData = await clickupApiRequestAllItems.call(this, 'tasks', 'GET', `/list/${listId}/task`, {}, qs); + } else { + qs.limit = this.getNodeParameter('limit', i) as number; + responseData = await clickupApiRequestAllItems.call(this, 'tasks', 'GET', `/list/${listId}/task`, {}, qs); + responseData = responseData.splice(0, qs.limit); + } + } + if (operation === 'member') { + const taskId = this.getNodeParameter('id', i) as string; + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + if (returnAll === true) { + responseData = await clickupApiRequest.call(this, 'GET', `/task/${taskId}/member`, {}, qs); + responseData = responseData.members; + } else { + qs.limit = this.getNodeParameter('limit', i) as number; + responseData = await clickupApiRequest.call(this, 'GET', `/task/${taskId}/member`, {}, qs); + responseData = responseData.members; + responseData = responseData.splice(0, qs.limit); + } + } + if (operation === 'setCustomField') { + const taskId = this.getNodeParameter('task', i) as string; + const fieldId = this.getNodeParameter('field', i) as string; + const value = this.getNodeParameter('value', i) as string; + const jsonParse = this.getNodeParameter('jsonParse', i) as boolean; + + const body: IDataObject = {}; + body.value = value; + if (jsonParse === true) { + body.value = validateJSON(body.value); + if (body.value === undefined) { + throw new NodeOperationError(this.getNode(), 'Value is invalid JSON!'); + } + } else { + //@ts-ignore + if (!isNaN(body.value)) { + body.value = parseInt(body.value, 10); + } + } + responseData = await clickupApiRequest.call(this, 'POST', `/task/${taskId}/field/${fieldId}`, body); + } + if (operation === 'delete') { + const taskId = this.getNodeParameter('id', i) as string; + responseData = await clickupApiRequest.call(this, 'DELETE', `/task/${taskId}`, {}); + responseData = { success: true }; + } + } + if (resource === 'taskTag') { + if (operation === 'add') { + const taskId = this.getNodeParameter('taskId', i) as string; + const name = this.getNodeParameter('tagName', i) as string; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const qs: IDataObject = {}; + Object.assign(qs, additionalFields); + responseData = await clickupApiRequest.call(this, 'POST', `/task/${taskId}/tag/${name}`, {}, qs); + responseData = { success: true }; + } + if (operation === 'remove') { + const taskId = this.getNodeParameter('taskId', i) as string; + const name = this.getNodeParameter('tagName', i) as string; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const qs: IDataObject = {}; + Object.assign(qs, additionalFields); + responseData = await clickupApiRequest.call(this, 'DELETE', `/task/${taskId}/tag/${name}`, {}, qs); + responseData = { success: true }; + } + } + if (resource === 'taskList') { + if (operation === 'add') { + const taskId = this.getNodeParameter('taskId', i) as string; + const listId = this.getNodeParameter('listId', i) as string; + responseData = await clickupApiRequest.call(this, 'POST', `/list/${listId}/task/${taskId}`); + responseData = { success: true }; + } + if (operation === 'remove') { + const taskId = this.getNodeParameter('taskId', i) as string; + const listId = this.getNodeParameter('listId', i) as string; + responseData = await clickupApiRequest.call(this, 'DELETE', `/list/${listId}/task/${taskId}`); + responseData = { success: true }; + } + } + if (resource === 'taskDependency') { + if (operation === 'create') { + const taskId = this.getNodeParameter('task', i) as string; + const dependsOnTaskId = this.getNodeParameter('dependsOnTask', i) as string; + const body: IDataObject = {}; + + body.depends_on = dependsOnTaskId; + + responseData = await clickupApiRequest.call(this, 'POST', `/task/${taskId}/dependency`, body); + responseData = { success: true }; + } + if (operation === 'delete') { + const taskId = this.getNodeParameter('task', i) as string; + const dependsOnTaskId = this.getNodeParameter('dependsOnTask', i) as string; + + qs.depends_on = dependsOnTaskId; + + responseData = await clickupApiRequest.call(this, 'DELETE', `/task/${taskId}/dependency`, {}, qs); + responseData = { success: true }; + } + } + if (resource === 'timeEntry') { + if (operation === 'update') { + const teamId = this.getNodeParameter('team', i) as string; + const timeEntryId = this.getNodeParameter('timeEntry', i) as string; + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + const timezone = this.getTimezone(); + const body: IDataObject = {}; + Object.assign(body, updateFields); + + if (body.start) { + body.start = moment.tz(body.start, timezone).valueOf(); + } + + if (body.duration) { + body.duration = body.duration as number * 60000; + } + + if (body.task) { + body.tid = body.task; + body.custom_task_ids = true; + } + + responseData = await clickupApiRequest.call(this, 'PUT', `/team/${teamId}/time_entries/${timeEntryId}`, body); + responseData = responseData.data; + } + if (operation === 'getAll') { + const teamId = this.getNodeParameter('team', i) as string; + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + const filters = this.getNodeParameter('filters', i) as IDataObject; + const timezone = this.getTimezone(); + Object.assign(qs, filters); + + if (filters.start_date) { + qs.start_date = moment.tz(qs.start_date, timezone).valueOf(); + } + if (filters.end_date) { + qs.end_date = moment.tz(qs.end_date, timezone).valueOf(); + } + responseData = await clickupApiRequest.call(this, 'GET', `/team/${teamId}/time_entries`, {}, qs); + + responseData = responseData.data; + + if (returnAll === false) { + const limit = this.getNodeParameter('limit', i) as number; + responseData = responseData.splice(0, limit); + } + + } + if (operation === 'get') { + const teamId = this.getNodeParameter('team', i) as string; + const running = this.getNodeParameter('running', i) as boolean; + + let endpoint = `/team/${teamId}/time_entries/current`; + + if (running === false) { + const timeEntryId = this.getNodeParameter('timeEntry', i) as string; + endpoint = `/team/${teamId}/time_entries/${timeEntryId}`; + } + + responseData = await clickupApiRequest.call(this, 'GET', endpoint); + responseData = responseData.data; + } + if (operation === 'create') { + const teamId = this.getNodeParameter('team', i) as string; + const taskId = this.getNodeParameter('task', i) as string; + const start = this.getNodeParameter('start', i) as string; + const duration = this.getNodeParameter('duration', i) as number; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const timezone = this.getTimezone(); + const body: IDataObject = { + start: moment.tz(start, timezone).valueOf(), + duration: duration * 60000, + tid: taskId, + }; + Object.assign(body, additionalFields); + + if (body.tags) { + body.tags = (body.tags as string[]).map((tag) => (JSON.parse(tag))); + } + + responseData = await clickupApiRequest.call(this, 'POST', `/team/${teamId}/time_entries`, body); + responseData = responseData.data; + } + if (operation === 'start') { + const teamId = this.getNodeParameter('team', i) as string; + const taskId = this.getNodeParameter('task', i) as string; + const body: IDataObject = {}; + body.tid = taskId; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + Object.assign(body, additionalFields); + responseData = await clickupApiRequest.call(this, 'POST', `/team/${teamId}/time_entries/start`, body); + responseData = responseData.data; + } + if (operation === 'stop') { + const teamId = this.getNodeParameter('team', i) as string; + responseData = await clickupApiRequest.call(this, 'POST', `/team/${teamId}/time_entries/stop`); + + if (responseData.data) { + responseData = responseData.data; + } else { + throw new NodeOperationError(this.getNode(), 'There seems to be nothing to stop.'); + } + } + if (operation === 'delete') { + const teamId = this.getNodeParameter('team', i) as string; + const timeEntryId = this.getNodeParameter('timeEntry', i) as string; + responseData = await clickupApiRequest.call(this, 'DELETE', `/team/${teamId}/time_entries/${timeEntryId}`); + responseData = responseData.data; + } + } + if (resource === 'timeEntryTag') { + if (operation === 'add') { + const teamId = this.getNodeParameter('team', i) as string; + const timeEntryIds = this.getNodeParameter('timeEntryIds', i) as string; + const tagsUi = this.getNodeParameter('tagsUi', i) as IDataObject; + const body: IDataObject = {}; + body.time_entry_ids = timeEntryIds.split(','); + if (tagsUi) { + const tags = (tagsUi as IDataObject).tagsValues as IDataObject[]; + if (tags === undefined) { + throw new NodeOperationError(this.getNode(), 'At least one tag must be set'); + } + body.tags = tags; + } + responseData = await clickupApiRequest.call(this, 'POST', `/team/${teamId}/time_entries/tags`, body); + responseData = { success: true }; + } + if (operation === 'getAll') { + const teamId = this.getNodeParameter('team', i) as string; + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + responseData = await clickupApiRequest.call(this, 'GET', `/team/${teamId}/time_entries/tags`); + + responseData = responseData.data; + + if (returnAll === false) { + const limit = this.getNodeParameter('limit', i) as number; + responseData = responseData.splice(0, limit); + } + + } + if (operation === 'remove') { + const teamId = this.getNodeParameter('team', i) as string; + const timeEntryIds = this.getNodeParameter('timeEntryIds', i) as string; + const tagNames = this.getNodeParameter('tagNames', i) as string[]; + const body: IDataObject = {}; + body.time_entry_ids = timeEntryIds.split(','); + body.tags = tagNames.map((tag) => (JSON.parse(tag).name)); + responseData = await clickupApiRequest.call(this, 'DELETE', `/team/${teamId}/time_entries/tags`, body); + responseData = { success: true }; } - qs.limit = this.getNodeParameter('limit', i) as number; - responseData = await clickupApiRequest.call(this, 'GET', endpoint, {}, qs); - responseData = responseData.lists; - responseData = responseData.splice(0, qs.limit); } - if (operation === 'update') { - const listId = this.getNodeParameter('list', i) as string; - const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; - const body: IList = {}; - if (updateFields.name) { - body.name = updateFields.name as string; + if (resource === 'spaceTag') { + if (operation === 'create') { + const spaceId = this.getNodeParameter('space', i) as string; + const name = this.getNodeParameter('name', i) as string; + const foregroundColor = this.getNodeParameter('foregroundColor', i) as string; + const backgroundColor = this.getNodeParameter('backgroundColor', i) as string; + const body: IDataObject = { + tag: { + name, + tag_bg: backgroundColor, + tag_fg: foregroundColor, + }, + }; + responseData = await clickupApiRequest.call(this, 'POST', `/space/${spaceId}/tag`, body); + responseData = { success: true }; } - if (updateFields.content) { - body.content = updateFields.content as string; + if (operation === 'delete') { + const spaceId = this.getNodeParameter('space', i) as string; + const name = this.getNodeParameter('name', i) as string; + responseData = await clickupApiRequest.call(this, 'DELETE', `/space/${spaceId}/tag/${name}`); + responseData = { success: true }; } - if (updateFields.dueDate) { - body.due_date = new Date(updateFields.dueDate as string).getTime(); + if (operation === 'getAll') { + const spaceId = this.getNodeParameter('space', i) as string; + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + responseData = await clickupApiRequest.call(this, 'GET', `/space/${spaceId}/tag`); + responseData = responseData.tags; + if (returnAll === false) { + const limit = this.getNodeParameter('limit', i) as number; + responseData = responseData.splice(0, limit); + } } - if (updateFields.dueDateTime) { - body.due_date_time = updateFields.dueDateTime as boolean; + if (operation === 'update') { + const spaceId = this.getNodeParameter('space', i) as string; + const tagName = this.getNodeParameter('name', i) as string; + const newTagName = this.getNodeParameter('newName', i) as string; + const foregroundColor = this.getNodeParameter('foregroundColor', i) as string; + const backgroundColor = this.getNodeParameter('backgroundColor', i) as string; + const body: IDataObject = { + tag: { + name: newTagName, + tag_bg: backgroundColor, + tag_fg: foregroundColor, + }, + }; + await clickupApiRequest.call(this, 'PUT', `/space/${spaceId}/tag/${tagName}`, body); + responseData = { success: true }; } - if (updateFields.priority) { - body.priority = updateFields.priority as number; - } - if (updateFields.assignee) { - body.assignee = parseInt(updateFields.assignee as string, 10); - } - if (updateFields.unsetStatus) { - body.unset_status = updateFields.unsetStatus as boolean; - } - responseData = await clickupApiRequest.call(this, 'PUT', `/list/${listId}`, body); } - } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else { - returnData.push(responseData as IDataObject); + if (resource === 'list') { + if (operation === 'create') { + const spaceId = this.getNodeParameter('space', i) as string; + const folderless = this.getNodeParameter('folderless', i) as string; + const name = this.getNodeParameter('name', i) as string; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const body: IList = { + name, + }; + if (additionalFields.content) { + body.content = additionalFields.content as string; + } + if (additionalFields.dueDate) { + body.due_date = new Date(additionalFields.dueDate as string).getTime(); + } + if (additionalFields.dueDateTime) { + body.due_date_time = additionalFields.dueDateTime as boolean; + } + if (additionalFields.priority) { + body.priority = additionalFields.priority as number; + } + if (additionalFields.assignee) { + body.assignee = parseInt(additionalFields.assignee as string, 10); + } + if (additionalFields.status) { + body.status = additionalFields.status as string; + } + if (folderless) { + responseData = await clickupApiRequest.call(this, 'POST', `/space/${spaceId}/list`, body); + } else { + const folderId = this.getNodeParameter('folder', i) as string; + responseData = await clickupApiRequest.call(this, 'POST', `/folder/${folderId}/list`, body); + } + } + if (operation === 'member') { + const listId = this.getNodeParameter('id', i) as string; + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + if (returnAll === true) { + responseData = await clickupApiRequest.call(this, 'GET', `/list/${listId}/member`, {}, qs); + responseData = responseData.members; + } else { + qs.limit = this.getNodeParameter('limit', i) as number; + responseData = await clickupApiRequest.call(this, 'GET', `/list/${listId}/member`, {}, qs); + responseData = responseData.members; + responseData = responseData.splice(0, qs.limit); + } + } + if (operation === 'customFields') { + const listId = this.getNodeParameter('list', i) as string; + responseData = await clickupApiRequest.call(this, 'GET', `/list/${listId}/field`); + responseData = responseData.fields; + } + if (operation === 'delete') { + const listId = this.getNodeParameter('list', i) as string; + responseData = await clickupApiRequest.call(this, 'DELETE', `/list/${listId}`); + responseData = { success: true }; + } + if (operation === 'get') { + const listId = this.getNodeParameter('list', i) as string; + responseData = await clickupApiRequest.call(this, 'GET', `/list/${listId}`); + } + if (operation === 'getAll') { + const filters = this.getNodeParameter('filters', i) as IDataObject; + const spaceId = this.getNodeParameter('space', i) as string; + const folderless = this.getNodeParameter('folderless', i) as boolean; + if (filters.archived) { + qs.archived = filters.archived as boolean; + } + let endpoint = `/space/${spaceId}/list`; + if (!folderless) { + const folderId = this.getNodeParameter('folder', i) as string; + endpoint = `/folder/${folderId}/list`; + } + + qs.limit = this.getNodeParameter('limit', i) as number; + responseData = await clickupApiRequest.call(this, 'GET', endpoint, {}, qs); + responseData = responseData.lists; + responseData = responseData.splice(0, qs.limit); + } + if (operation === 'update') { + const listId = this.getNodeParameter('list', i) as string; + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + const body: IList = {}; + if (updateFields.name) { + body.name = updateFields.name as string; + } + if (updateFields.content) { + body.content = updateFields.content as string; + } + if (updateFields.dueDate) { + body.due_date = new Date(updateFields.dueDate as string).getTime(); + } + if (updateFields.dueDateTime) { + body.due_date_time = updateFields.dueDateTime as boolean; + } + if (updateFields.priority) { + body.priority = updateFields.priority as number; + } + if (updateFields.assignee) { + body.assignee = parseInt(updateFields.assignee as string, 10); + } + if (updateFields.unsetStatus) { + body.unset_status = updateFields.unsetStatus as boolean; + } + responseData = await clickupApiRequest.call(this, 'PUT', `/list/${listId}`, body); + } + } + if (Array.isArray(responseData)) { + returnData.push.apply(returnData, responseData as IDataObject[]); + } else { + returnData.push(responseData as IDataObject); + } + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } } return [this.helpers.returnJsonArray(returnData)]; diff --git a/packages/nodes-base/nodes/Clockify/Clockify.node.ts b/packages/nodes-base/nodes/Clockify/Clockify.node.ts index 4ae646442e..321c9aefce 100644 --- a/packages/nodes-base/nodes/Clockify/Clockify.node.ts +++ b/packages/nodes-base/nodes/Clockify/Clockify.node.ts @@ -233,354 +233,362 @@ export class Clockify implements INodeType { for (let i = 0; i < length; i++) { - if (resource === 'project') { + try { + if (resource === 'project') { - if (operation === 'create') { + if (operation === 'create') { - const workspaceId = this.getNodeParameter('workspaceId', i) as string; + const workspaceId = this.getNodeParameter('workspaceId', i) as string; - const name = this.getNodeParameter('name', i) as string; + const name = this.getNodeParameter('name', i) as string; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const body: IDataObject = { - name, - }; + const body: IDataObject = { + name, + }; - Object.assign(body, additionalFields); + Object.assign(body, additionalFields); - if (body.estimateUi) { + if (body.estimateUi) { - body.estimate = (body.estimateUi as IDataObject).estimateValues; + body.estimate = (body.estimateUi as IDataObject).estimateValues; - delete body.estimateUi; - } + delete body.estimateUi; + } - responseData = await clockifyApiRequest.call( - this, - 'POST', - `/workspaces/${workspaceId}/projects`, - body, - qs, - ); - } - - if (operation === 'delete') { - - const workspaceId = this.getNodeParameter('workspaceId', i) as string; - - const projectId = this.getNodeParameter('projectId', i) as string; - - responseData = await clockifyApiRequest.call( - this, - 'DELETE', - `/workspaces/${workspaceId}/projects/${projectId}`, - {}, - qs, - ); - - responseData = { success: true }; - } - - if (operation === 'get') { - - const workspaceId = this.getNodeParameter('workspaceId', i) as string; - - const projectId = this.getNodeParameter('projectId', i) as string; - - responseData = await clockifyApiRequest.call( - this, - 'GET', - `/workspaces/${workspaceId}/projects/${projectId}`, - {}, - qs, - ); - } - - if (operation === 'getAll') { - - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - - const workspaceId = this.getNodeParameter('workspaceId', i) as string; - - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - - Object.assign(qs, additionalFields); - - if (returnAll) { - responseData = await clockifyApiRequestAllItems.call( + responseData = await clockifyApiRequest.call( this, - 'GET', + 'POST', `/workspaces/${workspaceId}/projects`, + body, + qs, + ); + } + + if (operation === 'delete') { + + const workspaceId = this.getNodeParameter('workspaceId', i) as string; + + const projectId = this.getNodeParameter('projectId', i) as string; + + responseData = await clockifyApiRequest.call( + this, + 'DELETE', + `/workspaces/${workspaceId}/projects/${projectId}`, {}, qs, ); - } else { + responseData = { success: true }; + } - qs.limit = this.getNodeParameter('limit', i) as number; + if (operation === 'get') { - responseData = await clockifyApiRequestAllItems.call( + const workspaceId = this.getNodeParameter('workspaceId', i) as string; + + const projectId = this.getNodeParameter('projectId', i) as string; + + responseData = await clockifyApiRequest.call( this, 'GET', - `/workspaces/${workspaceId}/projects`, + `/workspaces/${workspaceId}/projects/${projectId}`, {}, qs, ); - - responseData = responseData.splice(0, qs.limit); - } - } - - if (operation === 'update') { - - const workspaceId = this.getNodeParameter('workspaceId', i) as string; - - const projectId = this.getNodeParameter('projectId', i) as string; - - const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; - - const body: IDataObject = {}; - - Object.assign(body, updateFields); - - if (body.estimateUi) { - - body.estimate = (body.estimateUi as IDataObject).estimateValues; - - delete body.estimateUi; } - responseData = await clockifyApiRequest.call( - this, - 'PUT', - `/workspaces/${workspaceId}/projects/${projectId}`, - body, - qs, - ); - } - } + if (operation === 'getAll') { - if (resource === 'tag') { + const returnAll = this.getNodeParameter('returnAll', i) as boolean; - if (operation === 'create') { + const workspaceId = this.getNodeParameter('workspaceId', i) as string; - const workspaceId = this.getNodeParameter('workspaceId', i) as string; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const name = this.getNodeParameter('name', i) as string; + Object.assign(qs, additionalFields); - const body: IDataObject = { - name, - }; + if (returnAll) { + responseData = await clockifyApiRequestAllItems.call( + this, + 'GET', + `/workspaces/${workspaceId}/projects`, + {}, + qs, + ); - responseData = await clockifyApiRequest.call( - this, - 'POST', - `/workspaces/${workspaceId}/tags`, - body, - qs, - ); - } + } else { - if (operation === 'delete') { + qs.limit = this.getNodeParameter('limit', i) as number; - const workspaceId = this.getNodeParameter('workspaceId', i) as string; + responseData = await clockifyApiRequestAllItems.call( + this, + 'GET', + `/workspaces/${workspaceId}/projects`, + {}, + qs, + ); - const tagId = this.getNodeParameter('tagId', i) as string; + responseData = responseData.splice(0, qs.limit); + } + } - responseData = await clockifyApiRequest.call( - this, - 'DELETE', - `/workspaces/${workspaceId}/tags/${tagId}`, - {}, - qs, - ); + if (operation === 'update') { - responseData = { success: true }; - } + const workspaceId = this.getNodeParameter('workspaceId', i) as string; - if (operation === 'getAll') { + const projectId = this.getNodeParameter('projectId', i) as string; - const returnAll = this.getNodeParameter('returnAll', i) as boolean; + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; - const workspaceId = this.getNodeParameter('workspaceId', i) as string; + const body: IDataObject = {}; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + Object.assign(body, updateFields); - Object.assign(qs, additionalFields); + if (body.estimateUi) { - if (returnAll) { - responseData = await clockifyApiRequestAllItems.call( + body.estimate = (body.estimateUi as IDataObject).estimateValues; + + delete body.estimateUi; + } + + responseData = await clockifyApiRequest.call( this, - 'GET', + 'PUT', + `/workspaces/${workspaceId}/projects/${projectId}`, + body, + qs, + ); + } + } + + if (resource === 'tag') { + + if (operation === 'create') { + + const workspaceId = this.getNodeParameter('workspaceId', i) as string; + + const name = this.getNodeParameter('name', i) as string; + + const body: IDataObject = { + name, + }; + + responseData = await clockifyApiRequest.call( + this, + 'POST', `/workspaces/${workspaceId}/tags`, - {}, + body, qs, ); + } - } else { + if (operation === 'delete') { - qs.limit = this.getNodeParameter('limit', i) as number; + const workspaceId = this.getNodeParameter('workspaceId', i) as string; - responseData = await clockifyApiRequestAllItems.call( + const tagId = this.getNodeParameter('tagId', i) as string; + + responseData = await clockifyApiRequest.call( this, - 'GET', - `/workspaces/${workspaceId}/tags`, + 'DELETE', + `/workspaces/${workspaceId}/tags/${tagId}`, {}, qs, ); - responseData = responseData.splice(0, qs.limit); + responseData = { success: true }; + } + + if (operation === 'getAll') { + + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + + const workspaceId = this.getNodeParameter('workspaceId', i) as string; + + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + + Object.assign(qs, additionalFields); + + if (returnAll) { + responseData = await clockifyApiRequestAllItems.call( + this, + 'GET', + `/workspaces/${workspaceId}/tags`, + {}, + qs, + ); + + } else { + + qs.limit = this.getNodeParameter('limit', i) as number; + + responseData = await clockifyApiRequestAllItems.call( + this, + 'GET', + `/workspaces/${workspaceId}/tags`, + {}, + qs, + ); + + responseData = responseData.splice(0, qs.limit); + } + } + + if (operation === 'update') { + + const workspaceId = this.getNodeParameter('workspaceId', i) as string; + + const tagId = this.getNodeParameter('tagId', i) as string; + + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + + const body: IDataObject = {}; + + Object.assign(body, updateFields); + + responseData = await clockifyApiRequest.call( + this, + 'PUT', + `/workspaces/${workspaceId}/tags/${tagId}`, + body, + qs, + ); } } - if (operation === 'update') { + if (resource === 'timeEntry') { - const workspaceId = this.getNodeParameter('workspaceId', i) as string; + if (operation === 'create') { - const tagId = this.getNodeParameter('tagId', i) as string; + const timezone = this.getTimezone(); - const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + const workspaceId = this.getNodeParameter('workspaceId', i) as string; - const body: IDataObject = {}; + const start = this.getNodeParameter('start', i) as string; - Object.assign(body, updateFields); + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - responseData = await clockifyApiRequest.call( - this, - 'PUT', - `/workspaces/${workspaceId}/tags/${tagId}`, - body, - qs, - ); - } - } + const body: IDataObject = { + start: moment.tz(start, timezone).utc().format(), + }; - if (resource === 'timeEntry') { + Object.assign(body, additionalFields); - if (operation === 'create') { + if (body.end) { + body.end = moment.tz(body.end, timezone).utc().format(); + } - const timezone = this.getTimezone(); + if (body.customFieldsUi) { - const workspaceId = this.getNodeParameter('workspaceId', i) as string; + const customFields = (body.customFieldsUi as IDataObject).customFieldsValues as IDataObject[]; - const start = this.getNodeParameter('start', i) as string; + body.customFields = customFields; + } - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - - const body: IDataObject = { - start: moment.tz(start, timezone).utc().format(), - }; - - Object.assign(body, additionalFields); - - if (body.end) { - body.end = moment.tz(body.end, timezone).utc().format(); + responseData = await clockifyApiRequest.call( + this, + 'POST', + `/workspaces/${workspaceId}/time-entries`, + body, + qs, + ); } - if (body.customFieldsUi) { + if (operation === 'delete') { - const customFields = (body.customFieldsUi as IDataObject).customFieldsValues as IDataObject[]; + const workspaceId = this.getNodeParameter('workspaceId', i) as string; - body.customFields = customFields; + const timeEntryId = this.getNodeParameter('timeEntryId', i) as string; + + responseData = await clockifyApiRequest.call( + this, + 'DELETE', + `/workspaces/${workspaceId}/time-entries/${timeEntryId}`, + {}, + qs, + ); + + responseData = { success: true }; } - responseData = await clockifyApiRequest.call( - this, - 'POST', - `/workspaces/${workspaceId}/time-entries`, - body, - qs, - ); - } + if (operation === 'get') { - if (operation === 'delete') { + const workspaceId = this.getNodeParameter('workspaceId', i) as string; - const workspaceId = this.getNodeParameter('workspaceId', i) as string; + const timeEntryId = this.getNodeParameter('timeEntryId', i) as string; - const timeEntryId = this.getNodeParameter('timeEntryId', i) as string; - - responseData = await clockifyApiRequest.call( - this, - 'DELETE', - `/workspaces/${workspaceId}/time-entries/${timeEntryId}`, - {}, - qs, - ); - - responseData = { success: true }; - } - - if (operation === 'get') { - - const workspaceId = this.getNodeParameter('workspaceId', i) as string; - - const timeEntryId = this.getNodeParameter('timeEntryId', i) as string; - - responseData = await clockifyApiRequest.call( - this, - 'GET', - `/workspaces/${workspaceId}/time-entries/${timeEntryId}`, - {}, - qs, - ); - } - - if (operation === 'update') { - - const timezone = this.getTimezone(); - - const workspaceId = this.getNodeParameter('workspaceId', i) as string; - - const timeEntryId = this.getNodeParameter('timeEntryId', i) as string; - - const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; - - const body: IDataObject = {}; - - Object.assign(body, updateFields); - - if (body.end) { - body.end = moment.tz(body.end, timezone).utc().format(); - } - - if (body.start) { - body.start = moment.tz(body.start, timezone).utc().format(); - } else { - // even if you do not want to update the start time, it always has to be set - // to make it more simple to the user, if he did not set a start time look for the current start time - // and set it - const { timeInterval: { start } } = await clockifyApiRequest.call( + responseData = await clockifyApiRequest.call( this, 'GET', `/workspaces/${workspaceId}/time-entries/${timeEntryId}`, {}, qs, ); - - body.start = start; } - responseData = await clockifyApiRequest.call( - this, - 'PUT', - `/workspaces/${workspaceId}/time-entries/${timeEntryId}`, - body, - qs, - ); + if (operation === 'update') { + + const timezone = this.getTimezone(); + + const workspaceId = this.getNodeParameter('workspaceId', i) as string; + + const timeEntryId = this.getNodeParameter('timeEntryId', i) as string; + + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + + const body: IDataObject = {}; + + Object.assign(body, updateFields); + + if (body.end) { + body.end = moment.tz(body.end, timezone).utc().format(); + } + + if (body.start) { + body.start = moment.tz(body.start, timezone).utc().format(); + } else { + // even if you do not want to update the start time, it always has to be set + // to make it more simple to the user, if he did not set a start time look for the current start time + // and set it + const { timeInterval: { start } } = await clockifyApiRequest.call( + this, + 'GET', + `/workspaces/${workspaceId}/time-entries/${timeEntryId}`, + {}, + qs, + ); + + body.start = start; + } + + responseData = await clockifyApiRequest.call( + this, + 'PUT', + `/workspaces/${workspaceId}/time-entries/${timeEntryId}`, + body, + qs, + ); + } } + + if (Array.isArray(responseData)) { + + returnData.push.apply(returnData, responseData as IDataObject[]); + + } else if (responseData !== undefined) { + + returnData.push(responseData as IDataObject); + } + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } } - if (Array.isArray(responseData)) { - - returnData.push.apply(returnData, responseData as IDataObject[]); - - } else if (responseData !== undefined) { - - returnData.push(responseData as IDataObject); - } - return [this.helpers.returnJsonArray(returnData)]; } } diff --git a/packages/nodes-base/nodes/Cockpit/Cockpit.node.ts b/packages/nodes-base/nodes/Cockpit/Cockpit.node.ts index 32335c5e95..52b6cc00ba 100644 --- a/packages/nodes-base/nodes/Cockpit/Cockpit.node.ts +++ b/packages/nodes-base/nodes/Cockpit/Cockpit.node.ts @@ -120,48 +120,56 @@ export class Cockpit implements INodeType { let responseData; for (let i = 0; i < length; i++) { - if (resource === 'collection') { - const collectionName = this.getNodeParameter('collection', i) as string; + try { + if (resource === 'collection') { + const collectionName = this.getNodeParameter('collection', i) as string; - if (operation === 'create') { - const data = createDataFromParameters.call(this, i); + if (operation === 'create') { + const data = createDataFromParameters.call(this, i); - responseData = await createCollectionEntry.call(this, collectionName, data); - } else if (operation === 'getAll') { - const options = this.getNodeParameter('options', i) as IDataObject; - const returnAll = this.getNodeParameter('returnAll', i) as boolean; + responseData = await createCollectionEntry.call(this, collectionName, data); + } else if (operation === 'getAll') { + const options = this.getNodeParameter('options', i) as IDataObject; + const returnAll = this.getNodeParameter('returnAll', i) as boolean; - if (!returnAll) { - options.limit = this.getNodeParameter('limit', i) as number; + if (!returnAll) { + options.limit = this.getNodeParameter('limit', i) as number; + } + + responseData = await getAllCollectionEntries.call(this, collectionName, options); + } else if (operation === 'update') { + const id = this.getNodeParameter('id', i) as string; + const data = createDataFromParameters.call(this, i); + + responseData = await createCollectionEntry.call(this, collectionName, data, id); } + } else if (resource === 'form') { + const formName = this.getNodeParameter('form', i) as string; - responseData = await getAllCollectionEntries.call(this, collectionName, options); - } else if (operation === 'update') { - const id = this.getNodeParameter('id', i) as string; - const data = createDataFromParameters.call(this, i); + if (operation === 'submit') { + const form = createDataFromParameters.call(this, i); - responseData = await createCollectionEntry.call(this, collectionName, data, id); + responseData = await submitForm.call(this, formName, form); + } + } else if (resource === 'singleton') { + const singletonName = this.getNodeParameter('singleton', i) as string; + + if (operation === 'get') { + responseData = await getSingleton.call(this, singletonName); + } } - } else if (resource === 'form') { - const formName = this.getNodeParameter('form', i) as string; - if (operation === 'submit') { - const form = createDataFromParameters.call(this, i); - - responseData = await submitForm.call(this, formName, form); + if (Array.isArray(responseData)) { + returnData.push.apply(returnData, responseData as IDataObject[]); + } else { + returnData.push(responseData as IDataObject); } - } else if (resource === 'singleton') { - const singletonName = this.getNodeParameter('singleton', i) as string; - - if (operation === 'get') { - responseData = await getSingleton.call(this, singletonName); + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; } - } - - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else { - returnData.push(responseData as IDataObject); + throw error; } } diff --git a/packages/nodes-base/nodes/Coda/Coda.node.ts b/packages/nodes-base/nodes/Coda/Coda.node.ts index 3a0d99afbd..875635edc3 100644 --- a/packages/nodes-base/nodes/Coda/Coda.node.ts +++ b/packages/nodes-base/nodes/Coda/Coda.node.ts @@ -231,78 +231,92 @@ export class Coda implements INodeType { if (resource === 'table') { // https://coda.io/developers/apis/v1beta1#operation/upsertRows if (operation === 'createRow') { - const sendData = {} as IDataObject; - for (let i = 0; i < items.length; i++) { - qs = {}; - const docId = this.getNodeParameter('docId', i) as string; - const tableId = this.getNodeParameter('tableId', i) as string; - const options = this.getNodeParameter('options', i) as IDataObject; - const endpoint = `/docs/${docId}/tables/${tableId}/rows`; + try { + const sendData = {} as IDataObject; + for (let i = 0; i < items.length; i++) { + qs = {}; + const docId = this.getNodeParameter('docId', i) as string; + const tableId = this.getNodeParameter('tableId', i) as string; + const options = this.getNodeParameter('options', i) as IDataObject; + const endpoint = `/docs/${docId}/tables/${tableId}/rows`; - if (options.disableParsing) { - qs.disableParsing = options.disableParsing as boolean; + if (options.disableParsing) { + qs.disableParsing = options.disableParsing as boolean; + } + + const cells = []; + cells.length = 0; + for (const key of Object.keys(items[i].json)) { + cells.push({ + column: key, + value: items[i].json[key], + }); + } + + // Collect all the data for the different docs/tables + if (sendData[endpoint] === undefined) { + sendData[endpoint] = { + rows: [], + // TODO: This is not perfect as it ignores if qs changes between + // different items but should be OK for now + qs, + }; + } + ((sendData[endpoint]! as IDataObject).rows! as IDataObject[]).push({ cells }); + + if (options.keyColumns) { + // @ts-ignore + (sendData[endpoint]! as IDataObject).keyColumns! = options.keyColumns.split(',') as string[]; + } } - const cells = []; - cells.length = 0; - for (const key of Object.keys(items[i].json)) { - cells.push({ - column: key, - value: items[i].json[key], - }); + // Now that all data got collected make all the requests + for (const endpoint of Object.keys(sendData)) { + await codaApiRequest.call(this, 'POST', endpoint, sendData[endpoint], (sendData[endpoint]! as IDataObject).qs! as IDataObject); } - - // Collect all the data for the different docs/tables - if (sendData[endpoint] === undefined) { - sendData[endpoint] = { - rows: [], - // TODO: This is not perfect as it ignores if qs changes between - // different items but should be OK for now - qs, - }; - } - ((sendData[endpoint]! as IDataObject).rows! as IDataObject[]).push({ cells }); - - if (options.keyColumns) { - // @ts-ignore - (sendData[endpoint]! as IDataObject).keyColumns! = options.keyColumns.split(',') as string[]; + } catch (error) { + if (this.continueOnFail()) { + return [this.helpers.returnJsonArray({ error: error.message })]; } + throw error; } - - // Now that all data got collected make all the requests - for (const endpoint of Object.keys(sendData)) { - await codaApiRequest.call(this, 'POST', endpoint, sendData[endpoint], (sendData[endpoint]! as IDataObject).qs! as IDataObject); - } - // Return the incoming data return [items]; } // https://coda.io/developers/apis/v1beta1#operation/getRow if (operation === 'getRow') { for (let i = 0; i < items.length; i++) { - const docId = this.getNodeParameter('docId', i) as string; - const tableId = this.getNodeParameter('tableId', i) as string; - const rowId = this.getNodeParameter('rowId', i) as string; - const options = this.getNodeParameter('options', i) as IDataObject; + try { + const docId = this.getNodeParameter('docId', i) as string; + const tableId = this.getNodeParameter('tableId', i) as string; + const rowId = this.getNodeParameter('rowId', i) as string; + const options = this.getNodeParameter('options', i) as IDataObject; - const endpoint = `/docs/${docId}/tables/${tableId}/rows/${rowId}`; - if (options.useColumnNames === false) { - qs.useColumnNames = options.useColumnNames as boolean; - } else { - qs.useColumnNames = true; - } - if (options.valueFormat) { - qs.valueFormat = options.valueFormat as string; - } + const endpoint = `/docs/${docId}/tables/${tableId}/rows/${rowId}`; + if (options.useColumnNames === false) { + qs.useColumnNames = options.useColumnNames as boolean; + } else { + qs.useColumnNames = true; + } + if (options.valueFormat) { + qs.valueFormat = options.valueFormat as string; + } - responseData = await codaApiRequest.call(this, 'GET', endpoint, {}, qs); - if (options.rawData === true) { - returnData.push(responseData); - } else { - returnData.push({ - id: responseData.id, - ...responseData.values, - }); + responseData = await codaApiRequest.call(this, 'GET', endpoint, {}, qs); + if (options.rawData === true) { + returnData.push(responseData); + } else { + returnData.push({ + id: responseData.id, + ...responseData.values, + }); + } + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } } @@ -341,6 +355,9 @@ export class Coda implements INodeType { responseData = responseData.items; } } catch (error) { + if (this.continueOnFail()) { + return [this.helpers.returnJsonArray({ error: error.message })]; + } throw new NodeApiError(this.getNode(), error); } @@ -358,69 +375,99 @@ export class Coda implements INodeType { } // https://coda.io/developers/apis/v1beta1#operation/deleteRows if (operation === 'deleteRow') { - const sendData = {} as IDataObject; - for (let i = 0; i < items.length; i++) { - const docId = this.getNodeParameter('docId', i) as string; - const tableId = this.getNodeParameter('tableId', i) as string; - const rowId = this.getNodeParameter('rowId', i) as string; - const endpoint = `/docs/${docId}/tables/${tableId}/rows`; + try { + const sendData = {} as IDataObject; + for (let i = 0; i < items.length; i++) { + const docId = this.getNodeParameter('docId', i) as string; + const tableId = this.getNodeParameter('tableId', i) as string; + const rowId = this.getNodeParameter('rowId', i) as string; + const endpoint = `/docs/${docId}/tables/${tableId}/rows`; - // Collect all the data for the different docs/tables - if (sendData[endpoint] === undefined) { - sendData[endpoint] = []; + // Collect all the data for the different docs/tables + if (sendData[endpoint] === undefined) { + sendData[endpoint] = []; + } + + (sendData[endpoint] as string[]).push(rowId); } - (sendData[endpoint] as string[]).push(rowId); + // Now that all data got collected make all the requests + for (const endpoint of Object.keys(sendData)) { + await codaApiRequest.call(this, 'DELETE', endpoint, { rowIds: sendData[endpoint]}, qs); + } + } catch (error) { + if (this.continueOnFail()) { + return [this.helpers.returnJsonArray({ error: error.message })]; + } + throw error; } - - // Now that all data got collected make all the requests - for (const endpoint of Object.keys(sendData)) { - await codaApiRequest.call(this, 'DELETE', endpoint, { rowIds: sendData[endpoint]}, qs); - } - // Return the incoming data return [items]; } // https://coda.io/developers/apis/v1beta1#operation/pushButton if (operation === 'pushButton') { for (let i = 0; i < items.length; i++) { - const docId = this.getNodeParameter('docId', i) as string; - const tableId = this.getNodeParameter('tableId', i) as string; - const rowId = this.getNodeParameter('rowId', i) as string; - const columnId = this.getNodeParameter('columnId', i) as string; - const endpoint = `/docs/${docId}/tables/${tableId}/rows/${rowId}/buttons/${columnId}`; - responseData = await codaApiRequest.call(this, 'POST', endpoint, {}); - returnData.push(responseData); + try { + const docId = this.getNodeParameter('docId', i) as string; + const tableId = this.getNodeParameter('tableId', i) as string; + const rowId = this.getNodeParameter('rowId', i) as string; + const columnId = this.getNodeParameter('columnId', i) as string; + const endpoint = `/docs/${docId}/tables/${tableId}/rows/${rowId}/buttons/${columnId}`; + responseData = await codaApiRequest.call(this, 'POST', endpoint, {}); + returnData.push(responseData); + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; + } } return [this.helpers.returnJsonArray(returnData)]; } //https://coda.io/developers/apis/v1beta1#operation/getColumn if (operation === 'getColumn') { for (let i = 0; i < items.length; i++) { - const docId = this.getNodeParameter('docId', i) as string; - const tableId = this.getNodeParameter('tableId', i) as string; - const columnId = this.getNodeParameter('columnId', i) as string; - const endpoint = `/docs/${docId}/tables/${tableId}/columns/${columnId}`; - responseData = await codaApiRequest.call(this, 'GET', endpoint, {}); - returnData.push(responseData); + try { + const docId = this.getNodeParameter('docId', i) as string; + const tableId = this.getNodeParameter('tableId', i) as string; + const columnId = this.getNodeParameter('columnId', i) as string; + const endpoint = `/docs/${docId}/tables/${tableId}/columns/${columnId}`; + responseData = await codaApiRequest.call(this, 'GET', endpoint, {}); + returnData.push(responseData); + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; + } } return [this.helpers.returnJsonArray(returnData)]; } //https://coda.io/developers/apis/v1beta1#operation/listColumns if (operation === 'getAllColumns') { for (let i = 0; i < items.length; i++) { - const returnAll = this.getNodeParameter('returnAll', 0) as boolean; - const docId = this.getNodeParameter('docId', i) as string; - const tableId = this.getNodeParameter('tableId', i) as string; - const endpoint = `/docs/${docId}/tables/${tableId}/columns`; - if (returnAll) { - responseData = await codaApiRequestAllItems.call(this, 'items', 'GET', endpoint, {}); - } else { - qs.limit = this.getNodeParameter('limit', 0) as number; - responseData = await codaApiRequest.call(this, 'GET', endpoint, {}, qs); - responseData = responseData.items; + try { + const returnAll = this.getNodeParameter('returnAll', 0) as boolean; + const docId = this.getNodeParameter('docId', i) as string; + const tableId = this.getNodeParameter('tableId', i) as string; + const endpoint = `/docs/${docId}/tables/${tableId}/columns`; + if (returnAll) { + responseData = await codaApiRequestAllItems.call(this, 'items', 'GET', endpoint, {}); + } else { + qs.limit = this.getNodeParameter('limit', 0) as number; + responseData = await codaApiRequest.call(this, 'GET', endpoint, {}, qs); + responseData = responseData.items; + } + returnData.push.apply(returnData,responseData); + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } - returnData.push.apply(returnData,responseData); } return [this.helpers.returnJsonArray(returnData)]; } @@ -429,28 +476,44 @@ export class Coda implements INodeType { //https://coda.io/developers/apis/v1beta1#operation/getFormula if (operation === 'get') { for (let i = 0; i < items.length; i++) { - const docId = this.getNodeParameter('docId', i) as string; - const formulaId = this.getNodeParameter('formulaId', i) as string; - const endpoint = `/docs/${docId}/formulas/${formulaId}`; - responseData = await codaApiRequest.call(this, 'GET', endpoint, {}); - returnData.push(responseData); + try { + const docId = this.getNodeParameter('docId', i) as string; + const formulaId = this.getNodeParameter('formulaId', i) as string; + const endpoint = `/docs/${docId}/formulas/${formulaId}`; + responseData = await codaApiRequest.call(this, 'GET', endpoint, {}); + returnData.push(responseData); + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; + } } return [this.helpers.returnJsonArray(returnData)]; } //https://coda.io/developers/apis/v1beta1#operation/listFormulas if (operation === 'getAll') { for (let i = 0; i < items.length; i++) { - const returnAll = this.getNodeParameter('returnAll', 0) as boolean; - const docId = this.getNodeParameter('docId', i) as string; - const endpoint = `/docs/${docId}/formulas`; - if (returnAll) { - responseData = await codaApiRequestAllItems.call(this, 'items', 'GET', endpoint, {}); - } else { - qs.limit = this.getNodeParameter('limit', 0) as number; - responseData = await codaApiRequest.call(this, 'GET', endpoint, {}, qs); - responseData = responseData.items; + try { + const returnAll = this.getNodeParameter('returnAll', 0) as boolean; + const docId = this.getNodeParameter('docId', i) as string; + const endpoint = `/docs/${docId}/formulas`; + if (returnAll) { + responseData = await codaApiRequestAllItems.call(this, 'items', 'GET', endpoint, {}); + } else { + qs.limit = this.getNodeParameter('limit', 0) as number; + responseData = await codaApiRequest.call(this, 'GET', endpoint, {}, qs); + responseData = responseData.items; + } + returnData.push.apply(returnData,responseData); + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } - returnData.push.apply(returnData,responseData); } return [this.helpers.returnJsonArray(returnData)]; } @@ -459,28 +522,44 @@ export class Coda implements INodeType { //https://coda.io/developers/apis/v1beta1#operation/getControl if (operation === 'get') { for (let i = 0; i < items.length; i++) { - const docId = this.getNodeParameter('docId', i) as string; - const controlId = this.getNodeParameter('controlId', i) as string; - const endpoint = `/docs/${docId}/controls/${controlId}`; - responseData = await codaApiRequest.call(this, 'GET', endpoint, {}); - returnData.push(responseData); + try { + const docId = this.getNodeParameter('docId', i) as string; + const controlId = this.getNodeParameter('controlId', i) as string; + const endpoint = `/docs/${docId}/controls/${controlId}`; + responseData = await codaApiRequest.call(this, 'GET', endpoint, {}); + returnData.push(responseData); + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; + } } return [this.helpers.returnJsonArray(returnData)]; } //https://coda.io/developers/apis/v1beta1#operation/listControls if (operation === 'getAll') { for (let i = 0; i < items.length; i++) { - const returnAll = this.getNodeParameter('returnAll', 0) as boolean; - const docId = this.getNodeParameter('docId', i) as string; - const endpoint = `/docs/${docId}/controls`; - if (returnAll) { - responseData = await codaApiRequestAllItems.call(this, 'items', 'GET', endpoint, {}); - } else { - qs.limit = this.getNodeParameter('limit', 0) as number; - responseData = await codaApiRequest.call(this, 'GET', endpoint, {}, qs); - responseData = responseData.items; + try { + const returnAll = this.getNodeParameter('returnAll', 0) as boolean; + const docId = this.getNodeParameter('docId', i) as string; + const endpoint = `/docs/${docId}/controls`; + if (returnAll) { + responseData = await codaApiRequestAllItems.call(this, 'items', 'GET', endpoint, {}); + } else { + qs.limit = this.getNodeParameter('limit', 0) as number; + responseData = await codaApiRequest.call(this, 'GET', endpoint, {}, qs); + responseData = responseData.items; + } + returnData.push.apply(returnData,responseData); + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } - returnData.push.apply(returnData,responseData); } return [this.helpers.returnJsonArray(returnData)]; } @@ -500,17 +579,25 @@ export class Coda implements INodeType { //https://coda.io/developers/apis/v1beta1#operation/listViews if (operation === 'getAll') { for (let i = 0; i < items.length; i++) { - const returnAll = this.getNodeParameter('returnAll', 0) as boolean; - const docId = this.getNodeParameter('docId', i) as string; - const endpoint = `/docs/${docId}/tables?tableTypes=view`; - if (returnAll) { - responseData = await codaApiRequestAllItems.call(this, 'items', 'GET', endpoint, {}); - } else { - qs.limit = this.getNodeParameter('limit', 0) as number; - responseData = await codaApiRequest.call(this, 'GET', endpoint, {}, qs); - responseData = responseData.items; + try { + const returnAll = this.getNodeParameter('returnAll', 0) as boolean; + const docId = this.getNodeParameter('docId', i) as string; + const endpoint = `/docs/${docId}/tables?tableTypes=view`; + if (returnAll) { + responseData = await codaApiRequestAllItems.call(this, 'items', 'GET', endpoint, {}); + } else { + qs.limit = this.getNodeParameter('limit', 0) as number; + responseData = await codaApiRequest.call(this, 'GET', endpoint, {}, qs); + responseData = responseData.items; + } + returnData.push.apply(returnData,responseData); + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } - returnData.push.apply(returnData,responseData); } return [this.helpers.returnJsonArray(returnData)]; } @@ -543,6 +630,9 @@ export class Coda implements INodeType { responseData = responseData.items; } } catch (error) { + if (this.continueOnFail()) { + return [this.helpers.returnJsonArray({ error: error.message })]; + } throw new NodeApiError(this.getNode(), error); } @@ -561,74 +651,106 @@ export class Coda implements INodeType { //https://coda.io/developers/apis/v1beta1#operation/deleteViewRow if (operation === 'deleteViewRow') { for (let i = 0; i < items.length; i++) { - const docId = this.getNodeParameter('docId', i) as string; - const viewId = this.getNodeParameter('viewId', i) as string; - const rowId = this.getNodeParameter('rowId', i) as string; - const endpoint = `/docs/${docId}/tables/${viewId}/rows/${rowId}`; - responseData = await codaApiRequest.call(this, 'DELETE', endpoint); - returnData.push.apply(returnData,responseData); + try { + const docId = this.getNodeParameter('docId', i) as string; + const viewId = this.getNodeParameter('viewId', i) as string; + const rowId = this.getNodeParameter('rowId', i) as string; + const endpoint = `/docs/${docId}/tables/${viewId}/rows/${rowId}`; + responseData = await codaApiRequest.call(this, 'DELETE', endpoint); + returnData.push.apply(returnData,responseData); + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; + } } return [this.helpers.returnJsonArray(returnData)]; } //https://coda.io/developers/apis/v1beta1#operation/pushViewButton if (operation === 'pushViewButton') { for (let i = 0; i < items.length; i++) { - const docId = this.getNodeParameter('docId', i) as string; - const viewId = this.getNodeParameter('viewId', i) as string; - const rowId = this.getNodeParameter('rowId', i) as string; - const columnId = this.getNodeParameter('columnId', i) as string; - const endpoint = `/docs/${docId}/tables/${viewId}/rows/${rowId}/buttons/${columnId}`; - responseData = await codaApiRequest.call(this, 'POST', endpoint); - returnData.push.apply(returnData,responseData); + try { + const docId = this.getNodeParameter('docId', i) as string; + const viewId = this.getNodeParameter('viewId', i) as string; + const rowId = this.getNodeParameter('rowId', i) as string; + const columnId = this.getNodeParameter('columnId', i) as string; + const endpoint = `/docs/${docId}/tables/${viewId}/rows/${rowId}/buttons/${columnId}`; + responseData = await codaApiRequest.call(this, 'POST', endpoint); + returnData.push.apply(returnData,responseData); + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; + } } return [this.helpers.returnJsonArray(returnData)]; } if (operation === 'getAllViewColumns') { for (let i = 0; i < items.length; i++) { - const returnAll = this.getNodeParameter('returnAll', 0) as boolean; - const docId = this.getNodeParameter('docId', i) as string; - const viewId = this.getNodeParameter('viewId', i) as string; - const endpoint = `/docs/${docId}/tables/${viewId}/columns`; - if (returnAll) { - responseData = await codaApiRequestAllItems.call(this, 'items', 'GET', endpoint, {}); - } else { - qs.limit = this.getNodeParameter('limit', 0) as number; - responseData = await codaApiRequest.call(this, 'GET', endpoint, {}, qs); - responseData = responseData.items; + try { + const returnAll = this.getNodeParameter('returnAll', 0) as boolean; + const docId = this.getNodeParameter('docId', i) as string; + const viewId = this.getNodeParameter('viewId', i) as string; + const endpoint = `/docs/${docId}/tables/${viewId}/columns`; + if (returnAll) { + responseData = await codaApiRequestAllItems.call(this, 'items', 'GET', endpoint, {}); + } else { + qs.limit = this.getNodeParameter('limit', 0) as number; + responseData = await codaApiRequest.call(this, 'GET', endpoint, {}, qs); + responseData = responseData.items; + } + returnData.push.apply(returnData,responseData); + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } - returnData.push.apply(returnData,responseData); } return [this.helpers.returnJsonArray(returnData)]; } //https://coda.io/developers/apis/v1beta1#operation/updateViewRow if (operation === 'updateViewRow') { for (let i = 0; i < items.length; i++) { - qs = {}; - const docId = this.getNodeParameter('docId', i) as string; - const viewId = this.getNodeParameter('viewId', i) as string; - const rowId = this.getNodeParameter('rowId', i) as string; - const keyName = this.getNodeParameter('keyName', i) as string; - const options = this.getNodeParameter('options', i) as IDataObject; - const body: IDataObject = {}; - const endpoint = `/docs/${docId}/tables/${viewId}/rows/${rowId}`; - if (options.disableParsing) { - qs.disableParsing = options.disableParsing as boolean; - } - const cells = []; - cells.length = 0; + try { + qs = {}; + const docId = this.getNodeParameter('docId', i) as string; + const viewId = this.getNodeParameter('viewId', i) as string; + const rowId = this.getNodeParameter('rowId', i) as string; + const keyName = this.getNodeParameter('keyName', i) as string; + const options = this.getNodeParameter('options', i) as IDataObject; + const body: IDataObject = {}; + const endpoint = `/docs/${docId}/tables/${viewId}/rows/${rowId}`; + if (options.disableParsing) { + qs.disableParsing = options.disableParsing as boolean; + } + const cells = []; + cells.length = 0; - //@ts-ignore - for (const key of Object.keys(items[i].json[keyName])) { - cells.push({ - column: key, - //@ts-ignore - value: items[i].json[keyName][key], - }); + //@ts-ignore + for (const key of Object.keys(items[i].json[keyName])) { + cells.push({ + column: key, + //@ts-ignore + value: items[i].json[keyName][key], + }); + } + body.row = { + cells, + }; + await codaApiRequest.call(this, 'PUT', endpoint, body, qs); + } catch (error) { + if (this.continueOnFail()) { + items[i].json = { error: error.message }; + continue; + } + throw error; } - body.row = { - cells, - }; - await codaApiRequest.call(this, 'PUT', endpoint, body, qs); } return [items]; } diff --git a/packages/nodes-base/nodes/CoinGecko/CoinGecko.node.ts b/packages/nodes-base/nodes/CoinGecko/CoinGecko.node.ts index 7a4bcbdfb0..520a115b7a 100644 --- a/packages/nodes-base/nodes/CoinGecko/CoinGecko.node.ts +++ b/packages/nodes-base/nodes/CoinGecko/CoinGecko.node.ts @@ -169,126 +169,330 @@ export class CoinGecko implements INodeType { const resource = this.getNodeParameter('resource', 0) as string; const operation = this.getNodeParameter('operation', 0) as string; for (let i = 0; i < length; i++) { + try { + if (resource === 'coin') { + //https://www.coingecko.com/api/documentations/v3#/coins/get_coins__id_ + //https://www.coingecko.com/api/documentations/v3#/contract/get_coins__id__contract__contract_address_ + if (operation === 'get') { - if (resource === 'coin') { - //https://www.coingecko.com/api/documentations/v3#/coins/get_coins__id_ - //https://www.coingecko.com/api/documentations/v3#/contract/get_coins__id__contract__contract_address_ - if (operation === 'get') { + const options = this.getNodeParameter('options', i) as IDataObject; - const options = this.getNodeParameter('options', i) as IDataObject; + qs.community_data = false; + qs.developer_data = false; + qs.localization = false; + qs.market_data = false; + qs.sparkline = false; + qs.tickers = false; - qs.community_data = false; - qs.developer_data = false; - qs.localization = false; - qs.market_data = false; - qs.sparkline = false; - qs.tickers = false; + Object.assign(qs, options); - Object.assign(qs, options); + const searchBy = this.getNodeParameter('searchBy', i) as string; - const searchBy = this.getNodeParameter('searchBy', i) as string; + if (searchBy === 'coinId') { + const coinId = this.getNodeParameter('coinId', i) as string; - if (searchBy === 'coinId') { + responseData = await coinGeckoApiRequest.call( + this, + 'GET', + `/coins/${coinId}`, + {}, + qs, + ); + } + + if (searchBy === 'contractAddress') { + const platformId = this.getNodeParameter('platformId', i) as string; + const contractAddress = this.getNodeParameter('contractAddress', i) as string; + + responseData = await coinGeckoApiRequest.call( + this, + 'GET', + `/coins/${platformId}/contract/${contractAddress}`, + {}, + qs, + ); + } + } + //https://www.coingecko.com/api/documentations/v3#/coins/get_coins_list + if (operation === 'getAll') { + + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + + let limit; + + responseData = await coinGeckoApiRequest.call( + this, + 'GET', + '/coins/list', + {}, + qs, + ); + + if (returnAll === false) { + limit = this.getNodeParameter('limit', i) as number; + responseData = responseData.splice(0, limit); + } + } + + //https://www.coingecko.com/api/documentations/v3#/coins/get_coins_list + if (operation === 'market') { + + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + const baseCurrency = this.getNodeParameter('baseCurrency', i) as string; + const options = this.getNodeParameter('options', i) as IDataObject; + + qs.vs_currency = baseCurrency; + + Object.assign(qs, options); + + if (options.price_change_percentage) { + qs.price_change_percentage = (options.price_change_percentage as string[]).join(','); + } + + if (returnAll) { + responseData = await coinGeckoRequestAllItems.call( + this, + '', + 'GET', + `/coins/markets`, + {}, + qs, + ); + } else { + const limit = this.getNodeParameter('limit', i) as number; + + qs.per_page = limit; + + responseData = await coinGeckoApiRequest.call( + this, + 'GET', + `/coins/markets`, + {}, + qs, + ); + } + } + + //https://www.coingecko.com/api/documentations/v3#/simple/get_simple_price + //https://www.coingecko.com/api/documentations/v3#/simple/get_simple_token_price__id_ + if (operation === 'price') { + + const searchBy = this.getNodeParameter('searchBy', i) as string; + const quoteCurrencies = this.getNodeParameter('quoteCurrencies', i) as string[]; + const options = this.getNodeParameter('options', i) as IDataObject; + + qs.vs_currencies = quoteCurrencies.join(','); + + Object.assign(qs, options); + + if (searchBy === 'coinId') { + const baseCurrencies = this.getNodeParameter('baseCurrencies', i) as string[]; + + qs.ids = baseCurrencies.join(','); + + responseData = await coinGeckoApiRequest.call( + this, + 'GET', + '/simple/price', + {}, + qs, + ); + } + + if (searchBy === 'contractAddress') { + const platformId = this.getNodeParameter('platformId', i) as string; + const contractAddresses = this.getNodeParameter('contractAddresses', i) as string; + + qs.contract_addresses = contractAddresses; + + responseData = await coinGeckoApiRequest.call( + this, + 'GET', + `/simple/token_price/${platformId}`, + {}, + qs, + ); + } + } + + //https://www.coingecko.com/api/documentations/v3#/coins/get_coins__id__tickers + if (operation === 'ticker') { + + const returnAll = this.getNodeParameter('returnAll', i) as boolean; const coinId = this.getNodeParameter('coinId', i) as string; + const options = this.getNodeParameter('options', i) as IDataObject; + + Object.assign(qs, options); + + if (options.exchange_ids) { + qs.exchange_ids = (options.exchange_ids as string[]).join(','); + } + + if (returnAll) { + + responseData = await coinGeckoRequestAllItems.call( + this, + 'tickers', + 'GET', + `/coins/${coinId}/tickers`, + {}, + qs, + ); + } else { + const limit = this.getNodeParameter('limit', i) as number; + + responseData = await coinGeckoApiRequest.call( + this, + 'GET', + `/coins/${coinId}/tickers`, + {}, + qs, + ); + + responseData = responseData.tickers; + responseData = responseData.splice(0, limit); + } + } + + //https://www.coingecko.com/api/documentations/v3#/coins/get_coins__id__history + if (operation === 'history') { + + const coinId = this.getNodeParameter('coinId', i) as string; + const date = this.getNodeParameter('date', i) as string; + const options = this.getNodeParameter('options', i) as IDataObject; + + Object.assign(qs, options); + + qs.date = moment(date).format('DD-MM-YYYY'); responseData = await coinGeckoApiRequest.call( this, 'GET', - `/coins/${coinId}`, + `/coins/${coinId}/history`, {}, qs, ); } - if (searchBy === 'contractAddress') { - const platformId = this.getNodeParameter('platformId', i) as string; - const contractAddress = this.getNodeParameter('contractAddress', i) as string; + //https://www.coingecko.com/api/documentations/v3#/coins/get_coins__id__market_chart + //https://www.coingecko.com/api/documentations/v3#/contract/get_coins__id__contract__contract_address__market_chart_ + if (operation === 'marketChart') { + + let respData; + + const searchBy = this.getNodeParameter('searchBy', i) as string; + const quoteCurrency = this.getNodeParameter('quoteCurrency', i) as string; + const days = this.getNodeParameter('days', i) as string; + + qs.vs_currency = quoteCurrency; + qs.days = days; + + if (searchBy === 'coinId') { + const coinId = this.getNodeParameter('baseCurrency', i) as string; + + respData = await coinGeckoApiRequest.call( + this, + 'GET', + `/coins/${coinId}/market_chart`, + {}, + qs, + ); + } + + if (searchBy === 'contractAddress') { + const platformId = this.getNodeParameter('platformId', i) as string; + const contractAddress = this.getNodeParameter('contractAddress', i) as string; + + respData = await coinGeckoApiRequest.call( + this, + 'GET', + `/coins/${platformId}/contract/${contractAddress}/market_chart`, + {}, + qs, + ); + } + + responseData = []; + for (let idx = 0; idx < respData.prices.length; idx++) { + const [time, price] = respData.prices[idx]; + const marketCaps = respData.market_caps[idx][1]; + const totalVolume = respData.total_volumes[idx][1]; + responseData.push({ time: moment(time).toISOString(), price, marketCaps, totalVolume } as IDataObject); + } + } + + //https://www.coingecko.com/api/documentations/v3#/coins/get_coins__id__ohlc + if (operation === 'candlestick') { + + const baseCurrency = this.getNodeParameter('baseCurrency', i) as string; + const quoteCurrency = this.getNodeParameter('quoteCurrency', i) as string; + const days = this.getNodeParameter('days', i) as string; + + qs.vs_currency = quoteCurrency; + qs.days = days; responseData = await coinGeckoApiRequest.call( this, 'GET', - `/coins/${platformId}/contract/${contractAddress}`, + `/coins/${baseCurrency}/ohlc`, {}, qs, ); - } - } - //https://www.coingecko.com/api/documentations/v3#/coins/get_coins_list - if (operation === 'getAll') { - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - - let limit; - - responseData = await coinGeckoApiRequest.call( - this, - 'GET', - '/coins/list', - {}, - qs, - ); - - if (returnAll === false) { - limit = this.getNodeParameter('limit', i) as number; - responseData = responseData.splice(0, limit); + for (let idx = 0; idx < responseData.length; idx++) { + const [time, open, high, low, close] = responseData[idx]; + responseData[idx] = { time: moment(time).toISOString(), open, high, low, close } as IDataObject; + } } } - //https://www.coingecko.com/api/documentations/v3#/coins/get_coins_list - if (operation === 'market') { + if (resource === 'event') { + //https://www.coingecko.com/api/documentations/v3#/events/get_events + if (operation === 'getAll') { - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - const baseCurrency = this.getNodeParameter('baseCurrency', i) as string; - const options = this.getNodeParameter('options', i) as IDataObject; + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + const options = this.getNodeParameter('options', i) as IDataObject; - qs.vs_currency = baseCurrency; + Object.assign(qs, options); - Object.assign(qs, options); + if (returnAll) { + responseData = await coinGeckoRequestAllItems.call( + this, + 'data', + 'GET', + '/events', + {}, + qs, + ); + } else { + const limit = this.getNodeParameter('limit', i) as number; - if (options.price_change_percentage) { - qs.price_change_percentage = (options.price_change_percentage as string[]).join(','); - } + qs.per_page = limit; - if (returnAll) { - responseData = await coinGeckoRequestAllItems.call( - this, - '', - 'GET', - `/coins/markets`, - {}, - qs, - ); - } else { - const limit = this.getNodeParameter('limit', i) as number; - - qs.per_page = limit; - - responseData = await coinGeckoApiRequest.call( - this, - 'GET', - `/coins/markets`, - {}, - qs, - ); + responseData = await coinGeckoApiRequest.call( + this, + 'GET', + '/events', + {}, + qs, + ); + responseData = responseData.data; + } } } - //https://www.coingecko.com/api/documentations/v3#/simple/get_simple_price - //https://www.coingecko.com/api/documentations/v3#/simple/get_simple_token_price__id_ - if (operation === 'price') { + if (resource === 'simple') { + //https://www.coingecko.com/api/documentations/v3#/simple/get_simple_price + if (operation === 'price') { - const searchBy = this.getNodeParameter('searchBy', i) as string; - const quoteCurrencies = this.getNodeParameter('quoteCurrencies', i) as string[]; - const options = this.getNodeParameter('options', i) as IDataObject; + const ids = this.getNodeParameter('ids', i) as string; + const currencies = this.getNodeParameter('currencies', i) as string[]; + const options = this.getNodeParameter('options', i) as IDataObject; - qs.vs_currencies = quoteCurrencies.join(','); + qs.ids = ids, + qs.vs_currencies = currencies.join(','); - Object.assign(qs, options); - - if (searchBy === 'coinId') { - const baseCurrencies = this.getNodeParameter('baseCurrencies', i) as string[]; - - qs.ids = baseCurrencies.join(','); + Object.assign(qs, options); responseData = await coinGeckoApiRequest.call( this, @@ -299,237 +503,40 @@ export class CoinGecko implements INodeType { ); } - if (searchBy === 'contractAddress') { - const platformId = this.getNodeParameter('platformId', i) as string; + //https://www.coingecko.com/api/documentations/v3#/simple/get_simple_token_price__id_ + if (operation === 'tokenPrice') { + + const id = this.getNodeParameter('id', i) as string; const contractAddresses = this.getNodeParameter('contractAddresses', i) as string; + const currencies = this.getNodeParameter('currencies', i) as string[]; + const options = this.getNodeParameter('options', i) as IDataObject; qs.contract_addresses = contractAddresses; - - responseData = await coinGeckoApiRequest.call( - this, - 'GET', - `/simple/token_price/${platformId}`, - {}, - qs, - ); - } - } - - //https://www.coingecko.com/api/documentations/v3#/coins/get_coins__id__tickers - if (operation === 'ticker') { - - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - const coinId = this.getNodeParameter('coinId', i) as string; - const options = this.getNodeParameter('options', i) as IDataObject; - - Object.assign(qs, options); - - if (options.exchange_ids) { - qs.exchange_ids = (options.exchange_ids as string[]).join(','); - } - - if (returnAll) { - - responseData = await coinGeckoRequestAllItems.call( - this, - 'tickers', - 'GET', - `/coins/${coinId}/tickers`, - {}, - qs, - ); - } else { - const limit = this.getNodeParameter('limit', i) as number; - - responseData = await coinGeckoApiRequest.call( - this, - 'GET', - `/coins/${coinId}/tickers`, - {}, - qs, - ); - - responseData = responseData.tickers; - responseData = responseData.splice(0, limit); - } - } - - //https://www.coingecko.com/api/documentations/v3#/coins/get_coins__id__history - if (operation === 'history') { - - const coinId = this.getNodeParameter('coinId', i) as string; - const date = this.getNodeParameter('date', i) as string; - const options = this.getNodeParameter('options', i) as IDataObject; - - Object.assign(qs, options); - - qs.date = moment(date).format('DD-MM-YYYY'); - - responseData = await coinGeckoApiRequest.call( - this, - 'GET', - `/coins/${coinId}/history`, - {}, - qs, - ); - } - - //https://www.coingecko.com/api/documentations/v3#/coins/get_coins__id__market_chart - //https://www.coingecko.com/api/documentations/v3#/contract/get_coins__id__contract__contract_address__market_chart_ - if (operation === 'marketChart') { - - let respData; - - const searchBy = this.getNodeParameter('searchBy', i) as string; - const quoteCurrency = this.getNodeParameter('quoteCurrency', i) as string; - const days = this.getNodeParameter('days', i) as string; - - qs.vs_currency = quoteCurrency; - qs.days = days; - - if (searchBy === 'coinId') { - const coinId = this.getNodeParameter('baseCurrency', i) as string; - - respData = await coinGeckoApiRequest.call( - this, - 'GET', - `/coins/${coinId}/market_chart`, - {}, - qs, - ); - } - - if (searchBy === 'contractAddress') { - const platformId = this.getNodeParameter('platformId', i) as string; - const contractAddress = this.getNodeParameter('contractAddress', i) as string; - - respData = await coinGeckoApiRequest.call( - this, - 'GET', - `/coins/${platformId}/contract/${contractAddress}/market_chart`, - {}, - qs, - ); - } - - responseData = []; - for (let idx = 0; idx < respData.prices.length; idx++) { - const [time, price] = respData.prices[idx]; - const marketCaps = respData.market_caps[idx][1]; - const totalVolume = respData.total_volumes[idx][1]; - responseData.push({ time: moment(time).toISOString(), price, marketCaps, totalVolume } as IDataObject); - } - } - - //https://www.coingecko.com/api/documentations/v3#/coins/get_coins__id__ohlc - if (operation === 'candlestick') { - - const baseCurrency = this.getNodeParameter('baseCurrency', i) as string; - const quoteCurrency = this.getNodeParameter('quoteCurrency', i) as string; - const days = this.getNodeParameter('days', i) as string; - - qs.vs_currency = quoteCurrency; - qs.days = days; - - responseData = await coinGeckoApiRequest.call( - this, - 'GET', - `/coins/${baseCurrency}/ohlc`, - {}, - qs, - ); - - for (let idx = 0; idx < responseData.length; idx++) { - const [time, open, high, low, close] = responseData[idx]; - responseData[idx] = { time: moment(time).toISOString(), open, high, low, close } as IDataObject; - } - } - } - - if (resource === 'event') { - //https://www.coingecko.com/api/documentations/v3#/events/get_events - if (operation === 'getAll') { - - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - const options = this.getNodeParameter('options', i) as IDataObject; - - Object.assign(qs, options); - - if (returnAll) { - responseData = await coinGeckoRequestAllItems.call( - this, - 'data', - 'GET', - '/events', - {}, - qs, - ); - } else { - const limit = this.getNodeParameter('limit', i) as number; - - qs.per_page = limit; - - responseData = await coinGeckoApiRequest.call( - this, - 'GET', - '/events', - {}, - qs, - ); - responseData = responseData.data; - } - } - } - - if (resource === 'simple') { - //https://www.coingecko.com/api/documentations/v3#/simple/get_simple_price - if (operation === 'price') { - - const ids = this.getNodeParameter('ids', i) as string; - const currencies = this.getNodeParameter('currencies', i) as string[]; - const options = this.getNodeParameter('options', i) as IDataObject; - - qs.ids = ids, qs.vs_currencies = currencies.join(','); - Object.assign(qs, options); + Object.assign(qs, options); - responseData = await coinGeckoApiRequest.call( - this, - 'GET', - '/simple/price', - {}, - qs, - ); + responseData = await coinGeckoApiRequest.call( + this, + 'GET', + `/simple/token_price/${id}`, + {}, + qs, + ); + } } - //https://www.coingecko.com/api/documentations/v3#/simple/get_simple_token_price__id_ - if (operation === 'tokenPrice') { - - const id = this.getNodeParameter('id', i) as string; - const contractAddresses = this.getNodeParameter('contractAddresses', i) as string; - const currencies = this.getNodeParameter('currencies', i) as string[]; - const options = this.getNodeParameter('options', i) as IDataObject; - - qs.contract_addresses = contractAddresses; - qs.vs_currencies = currencies.join(','); - - Object.assign(qs, options); - - responseData = await coinGeckoApiRequest.call( - this, - 'GET', - `/simple/token_price/${id}`, - {}, - qs, - ); + if (Array.isArray(responseData)) { + returnData.push.apply(returnData, responseData as IDataObject[]); + } else if (responseData !== undefined) { + returnData.push(responseData as IDataObject); } - } - - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else if (responseData !== undefined) { - returnData.push(responseData as IDataObject); + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } } diff --git a/packages/nodes-base/nodes/Compression.node.ts b/packages/nodes-base/nodes/Compression.node.ts index 80ac7f0e6f..14cbdd5008 100644 --- a/packages/nodes-base/nodes/Compression.node.ts +++ b/packages/nodes-base/nodes/Compression.node.ts @@ -205,122 +205,131 @@ export class Compression implements INodeType { const operation = this.getNodeParameter('operation', 0) as string; for (let i = 0; i < length; i++) { + try { - if (operation === 'decompress') { - const binaryPropertyNames = (this.getNodeParameter('binaryPropertyName', 0) as string).split(',').map(key => key.trim()); + if (operation === 'decompress') { + const binaryPropertyNames = (this.getNodeParameter('binaryPropertyName', 0) as string).split(',').map(key => key.trim()); - const outputPrefix = this.getNodeParameter('outputPrefix', 0) as string; + const outputPrefix = this.getNodeParameter('outputPrefix', 0) as string; - const binaryObject: IBinaryKeyData = {}; + const binaryObject: IBinaryKeyData = {}; - let zipIndex = 0; + let zipIndex = 0; - for (const [index, binaryPropertyName] of binaryPropertyNames.entries()) { - if (items[i].binary === undefined) { - throw new NodeOperationError(this.getNode(), 'No binary data exists on item!'); - } - //@ts-ignore - if (items[i].binary[binaryPropertyName] === undefined) { - throw new NodeOperationError(this.getNode(), `No binary data property "${binaryPropertyName}" does not exists on item!`); - } - - const binaryData = (items[i].binary as IBinaryKeyData)[binaryPropertyName]; - - if (binaryData.fileExtension === 'zip') { - const files = await unzip(Buffer.from(binaryData.data as string, BINARY_ENCODING)); - - for (const key of Object.keys(files)) { - // when files are compresed using MACOSX for some reason they are duplicated under __MACOSX - if (key.includes('__MACOSX')) { - continue; - } - - const data = await this.helpers.prepareBinaryData(Buffer.from(files[key].buffer), key); - - binaryObject[`${outputPrefix}${zipIndex++}`] = data; + for (const [index, binaryPropertyName] of binaryPropertyNames.entries()) { + if (items[i].binary === undefined) { + throw new NodeOperationError(this.getNode(), 'No binary data exists on item!'); + } + //@ts-ignore + if (items[i].binary[binaryPropertyName] === undefined) { + throw new NodeOperationError(this.getNode(), `No binary data property "${binaryPropertyName}" does not exists on item!`); } - } else if (binaryData.fileExtension === 'gz') { - const file = await gunzip(Buffer.from(binaryData.data as string, BINARY_ENCODING)); - const fileName = binaryData.fileName?.split('.')[0]; + const binaryData = (items[i].binary as IBinaryKeyData)[binaryPropertyName]; - const propertyName = `${outputPrefix}${index}`; + if (binaryData.fileExtension === 'zip') { + const files = await unzip(Buffer.from(binaryData.data as string, BINARY_ENCODING)); - binaryObject[propertyName] = await this.helpers.prepareBinaryData(Buffer.from(file.buffer), fileName); - const fileExtension = mime.extension(binaryObject[propertyName].mimeType) as string; - binaryObject[propertyName].fileName = `${fileName}.${fileExtension}`; - binaryObject[propertyName].fileExtension = fileExtension; - } - } + for (const key of Object.keys(files)) { + // when files are compresed using MACOSX for some reason they are duplicated under __MACOSX + if (key.includes('__MACOSX')) { + continue; + } - returnData.push({ - json: items[i].json, - binary: binaryObject, - }); - } + const data = await this.helpers.prepareBinaryData(Buffer.from(files[key].buffer), key); - if (operation === 'compress') { - const binaryPropertyNames = (this.getNodeParameter('binaryPropertyName', 0) as string).split(',').map(key => key.trim()); + binaryObject[`${outputPrefix}${zipIndex++}`] = data; + } + } else if (binaryData.fileExtension === 'gz') { + const file = await gunzip(Buffer.from(binaryData.data as string, BINARY_ENCODING)); - const outputFormat = this.getNodeParameter('outputFormat', 0) as string; + const fileName = binaryData.fileName?.split('.')[0]; - const zipData: fflate.Zippable = {}; + const propertyName = `${outputPrefix}${index}`; - const binaryObject: IBinaryKeyData = {}; - - for (const [index, binaryPropertyName] of binaryPropertyNames.entries()) { - - if (items[i].binary === undefined) { - throw new NodeOperationError(this.getNode(), 'No binary data exists on item!'); - } - //@ts-ignore - if (items[i].binary[binaryPropertyName] === undefined) { - throw new NodeOperationError(this.getNode(), `No binary data property "${binaryPropertyName}" does not exists on item!`); + binaryObject[propertyName] = await this.helpers.prepareBinaryData(Buffer.from(file.buffer), fileName); + const fileExtension = mime.extension(binaryObject[propertyName].mimeType) as string; + binaryObject[propertyName].fileName = `${fileName}.${fileExtension}`; + binaryObject[propertyName].fileExtension = fileExtension; + } } - const binaryData = (items[i].binary as IBinaryKeyData)[binaryPropertyName]; - - if (outputFormat === 'zip') { - zipData[binaryData.fileName as string] = [ - Buffer.from(binaryData.data, BINARY_ENCODING), { - level: ALREADY_COMPRESSED.includes(binaryData.fileExtension as string) ? 0 : 6, - }, - ]; - - } else if (outputFormat === 'gzip') { - const outputPrefix = this.getNodeParameter('outputPrefix', 0) as string; - - const data = await gzip(Buffer.from(binaryData.data, BINARY_ENCODING)) as Uint8Array; - - const fileName = binaryData.fileName?.split('.')[0]; - - binaryObject[`${outputPrefix}${index}`] = await this.helpers.prepareBinaryData(Buffer.from(data), `${fileName}.gzip`); - } - } - - if (outputFormat === 'zip') { - const fileName = this.getNodeParameter('fileName', 0) as string; - - const binaryPropertyOutput = this.getNodeParameter('binaryPropertyOutput', 0) as string; - - const buffer = await zip(zipData); - - const data = await this.helpers.prepareBinaryData(Buffer.from(buffer), fileName); - - returnData.push({ - json: items[i].json, - binary: { - [binaryPropertyOutput]: data, - }, - }); - } - - if (outputFormat === 'gzip') { returnData.push({ json: items[i].json, binary: binaryObject, }); } + + if (operation === 'compress') { + const binaryPropertyNames = (this.getNodeParameter('binaryPropertyName', 0) as string).split(',').map(key => key.trim()); + + const outputFormat = this.getNodeParameter('outputFormat', 0) as string; + + const zipData: fflate.Zippable = {}; + + const binaryObject: IBinaryKeyData = {}; + + for (const [index, binaryPropertyName] of binaryPropertyNames.entries()) { + + if (items[i].binary === undefined) { + throw new NodeOperationError(this.getNode(), 'No binary data exists on item!'); + } + //@ts-ignore + if (items[i].binary[binaryPropertyName] === undefined) { + throw new NodeOperationError(this.getNode(), `No binary data property "${binaryPropertyName}" does not exists on item!`); + } + + const binaryData = (items[i].binary as IBinaryKeyData)[binaryPropertyName]; + + if (outputFormat === 'zip') { + zipData[binaryData.fileName as string] = [ + Buffer.from(binaryData.data, BINARY_ENCODING), { + level: ALREADY_COMPRESSED.includes(binaryData.fileExtension as string) ? 0 : 6, + }, + ]; + + } else if (outputFormat === 'gzip') { + const outputPrefix = this.getNodeParameter('outputPrefix', 0) as string; + + const data = await gzip(Buffer.from(binaryData.data, BINARY_ENCODING)) as Uint8Array; + + const fileName = binaryData.fileName?.split('.')[0]; + + binaryObject[`${outputPrefix}${index}`] = await this.helpers.prepareBinaryData(Buffer.from(data), `${fileName}.gzip`); + } + } + + if (outputFormat === 'zip') { + const fileName = this.getNodeParameter('fileName', 0) as string; + + const binaryPropertyOutput = this.getNodeParameter('binaryPropertyOutput', 0) as string; + + const buffer = await zip(zipData); + + const data = await this.helpers.prepareBinaryData(Buffer.from(buffer), fileName); + + returnData.push({ + json: items[i].json, + binary: { + [binaryPropertyOutput]: data, + }, + }); + } + + if (outputFormat === 'gzip') { + returnData.push({ + json: items[i].json, + binary: binaryObject, + }); + } + } + + } catch (error) { + if (this.continueOnFail()) { + returnData.push({json:{ error: error.message }}); + continue; + } + throw error; } } diff --git a/packages/nodes-base/nodes/Contentful/Contentful.node.ts b/packages/nodes-base/nodes/Contentful/Contentful.node.ts index 0097ee1805..d5b2ff70dc 100644 --- a/packages/nodes-base/nodes/Contentful/Contentful.node.ts +++ b/packages/nodes-base/nodes/Contentful/Contentful.node.ts @@ -101,224 +101,232 @@ export class Contentful implements INodeType { const qs: Record = {}; for (let i = 0; i < items.length; i++) { - if (resource === 'space') { - if (operation === 'get') { + try { + if (resource === 'space') { + if (operation === 'get') { - const credentials = this.getCredentials('contentfulApi'); + const credentials = this.getCredentials('contentfulApi'); - responseData = await contentfulApiRequest.call(this, 'GET', `/spaces/${credentials?.spaceId}`); - } - } - if (resource === 'contentType') { - if (operation === 'get') { - - const credentials = this.getCredentials('contentfulApi'); - - const env = this.getNodeParameter('environmentId', 0) as string; - - const id = this.getNodeParameter('contentTypeId', 0) as string; - - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - - responseData = await contentfulApiRequest.call(this, 'GET', `/spaces/${credentials?.spaceId}/environments/${env}/content_types/${id}`); - - if (!additionalFields.rawData) { - responseData = responseData.fields; + responseData = await contentfulApiRequest.call(this, 'GET', `/spaces/${credentials?.spaceId}`); } } - } - if (resource === 'entry') { + if (resource === 'contentType') { + if (operation === 'get') { - if (operation === 'get') { + const credentials = this.getCredentials('contentfulApi'); - const credentials = this.getCredentials('contentfulApi'); + const env = this.getNodeParameter('environmentId', 0) as string; - const env = this.getNodeParameter('environmentId', 0) as string; + const id = this.getNodeParameter('contentTypeId', 0) as string; - const id = this.getNodeParameter('entryId', 0) as string; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + responseData = await contentfulApiRequest.call(this, 'GET', `/spaces/${credentials?.spaceId}/environments/${env}/content_types/${id}`); - responseData = await contentfulApiRequest.call(this, 'GET', `/spaces/${credentials?.spaceId}/environments/${env}/entries/${id}`, {}, qs); - - if (!additionalFields.rawData) { - responseData = responseData.fields; - } - - } else if (operation === 'getAll') { - const credentials = this.getCredentials('contentfulApi'); - - const returnAll = this.getNodeParameter('returnAll', 0) as boolean; - - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const rawData = additionalFields.rawData; - additionalFields.rawData = undefined; - - const env = this.getNodeParameter('environmentId', i) as string; - - Object.assign(qs, additionalFields); - - if (qs.equal) { - const [atribute, value] = (qs.equal as string).split('='); - qs[atribute] = value; - delete qs.equal; - } - - if (qs.notEqual) { - const [atribute, value] = (qs.notEqual as string).split('='); - qs[atribute] = value; - delete qs.notEqual; - } - - if (qs.include) { - const [atribute, value] = (qs.include as string).split('='); - qs[atribute] = value; - delete qs.include; - } - - if (qs.exclude) { - const [atribute, value] = (qs.exclude as string).split('='); - qs[atribute] = value; - delete qs.exclude; - } - - if (returnAll) { - responseData = await contenfulApiRequestAllItems.call(this, 'items', 'GET', `/spaces/${credentials?.spaceId}/environments/${env}/entries`, {}, qs); - - if (!rawData) { - const assets : IDataObject[] = []; - // tslint:disable-next-line: no-any - responseData.map((asset : any) => { - assets.push(asset.fields); - }); - responseData = assets; - } - } else { - const limit = this.getNodeParameter('limit', 0) as number; - qs.limit = limit; - responseData = await contentfulApiRequest.call(this, 'GET', `/spaces/${credentials?.spaceId}/environments/${env}/entries`, {}, qs); - responseData = responseData.items; - - if (!rawData) { - const assets : IDataObject[] = []; - // tslint:disable-next-line: no-any - responseData.map((asset : any) => { - assets.push(asset.fields); - }); - responseData = assets; + if (!additionalFields.rawData) { + responseData = responseData.fields; } } } - } - if (resource === 'asset') { - if (operation === 'get') { + if (resource === 'entry') { - const credentials = this.getCredentials('contentfulApi'); + if (operation === 'get') { - const env = this.getNodeParameter('environmentId', 0) as string; + const credentials = this.getCredentials('contentfulApi'); - const id = this.getNodeParameter('assetId', 0) as string; + const env = this.getNodeParameter('environmentId', 0) as string; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const id = this.getNodeParameter('entryId', 0) as string; - responseData = await contentfulApiRequest.call(this, 'GET', `/spaces/${credentials?.spaceId}/environments/${env}/assets/${id}`, {}, qs); + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - if (!additionalFields.rawData) { - responseData = responseData.fields; - } + responseData = await contentfulApiRequest.call(this, 'GET', `/spaces/${credentials?.spaceId}/environments/${env}/entries/${id}`, {}, qs); - } else if (operation === 'getAll') { - - const credentials = this.getCredentials('contentfulApi'); - - const returnAll = this.getNodeParameter('returnAll', 0) as boolean; - - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const rawData = additionalFields.rawData; - additionalFields.rawData = undefined; - - const env = this.getNodeParameter('environmentId', i) as string; - - Object.assign(qs, additionalFields); - - if (qs.equal) { - const [atribute, value] = (qs.equal as string).split('='); - qs[atribute] = value; - delete qs.equal; - } - - if (qs.notEqual) { - const [atribute, value] = (qs.notEqual as string).split('='); - qs[atribute] = value; - delete qs.notEqual; - } - - if (qs.include) { - const [atribute, value] = (qs.include as string).split('='); - qs[atribute] = value; - delete qs.include; - } - - if (qs.exclude) { - const [atribute, value] = (qs.exclude as string).split('='); - qs[atribute] = value; - delete qs.exclude; - } - - if (returnAll) { - responseData = await contenfulApiRequestAllItems.call(this, 'items', 'GET', `/spaces/${credentials?.spaceId}/environments/${env}/assets`, {}, qs); - - if (!rawData) { - const assets : IDataObject[] = []; - // tslint:disable-next-line: no-any - responseData.map((asset : any) => { - assets.push(asset.fields); - }); - responseData = assets; + if (!additionalFields.rawData) { + responseData = responseData.fields; } - } else { - const limit = this.getNodeParameter('limit', i) as number; - qs.limit = limit; - responseData = await contentfulApiRequest.call(this, 'GET', `/spaces/${credentials?.spaceId}/environments/${env}/assets`, {}, qs); - responseData = responseData.items; - if (!rawData) { - const assets : IDataObject[] = []; - // tslint:disable-next-line: no-any - responseData.map((asset : any) => { - assets.push(asset.fields); - }); - responseData = assets; + } else if (operation === 'getAll') { + const credentials = this.getCredentials('contentfulApi'); + + const returnAll = this.getNodeParameter('returnAll', 0) as boolean; + + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const rawData = additionalFields.rawData; + additionalFields.rawData = undefined; + + const env = this.getNodeParameter('environmentId', i) as string; + + Object.assign(qs, additionalFields); + + if (qs.equal) { + const [atribute, value] = (qs.equal as string).split('='); + qs[atribute] = value; + delete qs.equal; + } + + if (qs.notEqual) { + const [atribute, value] = (qs.notEqual as string).split('='); + qs[atribute] = value; + delete qs.notEqual; + } + + if (qs.include) { + const [atribute, value] = (qs.include as string).split('='); + qs[atribute] = value; + delete qs.include; + } + + if (qs.exclude) { + const [atribute, value] = (qs.exclude as string).split('='); + qs[atribute] = value; + delete qs.exclude; + } + + if (returnAll) { + responseData = await contenfulApiRequestAllItems.call(this, 'items', 'GET', `/spaces/${credentials?.spaceId}/environments/${env}/entries`, {}, qs); + + if (!rawData) { + const assets : IDataObject[] = []; + // tslint:disable-next-line: no-any + responseData.map((asset : any) => { + assets.push(asset.fields); + }); + responseData = assets; + } + } else { + const limit = this.getNodeParameter('limit', 0) as number; + qs.limit = limit; + responseData = await contentfulApiRequest.call(this, 'GET', `/spaces/${credentials?.spaceId}/environments/${env}/entries`, {}, qs); + responseData = responseData.items; + + if (!rawData) { + const assets : IDataObject[] = []; + // tslint:disable-next-line: no-any + responseData.map((asset : any) => { + assets.push(asset.fields); + }); + responseData = assets; + } } } } - } - if (resource === 'locale') { + if (resource === 'asset') { + if (operation === 'get') { - if (operation === 'getAll') { + const credentials = this.getCredentials('contentfulApi'); - const credentials = this.getCredentials('contentfulApi'); + const env = this.getNodeParameter('environmentId', 0) as string; - const returnAll = this.getNodeParameter('returnAll', 0) as boolean; + const id = this.getNodeParameter('assetId', 0) as string; - const env = this.getNodeParameter('environmentId', i) as string; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - if (returnAll) { - responseData = await contenfulApiRequestAllItems.call(this, 'items', 'GET', `/spaces/${credentials?.spaceId}/environments/${env}/locales`, {}, qs); + responseData = await contentfulApiRequest.call(this, 'GET', `/spaces/${credentials?.spaceId}/environments/${env}/assets/${id}`, {}, qs); - } else { - const limit = this.getNodeParameter('limit', 0) as number; - qs.limit = limit; - responseData = await contentfulApiRequest.call(this, 'GET', `/spaces/${credentials?.spaceId}/environments/${env}/locales`, {}, qs); - responseData = responseData.items; + if (!additionalFields.rawData) { + responseData = responseData.fields; + } + } else if (operation === 'getAll') { + + const credentials = this.getCredentials('contentfulApi'); + + const returnAll = this.getNodeParameter('returnAll', 0) as boolean; + + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const rawData = additionalFields.rawData; + additionalFields.rawData = undefined; + + const env = this.getNodeParameter('environmentId', i) as string; + + Object.assign(qs, additionalFields); + + if (qs.equal) { + const [atribute, value] = (qs.equal as string).split('='); + qs[atribute] = value; + delete qs.equal; + } + + if (qs.notEqual) { + const [atribute, value] = (qs.notEqual as string).split('='); + qs[atribute] = value; + delete qs.notEqual; + } + + if (qs.include) { + const [atribute, value] = (qs.include as string).split('='); + qs[atribute] = value; + delete qs.include; + } + + if (qs.exclude) { + const [atribute, value] = (qs.exclude as string).split('='); + qs[atribute] = value; + delete qs.exclude; + } + + if (returnAll) { + responseData = await contenfulApiRequestAllItems.call(this, 'items', 'GET', `/spaces/${credentials?.spaceId}/environments/${env}/assets`, {}, qs); + + if (!rawData) { + const assets : IDataObject[] = []; + // tslint:disable-next-line: no-any + responseData.map((asset : any) => { + assets.push(asset.fields); + }); + responseData = assets; + } + } else { + const limit = this.getNodeParameter('limit', i) as number; + qs.limit = limit; + responseData = await contentfulApiRequest.call(this, 'GET', `/spaces/${credentials?.spaceId}/environments/${env}/assets`, {}, qs); + responseData = responseData.items; + + if (!rawData) { + const assets : IDataObject[] = []; + // tslint:disable-next-line: no-any + responseData.map((asset : any) => { + assets.push(asset.fields); + }); + responseData = assets; + } + } } } - } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else { - returnData.push(responseData as IDataObject); + if (resource === 'locale') { + + if (operation === 'getAll') { + + const credentials = this.getCredentials('contentfulApi'); + + const returnAll = this.getNodeParameter('returnAll', 0) as boolean; + + const env = this.getNodeParameter('environmentId', i) as string; + + if (returnAll) { + responseData = await contenfulApiRequestAllItems.call(this, 'items', 'GET', `/spaces/${credentials?.spaceId}/environments/${env}/locales`, {}, qs); + + } else { + const limit = this.getNodeParameter('limit', 0) as number; + qs.limit = limit; + responseData = await contentfulApiRequest.call(this, 'GET', `/spaces/${credentials?.spaceId}/environments/${env}/locales`, {}, qs); + responseData = responseData.items; + + } + } + } + if (Array.isArray(responseData)) { + returnData.push.apply(returnData, responseData as IDataObject[]); + } else { + returnData.push(responseData as IDataObject); + } + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } } return [this.helpers.returnJsonArray(returnData)]; diff --git a/packages/nodes-base/nodes/ConvertKit/ConvertKit.node.ts b/packages/nodes-base/nodes/ConvertKit/ConvertKit.node.ts index 2d7ed96c52..72ba8b7b66 100644 --- a/packages/nodes-base/nodes/ConvertKit/ConvertKit.node.ts +++ b/packages/nodes-base/nodes/ConvertKit/ConvertKit.node.ts @@ -185,299 +185,309 @@ export class ConvertKit implements INodeType { for (let i = 0; i < items.length; i++) { - if (resource === 'customField') { - if (operation === 'create') { + try { - const label = this.getNodeParameter('label', i) as string; + if (resource === 'customField') { + if (operation === 'create') { - responseData = await convertKitApiRequest.call(this, 'POST', '/custom_fields', { label }, qs); - } - if (operation === 'delete') { + const label = this.getNodeParameter('label', i) as string; - const id = this.getNodeParameter('id', i) as string; + responseData = await convertKitApiRequest.call(this, 'POST', '/custom_fields', { label }, qs); + } + if (operation === 'delete') { - responseData = await convertKitApiRequest.call(this, 'DELETE', `/custom_fields/${id}`); - } - if (operation === 'get') { + const id = this.getNodeParameter('id', i) as string; - const id = this.getNodeParameter('id', i) as string; + responseData = await convertKitApiRequest.call(this, 'DELETE', `/custom_fields/${id}`); + } + if (operation === 'get') { - responseData = await convertKitApiRequest.call(this, 'GET', `/custom_fields/${id}`); - } - if (operation === 'getAll') { + const id = this.getNodeParameter('id', i) as string; - const returnAll = this.getNodeParameter('returnAll', i) as boolean; + responseData = await convertKitApiRequest.call(this, 'GET', `/custom_fields/${id}`); + } + if (operation === 'getAll') { - responseData = await convertKitApiRequest.call(this, 'GET', `/custom_fields`); + const returnAll = this.getNodeParameter('returnAll', i) as boolean; - responseData = responseData.custom_fields; + responseData = await convertKitApiRequest.call(this, 'GET', `/custom_fields`); - if (!returnAll) { + responseData = responseData.custom_fields; - const limit = this.getNodeParameter('limit', i) as number; + if (!returnAll) { - responseData = responseData.slice(0, limit); + const limit = this.getNodeParameter('limit', i) as number; + + responseData = responseData.slice(0, limit); + } + } + if (operation === 'update') { + + const id = this.getNodeParameter('id', i) as string; + + const label = this.getNodeParameter('label', i) as string; + + responseData = await convertKitApiRequest.call(this, 'PUT', `/custom_fields/${id}`, { label }); + + responseData = { success: true }; } } - if (operation === 'update') { - const id = this.getNodeParameter('id', i) as string; + if (resource === 'form') { + if (operation === 'addSubscriber') { - const label = this.getNodeParameter('label', i) as string; + const email = this.getNodeParameter('email', i) as string; - responseData = await convertKitApiRequest.call(this, 'PUT', `/custom_fields/${id}`, { label }); + const formId = this.getNodeParameter('id', i) as string; - responseData = { success: true }; - } - } + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - if (resource === 'form') { - if (operation === 'addSubscriber') { + const body: IDataObject = { + email, + }; - const email = this.getNodeParameter('email', i) as string; + if (additionalFields.firstName) { + body.first_name = additionalFields.firstName as string; + } - const formId = this.getNodeParameter('id', i) as string; + if (additionalFields.tags) { + body.tags = additionalFields.tags as string[]; + } - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - - const body: IDataObject = { - email, - }; - - if (additionalFields.firstName) { - body.first_name = additionalFields.firstName as string; - } - - if (additionalFields.tags) { - body.tags = additionalFields.tags as string[]; - } - - if (additionalFields.fieldsUi) { - const fieldValues = (additionalFields.fieldsUi as IDataObject).fieldsValues as IDataObject[]; - if (fieldValues) { - body.fields = {}; - for (const fieldValue of fieldValues) { - //@ts-ignore - body.fields[fieldValue.key] = fieldValue.value; + if (additionalFields.fieldsUi) { + const fieldValues = (additionalFields.fieldsUi as IDataObject).fieldsValues as IDataObject[]; + if (fieldValues) { + body.fields = {}; + for (const fieldValue of fieldValues) { + //@ts-ignore + body.fields[fieldValue.key] = fieldValue.value; + } } } + + const { subscription } = await convertKitApiRequest.call(this, 'POST', `/forms/${formId}/subscribe`, body); + + responseData = subscription; + } + if (operation === 'getAll') { + + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + + responseData = await convertKitApiRequest.call(this, 'GET', `/forms`); + + responseData = responseData.forms; + + if (!returnAll) { + + const limit = this.getNodeParameter('limit', i) as number; + + responseData = responseData.slice(0, limit); + } + } + if (operation === 'getSubscriptions') { + + const formId = this.getNodeParameter('id', i) as string; + + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + + if (additionalFields.subscriberState) { + qs.subscriber_state = additionalFields.subscriberState as string; + } + + responseData = await convertKitApiRequest.call(this, 'GET', `/forms/${formId}/subscriptions`, {}, qs); + + responseData = responseData.subscriptions; + + if (!returnAll) { + + const limit = this.getNodeParameter('limit', i) as number; + + responseData = responseData.slice(0, limit); + } + } + } + + if (resource === 'sequence') { + if (operation === 'addSubscriber') { + + const email = this.getNodeParameter('email', i) as string; + + const sequenceId = this.getNodeParameter('id', i) as string; + + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + + const body: IDataObject = { + email, + }; + + if (additionalFields.firstName) { + body.first_name = additionalFields.firstName as string; + } + + if (additionalFields.tags) { + body.tags = additionalFields.tags as string[]; + } + + if (additionalFields.fieldsUi) { + const fieldValues = (additionalFields.fieldsUi as IDataObject).fieldsValues as IDataObject[]; + if (fieldValues) { + body.fields = {}; + for (const fieldValue of fieldValues) { + //@ts-ignore + body.fields[fieldValue.key] = fieldValue.value; + } + } + } + + const { subscription } = await convertKitApiRequest.call(this, 'POST', `/sequences/${sequenceId}/subscribe`, body); + + responseData = subscription; + } + if (operation === 'getAll') { + + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + + responseData = await convertKitApiRequest.call(this, 'GET', `/sequences`); + + responseData = responseData.courses; + + if (!returnAll) { + + const limit = this.getNodeParameter('limit', i) as number; + + responseData = responseData.slice(0, limit); + } + } + if (operation === 'getSubscriptions') { + + const sequenceId = this.getNodeParameter('id', i) as string; + + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + + if (additionalFields.subscriberState) { + qs.subscriber_state = additionalFields.subscriberState as string; + } + + responseData = await convertKitApiRequest.call(this, 'GET', `/sequences/${sequenceId}/subscriptions`, {}, qs); + + responseData = responseData.subscriptions; + + if (!returnAll) { + + const limit = this.getNodeParameter('limit', i) as number; + + responseData = responseData.slice(0, limit); + } + } + } + + if (resource === 'tag') { + if (operation === 'create') { + + const names = ((this.getNodeParameter('name', i) as string).split(',') as string[]).map((e) => ({ name: e })); + + const body: IDataObject = { + tag: names, + }; + + responseData = await convertKitApiRequest.call(this, 'POST', '/tags', body); + } + + if (operation === 'getAll') { + + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + + responseData = await convertKitApiRequest.call(this, 'GET', `/tags`); + + responseData = responseData.tags; + + if (!returnAll) { + + const limit = this.getNodeParameter('limit', i) as number; + + responseData = responseData.slice(0, limit); + } + } + } + + if (resource === 'tagSubscriber') { + + if (operation === 'add') { + + const tagId = this.getNodeParameter('tagId', i) as string; + + const email = this.getNodeParameter('email', i) as string; + + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + + const body: IDataObject = { + email, + }; + + if (additionalFields.firstName) { + body.first_name = additionalFields.firstName as string; + } + + if (additionalFields.fieldsUi) { + const fieldValues = (additionalFields.fieldsUi as IDataObject).fieldsValues as IDataObject[]; + if (fieldValues) { + body.fields = {}; + for (const fieldValue of fieldValues) { + //@ts-ignore + body.fields[fieldValue.key] = fieldValue.value; + } + } + } + + const { subscription } = await convertKitApiRequest.call(this, 'POST', `/tags/${tagId}/subscribe`, body); + + responseData = subscription; + } + + if (operation === 'getAll') { + + const tagId = this.getNodeParameter('tagId', i) as string; + + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + + responseData = await convertKitApiRequest.call(this, 'GET', `/tags/${tagId}/subscriptions`); + + responseData = responseData.subscriptions; + + if (!returnAll) { + + const limit = this.getNodeParameter('limit', i) as number; + + responseData = responseData.slice(0, limit); + } } - const { subscription } = await convertKitApiRequest.call(this, 'POST', `/forms/${formId}/subscribe`, body); + if (operation === 'delete') { - responseData = subscription; - } - if (operation === 'getAll') { + const tagId = this.getNodeParameter('tagId', i) as string; - const returnAll = this.getNodeParameter('returnAll', i) as boolean; + const email = this.getNodeParameter('email', i) as string; - responseData = await convertKitApiRequest.call(this, 'GET', `/forms`); - - responseData = responseData.forms; - - if (!returnAll) { - - const limit = this.getNodeParameter('limit', i) as number; - - responseData = responseData.slice(0, limit); - } - } - if (operation === 'getSubscriptions') { - - const formId = this.getNodeParameter('id', i) as string; - - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - - if (additionalFields.subscriberState) { - qs.subscriber_state = additionalFields.subscriberState as string; - } - - responseData = await convertKitApiRequest.call(this, 'GET', `/forms/${formId}/subscriptions`, {}, qs); - - responseData = responseData.subscriptions; - - if (!returnAll) { - - const limit = this.getNodeParameter('limit', i) as number; - - responseData = responseData.slice(0, limit); - } - } - } - - if (resource === 'sequence') { - if (operation === 'addSubscriber') { - - const email = this.getNodeParameter('email', i) as string; - - const sequenceId = this.getNodeParameter('id', i) as string; - - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - - const body: IDataObject = { - email, - }; - - if (additionalFields.firstName) { - body.first_name = additionalFields.firstName as string; - } - - if (additionalFields.tags) { - body.tags = additionalFields.tags as string[]; - } - - if (additionalFields.fieldsUi) { - const fieldValues = (additionalFields.fieldsUi as IDataObject).fieldsValues as IDataObject[]; - if (fieldValues) { - body.fields = {}; - for (const fieldValue of fieldValues) { - //@ts-ignore - body.fields[fieldValue.key] = fieldValue.value; - } - } - } - - const { subscription } = await convertKitApiRequest.call(this, 'POST', `/sequences/${sequenceId}/subscribe`, body); - - responseData = subscription; - } - if (operation === 'getAll') { - - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - - responseData = await convertKitApiRequest.call(this, 'GET', `/sequences`); - - responseData = responseData.courses; - - if (!returnAll) { - - const limit = this.getNodeParameter('limit', i) as number; - - responseData = responseData.slice(0, limit); - } - } - if (operation === 'getSubscriptions') { - - const sequenceId = this.getNodeParameter('id', i) as string; - - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - - if (additionalFields.subscriberState) { - qs.subscriber_state = additionalFields.subscriberState as string; - } - - responseData = await convertKitApiRequest.call(this, 'GET', `/sequences/${sequenceId}/subscriptions`, {}, qs); - - responseData = responseData.subscriptions; - - if (!returnAll) { - - const limit = this.getNodeParameter('limit', i) as number; - - responseData = responseData.slice(0, limit); - } - } - } - - if (resource === 'tag') { - if (operation === 'create') { - - const names = ((this.getNodeParameter('name', i) as string).split(',') as string[]).map((e) => ({ name: e })); - - const body: IDataObject = { - tag: names, - }; - - responseData = await convertKitApiRequest.call(this, 'POST', '/tags', body); - } - - if (operation === 'getAll') { - - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - - responseData = await convertKitApiRequest.call(this, 'GET', `/tags`); - - responseData = responseData.tags; - - if (!returnAll) { - - const limit = this.getNodeParameter('limit', i) as number; - - responseData = responseData.slice(0, limit); - } - } - } - - if (resource === 'tagSubscriber') { - - if (operation === 'add') { - - const tagId = this.getNodeParameter('tagId', i) as string; - - const email = this.getNodeParameter('email', i) as string; - - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - - const body: IDataObject = { - email, - }; - - if (additionalFields.firstName) { - body.first_name = additionalFields.firstName as string; - } - - if (additionalFields.fieldsUi) { - const fieldValues = (additionalFields.fieldsUi as IDataObject).fieldsValues as IDataObject[]; - if (fieldValues) { - body.fields = {}; - for (const fieldValue of fieldValues) { - //@ts-ignore - body.fields[fieldValue.key] = fieldValue.value; - } - } - } - - const { subscription } = await convertKitApiRequest.call(this, 'POST', `/tags/${tagId}/subscribe`, body); - - responseData = subscription; - } - - if (operation === 'getAll') { - - const tagId = this.getNodeParameter('tagId', i) as string; - - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - - responseData = await convertKitApiRequest.call(this, 'GET', `/tags/${tagId}/subscriptions`); - - responseData = responseData.subscriptions; - - if (!returnAll) { - - const limit = this.getNodeParameter('limit', i) as number; - - responseData = responseData.slice(0, limit); + responseData = await convertKitApiRequest.call(this, 'POST', `/tags/${tagId}>/unsubscribe`, { email }); } } - if (operation === 'delete') { - - const tagId = this.getNodeParameter('tagId', i) as string; - - const email = this.getNodeParameter('email', i) as string; - - responseData = await convertKitApiRequest.call(this, 'POST', `/tags/${tagId}>/unsubscribe`, { email }); + if (Array.isArray(responseData)) { + returnData.push.apply(returnData, responseData as IDataObject[]); + } else if (responseData !== undefined) { + returnData.push(responseData as IDataObject); } - } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else if (responseData !== undefined) { - returnData.push(responseData as IDataObject); + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } } diff --git a/packages/nodes-base/nodes/Cortex/Cortex.node.ts b/packages/nodes-base/nodes/Cortex/Cortex.node.ts index d2b934fcdc..e4a8ba6a09 100644 --- a/packages/nodes-base/nodes/Cortex/Cortex.node.ts +++ b/packages/nodes-base/nodes/Cortex/Cortex.node.ts @@ -204,264 +204,274 @@ export class Cortex implements INodeType { const operation = this.getNodeParameter('operation', 0) as string; for (let i = 0; i < length; i++) { - if (resource === 'analyzer') { - //https://github.com/TheHive-Project/CortexDocs/blob/master/api/api-guide.md#run - if (operation === 'execute') { + try { - let force = false; + if (resource === 'analyzer') { + //https://github.com/TheHive-Project/CortexDocs/blob/master/api/api-guide.md#run + if (operation === 'execute') { - const analyzer = this.getNodeParameter('analyzer', i) as string; + let force = false; - const observableType = this.getNodeParameter('observableType', i) as string; + const analyzer = this.getNodeParameter('analyzer', i) as string; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const observableType = this.getNodeParameter('observableType', i) as string; - const tlp = this.getNodeParameter('tlp', i) as string; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const body: IDataObject = { - dataType: observableType, - tlp, - }; + const tlp = this.getNodeParameter('tlp', i) as string; - if (additionalFields.force === true) { - force = true; - } - - if (observableType === 'file') { - - const item = items[i]; - - if (item.binary === undefined) { - throw new NodeOperationError(this.getNode(), 'No binary data exists on item!'); - } - - const binaryPropertyName = this.getNodeParameter('binaryPropertyName', i) as string; - - if (item.binary[binaryPropertyName] === undefined) { - throw new NodeOperationError(this.getNode(), `No binary data property "${binaryPropertyName}" does not exists on item!`); - } - - const fileBufferData = Buffer.from(item.binary[binaryPropertyName].data, BINARY_ENCODING); - - const options = { - formData: { - data: { - value: fileBufferData, - options: { - contentType: item.binary[binaryPropertyName].mimeType, - filename: item.binary[binaryPropertyName].fileName, - }, - }, - _json: JSON.stringify({ - dataType: observableType, - tlp, - }), - }, + const body: IDataObject = { + dataType: observableType, + tlp, }; - responseData = await cortexApiRequest.call( - this, - 'POST', - `/analyzer/${analyzer.split('::')[0]}/run`, - {}, - { force }, - '', - options, - ) as IJob; + if (additionalFields.force === true) { + force = true; + } - continue; + if (observableType === 'file') { - } else { - const observableValue = this.getNodeParameter('observableValue', i) as string; + const item = items[i]; - body.data = observableValue; + if (item.binary === undefined) { + throw new NodeOperationError(this.getNode(), 'No binary data exists on item!'); + } - responseData = await cortexApiRequest.call( - this, - 'POST', - `/analyzer/${analyzer.split('::')[0]}/run`, - body, - { force }, - ) as IJob; + const binaryPropertyName = this.getNodeParameter('binaryPropertyName', i) as string; + + if (item.binary[binaryPropertyName] === undefined) { + throw new NodeOperationError(this.getNode(), `No binary data property "${binaryPropertyName}" does not exists on item!`); + } + + const fileBufferData = Buffer.from(item.binary[binaryPropertyName].data, BINARY_ENCODING); + + const options = { + formData: { + data: { + value: fileBufferData, + options: { + contentType: item.binary[binaryPropertyName].mimeType, + filename: item.binary[binaryPropertyName].fileName, + }, + }, + _json: JSON.stringify({ + dataType: observableType, + tlp, + }), + }, + }; + + responseData = await cortexApiRequest.call( + this, + 'POST', + `/analyzer/${analyzer.split('::')[0]}/run`, + {}, + { force }, + '', + options, + ) as IJob; + + continue; + + } else { + const observableValue = this.getNodeParameter('observableValue', i) as string; + + body.data = observableValue; + + responseData = await cortexApiRequest.call( + this, + 'POST', + `/analyzer/${analyzer.split('::')[0]}/run`, + body, + { force }, + ) as IJob; + } + + if (additionalFields.timeout) { + responseData = await cortexApiRequest.call( + this, + 'GET', + `/job/${responseData.id}/waitreport`, + {}, + { atMost: `${additionalFields.timeout}second` }, + ); + } } + } + + if (resource === 'job') { + //https://github.com/TheHive-Project/CortexDocs/blob/master/api/api-guide.md#get-details-1 + if (operation === 'get') { + + const jobId = this.getNodeParameter('jobId', i) as string; - if (additionalFields.timeout) { responseData = await cortexApiRequest.call( this, 'GET', - `/job/${responseData.id}/waitreport`, - {}, - { atMost: `${additionalFields.timeout}second` }, + `/job/${jobId}`, + ); + } + //https://github.com/TheHive-Project/CortexDocs/blob/master/api/api-guide.md#get-details-and-report + if (operation === 'report') { + + const jobId = this.getNodeParameter('jobId', i) as string; + + responseData = await cortexApiRequest.call( + this, + 'GET', + `/job/${jobId}/report`, ); } } - } - if (resource === 'job') { - //https://github.com/TheHive-Project/CortexDocs/blob/master/api/api-guide.md#get-details-1 - if (operation === 'get') { + if (resource === 'responder') { + if (operation === 'execute') { + const responderId = (this.getNodeParameter('responder', i) as string).split('::')[0]; - const jobId = this.getNodeParameter('jobId', i) as string; + const entityType = this.getNodeParameter('entityType', i) as string; - responseData = await cortexApiRequest.call( - this, - 'GET', - `/job/${jobId}`, - ); - } - //https://github.com/TheHive-Project/CortexDocs/blob/master/api/api-guide.md#get-details-and-report - if (operation === 'report') { - - const jobId = this.getNodeParameter('jobId', i) as string; - - responseData = await cortexApiRequest.call( - this, - 'GET', - `/job/${jobId}/report`, - ); - } - } - - if (resource === 'responder') { - if (operation === 'execute') { - const responderId = (this.getNodeParameter('responder', i) as string).split('::')[0]; - - const entityType = this.getNodeParameter('entityType', i) as string; - - const isJSON = this.getNodeParameter('jsonObject', i) as boolean; - let body: IDataObject; + const isJSON = this.getNodeParameter('jsonObject', i) as boolean; + let body: IDataObject; - if (isJSON) { - const entityJson = JSON.parse(this.getNodeParameter('objectData', i) as string); + if (isJSON) { + const entityJson = JSON.parse(this.getNodeParameter('objectData', i) as string); - body = { - responderId, - label: getEntityLabel(entityJson), - dataType: `thehive:${entityType}`, - data: entityJson, - tlp: entityJson.tlp || 2, - pap: entityJson.pap || 2, - message: entityJson.message || '', - parameters: [], - }; + body = { + responderId, + label: getEntityLabel(entityJson), + dataType: `thehive:${entityType}`, + data: entityJson, + tlp: entityJson.tlp || 2, + pap: entityJson.pap || 2, + message: entityJson.message || '', + parameters: [], + }; - } else { + } else { - const values = (this.getNodeParameter('parameters', i) as IDataObject).values as IDataObject; + const values = (this.getNodeParameter('parameters', i) as IDataObject).values as IDataObject; - body = { - responderId, - dataType: `thehive:${entityType}`, - data: { - _type: entityType, - ...prepareParameters(values), - }, - }; - if (entityType === 'alert') { - // deal with alert artifacts - const artifacts = (body.data as IDataObject).artifacts as IDataObject; + body = { + responderId, + dataType: `thehive:${entityType}`, + data: { + _type: entityType, + ...prepareParameters(values), + }, + }; + if (entityType === 'alert') { + // deal with alert artifacts + const artifacts = (body.data as IDataObject).artifacts as IDataObject; - if (artifacts) { + if (artifacts) { - const artifactValues = (artifacts as IDataObject).artifactValues as IDataObject[]; + const artifactValues = (artifacts as IDataObject).artifactValues as IDataObject[]; - if (artifactValues) { + if (artifactValues) { - const artifactData = []; + const artifactData = []; - for (const artifactvalue of artifactValues) { + for (const artifactvalue of artifactValues) { - const element: IDataObject = {}; + const element: IDataObject = {}; - element.message = artifactvalue.message as string; + element.message = artifactvalue.message as string; - element.tags = splitTags(artifactvalue.tags as string) as string[]; + element.tags = splitTags(artifactvalue.tags as string) as string[]; - element.dataType = artifactvalue.dataType as string; + element.dataType = artifactvalue.dataType as string; - element.data = artifactvalue.data as string; + element.data = artifactvalue.data as string; - if (artifactvalue.dataType === 'file') { + if (artifactvalue.dataType === 'file') { - const item = items[i]; + const item = items[i]; - if (item.binary === undefined) { - throw new NodeOperationError(this.getNode(), 'No binary data exists on item!'); + if (item.binary === undefined) { + throw new NodeOperationError(this.getNode(), 'No binary data exists on item!'); + } + + const binaryPropertyName = artifactvalue.binaryProperty as string; + + if (item.binary[binaryPropertyName] === undefined) { + throw new NodeOperationError(this.getNode(), `No binary data property '${binaryPropertyName}' does not exists on item!`); + } + + const binaryData = item.binary[binaryPropertyName] as IBinaryData; + + element.data = `${binaryData.fileName};${binaryData.mimeType};${binaryData.data}`; } - const binaryPropertyName = artifactvalue.binaryProperty as string; - - if (item.binary[binaryPropertyName] === undefined) { - throw new NodeOperationError(this.getNode(), `No binary data property '${binaryPropertyName}' does not exists on item!`); - } - - const binaryData = item.binary[binaryPropertyName] as IBinaryData; - - element.data = `${binaryData.fileName};${binaryData.mimeType};${binaryData.data}`; + artifactData.push(element); } - artifactData.push(element); + (body.data as IDataObject).artifacts = artifactData; + } + } + } + if (entityType === 'case_artifact') { + // deal with file observable + + if ((body.data as IDataObject).dataType === 'file') { + + const item = items[i]; + + if (item.binary === undefined) { + throw new NodeOperationError(this.getNode(), 'No binary data exists on item!'); } - (body.data as IDataObject).artifacts = artifactData; + const binaryPropertyName = (body.data as IDataObject).binaryPropertyName as string; + if (item.binary[binaryPropertyName] === undefined) { + throw new NodeOperationError(this.getNode(), `No binary data property "${binaryPropertyName}" does not exists on item!`); + } + + const fileBufferData = Buffer.from(item.binary[binaryPropertyName].data, BINARY_ENCODING); + const sha256 = createHash('sha256').update(fileBufferData).digest('hex'); + + (body.data as IDataObject).attachment = { + name: item.binary[binaryPropertyName].fileName, + hashes: [ + sha256, + createHash('sha1').update(fileBufferData).digest('hex'), + createHash('md5').update(fileBufferData).digest('hex'), + ], + size: fileBufferData.byteLength, + contentType: item.binary[binaryPropertyName].mimeType, + id: sha256, + }; + + delete (body.data as IDataObject).binaryPropertyName; } } + // add the job label after getting all entity attributes + body = { + label: getEntityLabel(body.data as IDataObject), + ...body, + }; + } - if (entityType === 'case_artifact') { - // deal with file observable - - if ((body.data as IDataObject).dataType === 'file') { - - const item = items[i]; - - if (item.binary === undefined) { - throw new NodeOperationError(this.getNode(), 'No binary data exists on item!'); - } - - const binaryPropertyName = (body.data as IDataObject).binaryPropertyName as string; - if (item.binary[binaryPropertyName] === undefined) { - throw new NodeOperationError(this.getNode(), `No binary data property "${binaryPropertyName}" does not exists on item!`); - } - - const fileBufferData = Buffer.from(item.binary[binaryPropertyName].data, BINARY_ENCODING); - const sha256 = createHash('sha256').update(fileBufferData).digest('hex'); - - (body.data as IDataObject).attachment = { - name: item.binary[binaryPropertyName].fileName, - hashes: [ - sha256, - createHash('sha1').update(fileBufferData).digest('hex'), - createHash('md5').update(fileBufferData).digest('hex'), - ], - size: fileBufferData.byteLength, - contentType: item.binary[binaryPropertyName].mimeType, - id: sha256, - }; - - delete (body.data as IDataObject).binaryPropertyName; - } - } - // add the job label after getting all entity attributes - body = { - label: getEntityLabel(body.data as IDataObject), - ...body, - }; - + responseData = await cortexApiRequest.call( + this, + 'POST', + `/responder/${responderId}/run`, + body, + ) as IJob; } - responseData = await cortexApiRequest.call( - this, - 'POST', - `/responder/${responderId}/run`, - body, - ) as IJob; } - } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else if (responseData !== undefined) { - returnData.push(responseData as IDataObject); + if (Array.isArray(responseData)) { + returnData.push.apply(returnData, responseData as IDataObject[]); + } else if (responseData !== undefined) { + returnData.push(responseData as IDataObject); + } + + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } } return [this.helpers.returnJsonArray(returnData)]; diff --git a/packages/nodes-base/nodes/Crypto.node.ts b/packages/nodes-base/nodes/Crypto.node.ts index dc602598a2..f8cd3cec7f 100644 --- a/packages/nodes-base/nodes/Crypto.node.ts +++ b/packages/nodes-base/nodes/Crypto.node.ts @@ -364,52 +364,63 @@ export class Crypto implements INodeType { let item: INodeExecutionData; for (let i = 0; i < length; i++) { - item = items[i]; - const dataPropertyName = this.getNodeParameter('dataPropertyName', i) as string; - const value = this.getNodeParameter('value', i) as string; - let newValue; - if (action === 'hash') { - const type = this.getNodeParameter('type', i) as string; - const encoding = this.getNodeParameter('encoding', i) as BinaryToTextEncoding; - newValue = createHash(type).update(value).digest(encoding); - } - if (action === 'hmac') { - const type = this.getNodeParameter('type', i) as string; - const secret = this.getNodeParameter('secret', i) as string; - const encoding = this.getNodeParameter('encoding', i) as BinaryToTextEncoding; - newValue = createHmac(type, secret).update(value).digest(encoding); - } - if (action === 'sign') { - const algorithm = this.getNodeParameter('algorithm', i) as string; - const encoding = this.getNodeParameter('encoding', i) as BinaryToTextEncoding; - const privateKey = this.getNodeParameter('privateKey', i) as string; - const sign = createSign(algorithm); - sign.write(value as string); - sign.end(); - newValue = sign.sign(privateKey, encoding); - } + try { - let newItem: INodeExecutionData; - if (dataPropertyName.includes('.')) { - // Uses dot notation so copy all data - newItem = { - json: JSON.parse(JSON.stringify(item.json)), - }; - } else { - // Does not use dot notation so shallow copy is enough - newItem = { - json: { ...item.json }, - }; + item = items[i]; + const dataPropertyName = this.getNodeParameter('dataPropertyName', i) as string; + const value = this.getNodeParameter('value', i) as string; + let newValue; + + if (action === 'hash') { + const type = this.getNodeParameter('type', i) as string; + const encoding = this.getNodeParameter('encoding', i) as BinaryToTextEncoding; + newValue = createHash(type).update(value).digest(encoding); + } + if (action === 'hmac') { + const type = this.getNodeParameter('type', i) as string; + const secret = this.getNodeParameter('secret', i) as string; + const encoding = this.getNodeParameter('encoding', i) as BinaryToTextEncoding; + newValue = createHmac(type, secret).update(value).digest(encoding); + } + if (action === 'sign') { + const algorithm = this.getNodeParameter('algorithm', i) as string; + const encoding = this.getNodeParameter('encoding', i) as BinaryToTextEncoding; + const privateKey = this.getNodeParameter('privateKey', i) as string; + const sign = createSign(algorithm); + sign.write(value as string); + sign.end(); + newValue = sign.sign(privateKey, encoding); + } + + let newItem: INodeExecutionData; + if (dataPropertyName.includes('.')) { + // Uses dot notation so copy all data + newItem = { + json: JSON.parse(JSON.stringify(item.json)), + }; + } else { + // Does not use dot notation so shallow copy is enough + newItem = { + json: { ...item.json }, + }; + } + + if (item.binary !== undefined) { + newItem.binary = item.binary; + } + + set(newItem, `json.${dataPropertyName}`, newValue); + + returnData.push(newItem); + + } catch (error) { + if (this.continueOnFail()) { + returnData.push({json:{ error: error.message }}); + continue; + } + throw error; } - - if (item.binary !== undefined) { - newItem.binary = item.binary; - } - - set(newItem, `json.${dataPropertyName}`, newValue); - - returnData.push(newItem); } return this.prepareOutputData(returnData); } diff --git a/packages/nodes-base/nodes/CustomerIo/CustomerIo.node.ts b/packages/nodes-base/nodes/CustomerIo/CustomerIo.node.ts index 92d991524b..b6396f9532 100644 --- a/packages/nodes-base/nodes/CustomerIo/CustomerIo.node.ts +++ b/packages/nodes-base/nodes/CustomerIo/CustomerIo.node.ts @@ -102,239 +102,249 @@ export class CustomerIo implements INodeType { let responseData; for (let i = 0; i < items.length; i++) { - if (resource === 'campaign') { - if (operation === 'get') { - const campaignId = this.getNodeParameter('campaignId', i) as number; - const endpoint = `/campaigns/${campaignId}`; + try { - responseData = await customerIoApiRequest.call(this, 'GET', endpoint, body, 'beta'); - responseData = responseData.campaign; - } - - if (operation === 'getAll') { - const endpoint = `/campaigns`; - - responseData = await customerIoApiRequest.call(this, 'GET', endpoint, body, 'beta'); - responseData = responseData.campaigns; - } - - if (operation === 'getMetrics') { - const campaignId = this.getNodeParameter('campaignId', i) as number; - const jsonParameters = this.getNodeParameter('jsonParameters', i) as boolean; - - if (jsonParameters) { - const additionalFieldsJson = this.getNodeParameter('additionalFieldsJson', i) as string; - - if (additionalFieldsJson !== '') { - - if (validateJSON(additionalFieldsJson) !== undefined) { - - Object.assign(body, JSON.parse(additionalFieldsJson)); - - } else { - throw new NodeOperationError(this.getNode(), 'Additional fields must be a valid JSON'); - } - } - } else { - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const period = this.getNodeParameter('period', i) as string; - let endpoint = `/campaigns/${campaignId}/metrics`; - - if (period !== 'days') { - endpoint = `${endpoint}?period=${period}`; - } - if (additionalFields.steps) { - body.steps = additionalFields.steps as number; - } - if (additionalFields.type) { - if (additionalFields.type === 'urbanAirship') { - additionalFields.type = 'urban_airship'; - } else { - body.type = additionalFields.type as string; - } - } + if (resource === 'campaign') { + if (operation === 'get') { + const campaignId = this.getNodeParameter('campaignId', i) as number; + const endpoint = `/campaigns/${campaignId}`; responseData = await customerIoApiRequest.call(this, 'GET', endpoint, body, 'beta'); - responseData = responseData.metric; + responseData = responseData.campaign; + } + + if (operation === 'getAll') { + const endpoint = `/campaigns`; + + responseData = await customerIoApiRequest.call(this, 'GET', endpoint, body, 'beta'); + responseData = responseData.campaigns; + } + + if (operation === 'getMetrics') { + const campaignId = this.getNodeParameter('campaignId', i) as number; + const jsonParameters = this.getNodeParameter('jsonParameters', i) as boolean; + + if (jsonParameters) { + const additionalFieldsJson = this.getNodeParameter('additionalFieldsJson', i) as string; + + if (additionalFieldsJson !== '') { + + if (validateJSON(additionalFieldsJson) !== undefined) { + + Object.assign(body, JSON.parse(additionalFieldsJson)); + + } else { + throw new NodeOperationError(this.getNode(), 'Additional fields must be a valid JSON'); + } + } + } else { + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const period = this.getNodeParameter('period', i) as string; + let endpoint = `/campaigns/${campaignId}/metrics`; + + if (period !== 'days') { + endpoint = `${endpoint}?period=${period}`; + } + if (additionalFields.steps) { + body.steps = additionalFields.steps as number; + } + if (additionalFields.type) { + if (additionalFields.type === 'urbanAirship') { + additionalFields.type = 'urban_airship'; + } else { + body.type = additionalFields.type as string; + } + } + + responseData = await customerIoApiRequest.call(this, 'GET', endpoint, body, 'beta'); + responseData = responseData.metric; + } } } - } - if (resource === 'customer') { + if (resource === 'customer') { - if (operation === 'upsert') { - const id = this.getNodeParameter('id', i) as number; - const jsonParameters = this.getNodeParameter('jsonParameters', i) as boolean; + if (operation === 'upsert') { + const id = this.getNodeParameter('id', i) as number; + const jsonParameters = this.getNodeParameter('jsonParameters', i) as boolean; - if (jsonParameters) { - const additionalFieldsJson = this.getNodeParameter('additionalFieldsJson', i) as string; + if (jsonParameters) { + const additionalFieldsJson = this.getNodeParameter('additionalFieldsJson', i) as string; - if (additionalFieldsJson !== '') { + if (additionalFieldsJson !== '') { - if (validateJSON(additionalFieldsJson) !== undefined) { + if (validateJSON(additionalFieldsJson) !== undefined) { - Object.assign(body, JSON.parse(additionalFieldsJson)); + Object.assign(body, JSON.parse(additionalFieldsJson)); - } else { - throw new NodeOperationError(this.getNode(), 'Additional fields must be a valid JSON'); + } else { + throw new NodeOperationError(this.getNode(), 'Additional fields must be a valid JSON'); + } + } + } else { + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + + if (additionalFields.customProperties) { + const data: any = {}; // tslint:disable-line:no-any + //@ts-ignore + additionalFields.customProperties.customProperty.map(property => { + data[property.key] = property.value; + }); + + body.data = data; + } + + if (additionalFields.email) { + body.email = additionalFields.email as string; + } + + if (additionalFields.createdAt) { + body.created_at = new Date(additionalFields.createdAt as string).getTime() / 1000; } } - } else { - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - if (additionalFields.customProperties) { + const endpoint = `/customers/${id}`; + + responseData = await customerIoApiRequest.call(this, 'PUT', endpoint, body, 'tracking'); + + responseData = Object.assign({ id }, body); + } + + if (operation === 'delete') { + const id = this.getNodeParameter('id', i) as number; + + body.id = id; + + const endpoint = `/customers/${id}`; + + await customerIoApiRequest.call(this, 'DELETE', endpoint, body, 'tracking'); + + responseData = { + success: true, + }; + } + } + + if (resource === 'event') { + if (operation === 'track') { + const customerId = this.getNodeParameter('customerId', i) as number; + const eventName = this.getNodeParameter('eventName', i) as string; + const jsonParameters = this.getNodeParameter('jsonParameters', i) as boolean; + + body.name = eventName; + + if (jsonParameters) { + const additionalFieldsJson = this.getNodeParameter('additionalFieldsJson', i) as string; + + if (additionalFieldsJson !== '') { + + if (validateJSON(additionalFieldsJson) !== undefined) { + Object.assign(body, JSON.parse(additionalFieldsJson)); + } else { + throw new NodeOperationError(this.getNode(), 'Additional fields must be a valid JSON'); + } + } + } else { + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; const data: any = {}; // tslint:disable-line:no-any - //@ts-ignore - additionalFields.customProperties.customProperty.map(property => { - data[property.key] = property.value; - }); + + if (additionalFields.customAttributes) { + //@ts-ignore + additionalFields.customAttributes.customAttribute.map(property => { + data[property.key] = property.value; + }); + } + + if (additionalFields.type) { + data.type = additionalFields.type as string; + } body.data = data; } - if (additionalFields.email) { - body.email = additionalFields.email as string; - } + const endpoint = `/customers/${customerId}/events`; - if (additionalFields.createdAt) { - body.created_at = new Date(additionalFields.createdAt as string).getTime() / 1000; - } + await customerIoApiRequest.call(this, 'POST', endpoint, body, 'tracking'); + responseData = { + success: true, + }; } - const endpoint = `/customers/${id}`; + if (operation === 'trackAnonymous') { + const eventName = this.getNodeParameter('eventName', i) as string; + const jsonParameters = this.getNodeParameter('jsonParameters', i) as boolean; - responseData = await customerIoApiRequest.call(this, 'PUT', endpoint, body, 'tracking'); + body.name = eventName; - responseData = Object.assign({ id }, body); - } + if (jsonParameters) { + const additionalFieldsJson = this.getNodeParameter('additionalFieldsJson', i) as string; - if (operation === 'delete') { - const id = this.getNodeParameter('id', i) as number; + if (additionalFieldsJson !== '') { - body.id = id; + if (validateJSON(additionalFieldsJson) !== undefined) { - const endpoint = `/customers/${id}`; + Object.assign(body, JSON.parse(additionalFieldsJson)); - await customerIoApiRequest.call(this, 'DELETE', endpoint, body, 'tracking'); - - responseData = { - success: true, - }; - } - } - - if (resource === 'event') { - if (operation === 'track') { - const customerId = this.getNodeParameter('customerId', i) as number; - const eventName = this.getNodeParameter('eventName', i) as string; - const jsonParameters = this.getNodeParameter('jsonParameters', i) as boolean; - - body.name = eventName; - - if (jsonParameters) { - const additionalFieldsJson = this.getNodeParameter('additionalFieldsJson', i) as string; - - if (additionalFieldsJson !== '') { - - if (validateJSON(additionalFieldsJson) !== undefined) { - Object.assign(body, JSON.parse(additionalFieldsJson)); - } else { - throw new NodeOperationError(this.getNode(), 'Additional fields must be a valid JSON'); + } else { + throw new NodeOperationError(this.getNode(), 'Additional fields must be a valid JSON'); + } } - } - } else { - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const data: any = {}; // tslint:disable-line:no-any + } else { + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const data: any = {}; // tslint:disable-line:no-any - if (additionalFields.customAttributes) { - //@ts-ignore - additionalFields.customAttributes.customAttribute.map(property => { - data[property.key] = property.value; - }); - } - - if (additionalFields.type) { - data.type = additionalFields.type as string; - } - - body.data = data; - } - - const endpoint = `/customers/${customerId}/events`; - - await customerIoApiRequest.call(this, 'POST', endpoint, body, 'tracking'); - responseData = { - success: true, - }; - } - - if (operation === 'trackAnonymous') { - const eventName = this.getNodeParameter('eventName', i) as string; - const jsonParameters = this.getNodeParameter('jsonParameters', i) as boolean; - - body.name = eventName; - - if (jsonParameters) { - const additionalFieldsJson = this.getNodeParameter('additionalFieldsJson', i) as string; - - if (additionalFieldsJson !== '') { - - if (validateJSON(additionalFieldsJson) !== undefined) { - - Object.assign(body, JSON.parse(additionalFieldsJson)); - - } else { - throw new NodeOperationError(this.getNode(), 'Additional fields must be a valid JSON'); + if (additionalFields.customAttributes) { + //@ts-ignore + additionalFields.customAttributes.customAttribute.map(property => { + data[property.key] = property.value; + }); } + body.data = data; } - } else { - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const data: any = {}; // tslint:disable-line:no-any - if (additionalFields.customAttributes) { - //@ts-ignore - additionalFields.customAttributes.customAttribute.map(property => { - data[property.key] = property.value; - }); - } - body.data = data; + const endpoint = `/events`; + await customerIoApiRequest.call(this, 'POST', endpoint, body, 'tracking'); + + responseData = { + success: true, + }; + } + } + + if (resource === 'segment') { + const segmentId = this.getNodeParameter('segmentId', i) as number; + const customerIds = this.getNodeParameter('customerIds', i) as string; + + body.id = segmentId; + body.ids = customerIds.split(','); + + let endpoint = ''; + + if (operation === 'add') { + endpoint = `/segments/${segmentId}/add_customers`; + } else { + endpoint = `/segments/${segmentId}/remove_customers`; } - const endpoint = `/events`; - await customerIoApiRequest.call(this, 'POST', endpoint, body, 'tracking'); + responseData = await customerIoApiRequest.call(this, 'POST', endpoint, body, 'tracking'); responseData = { success: true, }; } - } - if (resource === 'segment') { - const segmentId = this.getNodeParameter('segmentId', i) as number; - const customerIds = this.getNodeParameter('customerIds', i) as string; - - body.id = segmentId; - body.ids = customerIds.split(','); - - let endpoint = ''; - - if (operation === 'add') { - endpoint = `/segments/${segmentId}/add_customers`; + if (Array.isArray(responseData)) { + returnData.push.apply(returnData, responseData as IDataObject[]); } else { - endpoint = `/segments/${segmentId}/remove_customers`; + returnData.push(responseData as unknown as IDataObject); } - responseData = await customerIoApiRequest.call(this, 'POST', endpoint, body, 'tracking'); - - responseData = { - success: true, - }; - } - - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else { - returnData.push(responseData as unknown as IDataObject); + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } } diff --git a/packages/nodes-base/nodes/DateTime.node.ts b/packages/nodes-base/nodes/DateTime.node.ts index d0aeb44731..df586997fd 100644 --- a/packages/nodes-base/nodes/DateTime.node.ts +++ b/packages/nodes-base/nodes/DateTime.node.ts @@ -393,110 +393,120 @@ export class DateTime implements INodeType { let item: INodeExecutionData; for (let i = 0; i < length; i++) { - const action = this.getNodeParameter('action', 0) as string; - item = items[i]; + try { - if (action === 'format') { - const currentDate = this.getNodeParameter('value', i) as string; - const dataPropertyName = this.getNodeParameter('dataPropertyName', i) as string; - const toFormat = this.getNodeParameter('toFormat', i) as string; - const options = this.getNodeParameter('options', i) as IDataObject; - let newDate; + const action = this.getNodeParameter('action', 0) as string; + item = items[i]; - if (currentDate === undefined) { - continue; - } - if (options.fromFormat === undefined && !moment(currentDate as string | number).isValid()) { - throw new NodeOperationError(this.getNode(), 'The date input format could not be recognized. Please set the "From Format" field'); - } + if (action === 'format') { + const currentDate = this.getNodeParameter('value', i) as string; + const dataPropertyName = this.getNodeParameter('dataPropertyName', i) as string; + const toFormat = this.getNodeParameter('toFormat', i) as string; + const options = this.getNodeParameter('options', i) as IDataObject; + let newDate; - if (Number.isInteger(currentDate as unknown as number)) { - newDate = moment.unix(currentDate as unknown as number); - } else { - if (options.fromTimezone || options.toTimezone) { - const fromTimezone = options.fromTimezone || workflowTimezone; - if (options.fromFormat) { - newDate = moment.tz(currentDate as string, options.fromFormat as string, fromTimezone as string); - } else { - newDate = moment.tz(currentDate as string, fromTimezone as string); - } + if (currentDate === undefined) { + continue; + } + if (options.fromFormat === undefined && !moment(currentDate as string | number).isValid()) { + throw new NodeOperationError(this.getNode(), 'The date input format could not be recognized. Please set the "From Format" field'); + } + + if (Number.isInteger(currentDate as unknown as number)) { + newDate = moment.unix(currentDate as unknown as number); } else { - if (options.fromFormat) { - newDate = moment(currentDate as string, options.fromFormat as string); + if (options.fromTimezone || options.toTimezone) { + const fromTimezone = options.fromTimezone || workflowTimezone; + if (options.fromFormat) { + newDate = moment.tz(currentDate as string, options.fromFormat as string, fromTimezone as string); + } else { + newDate = moment.tz(currentDate as string, fromTimezone as string); + } } else { - newDate = moment(currentDate as string); + if (options.fromFormat) { + newDate = moment(currentDate as string, options.fromFormat as string); + } else { + newDate = moment(currentDate as string); + } } } + + if (options.toTimezone || options.fromTimezone) { + // If either a source or a target timezone got defined the + // timezone of the date has to be changed. If a target-timezone + // is set use it else fall back to workflow timezone. + newDate = newDate.tz(options.toTimezone as string || workflowTimezone); + } + + newDate = newDate.format(toFormat); + + let newItem: INodeExecutionData; + if (dataPropertyName.includes('.')) { + // Uses dot notation so copy all data + newItem = { + json: JSON.parse(JSON.stringify(item.json)), + }; + } else { + // Does not use dot notation so shallow copy is enough + newItem = { + json: { ...item.json }, + }; + } + + if (item.binary !== undefined) { + newItem.binary = item.binary; + } + + set(newItem, `json.${dataPropertyName}`, newDate); + + returnData.push(newItem); } - if (options.toTimezone || options.fromTimezone) { - // If either a source or a target timezone got defined the - // timezone of the date has to be changed. If a target-timezone - // is set use it else fall back to workflow timezone. - newDate = newDate.tz(options.toTimezone as string || workflowTimezone); + if (action === 'calculate') { + + const dateValue = this.getNodeParameter('value', i) as string; + const operation = this.getNodeParameter('operation', i) as 'add' | 'subtract'; + const duration = this.getNodeParameter('duration', i) as number; + const timeUnit = this.getNodeParameter('timeUnit', i) as moment.DurationInputArg2; + const { fromFormat } = this.getNodeParameter('options', i) as { fromFormat?: string }; + const dataPropertyName = this.getNodeParameter('dataPropertyName', i) as string; + + const newDate = fromFormat + ? parseDateByFormat(dateValue, fromFormat) + : parseDateByDefault(dateValue); + + operation === 'add' + ? newDate.add(duration, timeUnit).utc().format() + : newDate.subtract(duration, timeUnit).utc().format(); + + let newItem: INodeExecutionData; + if (dataPropertyName.includes('.')) { + // Uses dot notation so copy all data + newItem = { + json: JSON.parse(JSON.stringify(item.json)), + }; + } else { + // Does not use dot notation so shallow copy is enough + newItem = { + json: { ...item.json }, + }; + } + + if (item.binary !== undefined) { + newItem.binary = item.binary; + } + + set(newItem, `json.${dataPropertyName}`, newDate); + + returnData.push(newItem); } - newDate = newDate.format(toFormat); - - let newItem: INodeExecutionData; - if (dataPropertyName.includes('.')) { - // Uses dot notation so copy all data - newItem = { - json: JSON.parse(JSON.stringify(item.json)), - }; - } else { - // Does not use dot notation so shallow copy is enough - newItem = { - json: { ...item.json }, - }; + } catch (error) { + if (this.continueOnFail()) { + returnData.push({json:{ error: error.message }}); + continue; } - - if (item.binary !== undefined) { - newItem.binary = item.binary; - } - - set(newItem, `json.${dataPropertyName}`, newDate); - - returnData.push(newItem); - } - - if (action === 'calculate') { - - const dateValue = this.getNodeParameter('value', i) as string; - const operation = this.getNodeParameter('operation', i) as 'add' | 'subtract'; - const duration = this.getNodeParameter('duration', i) as number; - const timeUnit = this.getNodeParameter('timeUnit', i) as moment.DurationInputArg2; - const { fromFormat } = this.getNodeParameter('options', i) as { fromFormat?: string }; - const dataPropertyName = this.getNodeParameter('dataPropertyName', i) as string; - - const newDate = fromFormat - ? parseDateByFormat(dateValue, fromFormat) - : parseDateByDefault(dateValue); - - operation === 'add' - ? newDate.add(duration, timeUnit).utc().format() - : newDate.subtract(duration, timeUnit).utc().format(); - - let newItem: INodeExecutionData; - if (dataPropertyName.includes('.')) { - // Uses dot notation so copy all data - newItem = { - json: JSON.parse(JSON.stringify(item.json)), - }; - } else { - // Does not use dot notation so shallow copy is enough - newItem = { - json: { ...item.json }, - }; - } - - if (item.binary !== undefined) { - newItem.binary = item.binary; - } - - set(newItem, `json.${dataPropertyName}`, newDate); - - returnData.push(newItem); + throw error; } } diff --git a/packages/nodes-base/nodes/DeepL/DeepL.node.ts b/packages/nodes-base/nodes/DeepL/DeepL.node.ts index ebd8377792..30169b2224 100644 --- a/packages/nodes-base/nodes/DeepL/DeepL.node.ts +++ b/packages/nodes-base/nodes/DeepL/DeepL.node.ts @@ -108,28 +108,35 @@ export class DeepL implements INodeType { const responseData = []; for (let i = 0; i < length; i++) { + try { + const resource = this.getNodeParameter('resource', i) as string; + const operation = this.getNodeParameter('operation', i) as string; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const resource = this.getNodeParameter('resource', i) as string; - const operation = this.getNodeParameter('operation', i) as string; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + if (resource === 'language') { - if (resource === 'language') { + if (operation === 'translate') { - if (operation === 'translate') { + const text = this.getNodeParameter('text', i) as string; + const translateTo = this.getNodeParameter('translateTo', i) as string; + const qs = { target_lang: translateTo, text } as IDataObject; - const text = this.getNodeParameter('text', i) as string; - const translateTo = this.getNodeParameter('translateTo', i) as string; - const qs = { target_lang: translateTo, text } as IDataObject; + if (additionalFields.sourceLang !== undefined) { + qs.source_lang = ['EN-GB', 'EN-US'].includes(additionalFields.sourceLang as string) + ? 'EN' + : additionalFields.sourceLang; + } - if (additionalFields.sourceLang !== undefined) { - qs.source_lang = ['EN-GB', 'EN-US'].includes(additionalFields.sourceLang as string) - ? 'EN' - : additionalFields.sourceLang; + const response = await deepLApiRequest.call(this, 'GET', '/translate', {}, qs); + responseData.push(response.translations[0]); } - - const response = await deepLApiRequest.call(this, 'GET', '/translate', {}, qs); - responseData.push(response.translations[0]); } + } catch (error) { + if (this.continueOnFail()) { + responseData.push({ error: error.message }); + continue; + } + throw error; } } diff --git a/packages/nodes-base/nodes/Demio/Demio.node.ts b/packages/nodes-base/nodes/Demio/Demio.node.ts index f0b21b483d..fb9ae1dbd0 100644 --- a/packages/nodes-base/nodes/Demio/Demio.node.ts +++ b/packages/nodes-base/nodes/Demio/Demio.node.ts @@ -139,71 +139,79 @@ export class Demio implements INodeType { const operation = this.getNodeParameter('operation', 0) as string; for (let i = 0; i < length; i++) { - if (resource === 'event') { - if (operation === 'get') { - const id = this.getNodeParameter('eventId', i) as string; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + try { + if (resource === 'event') { + if (operation === 'get') { + const id = this.getNodeParameter('eventId', i) as string; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - if (additionalFields.date_id !== undefined) { - responseData = await demioApiRequest.call(this, 'GET', `/event/${id}/date/${additionalFields.date_id}`); - } else { - Object.assign(qs, additionalFields); - responseData = await demioApiRequest.call(this, 'GET', `/event/${id}`, {}, qs); + if (additionalFields.date_id !== undefined) { + responseData = await demioApiRequest.call(this, 'GET', `/event/${id}/date/${additionalFields.date_id}`); + } else { + Object.assign(qs, additionalFields); + responseData = await demioApiRequest.call(this, 'GET', `/event/${id}`, {}, qs); + } + } + if (operation === 'getAll') { + const filters = this.getNodeParameter('filters', i) as IDataObject; + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + + Object.assign(qs, filters); + + responseData = await demioApiRequest.call(this, 'GET', `/events`, {}, qs); + + if (returnAll === false) { + const limit = this.getNodeParameter('limit', i) as number; + responseData = responseData.splice(0, limit); + } + + } + if (operation === 'register') { + const eventId = this.getNodeParameter('eventId', i) as string; + const firstName = this.getNodeParameter('firstName', i) as string; + const email = this.getNodeParameter('email', i) as string; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + + const body: IDataObject = { + name: firstName, + email, + id: eventId, + }; + + Object.assign(body, additionalFields); + + if (additionalFields.customFieldsUi) { + const customFields = (additionalFields.customFieldsUi as IDataObject || {}).customFieldsValues as IDataObject[] || []; + const data = customFields.reduce((obj, value) => Object.assign(obj, { [`${value.fieldId}`]: value.value }), {}); + Object.assign(body, data); + delete additionalFields.customFields; + } + + responseData = await demioApiRequest.call(this, 'PUT', `/event/register`, body); } } - if (operation === 'getAll') { - const filters = this.getNodeParameter('filters', i) as IDataObject; - const returnAll = this.getNodeParameter('returnAll', i) as boolean; + if (resource === 'report') { + if (operation === 'get') { + const sessionId = this.getNodeParameter('dateId', i) as string; + const filters = this.getNodeParameter('filters', i) as IDataObject; - Object.assign(qs, filters); + Object.assign(qs, filters); - responseData = await demioApiRequest.call(this, 'GET', `/events`, {}, qs); - - if (returnAll === false) { - const limit = this.getNodeParameter('limit', i) as number; - responseData = responseData.splice(0, limit); + responseData = await demioApiRequest.call(this, 'GET', `/report/${sessionId}/participants`, {}, qs); + responseData = responseData.participants; } - } - if (operation === 'register') { - const eventId = this.getNodeParameter('eventId', i) as string; - const firstName = this.getNodeParameter('firstName', i) as string; - const email = this.getNodeParameter('email', i) as string; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - - const body: IDataObject = { - name: firstName, - email, - id: eventId, - }; - - Object.assign(body, additionalFields); - - if (additionalFields.customFieldsUi) { - const customFields = (additionalFields.customFieldsUi as IDataObject || {}).customFieldsValues as IDataObject[] || []; - const data = customFields.reduce((obj, value) => Object.assign(obj, { [`${value.fieldId}`]: value.value }), {}); - Object.assign(body, data); - delete additionalFields.customFields; - } - - responseData = await demioApiRequest.call(this, 'PUT', `/event/register`, body); + if (Array.isArray(responseData)) { + returnData.push.apply(returnData, responseData as IDataObject[]); + } else { + returnData.push(responseData as IDataObject); } - } - if (resource === 'report') { - if (operation === 'get') { - const sessionId = this.getNodeParameter('dateId', i) as string; - const filters = this.getNodeParameter('filters', i) as IDataObject; - - Object.assign(qs, filters); - - responseData = await demioApiRequest.call(this, 'GET', `/report/${sessionId}/participants`, {}, qs); - responseData = responseData.participants; + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; } - } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else { - returnData.push(responseData as IDataObject); + throw error; } } return [this.helpers.returnJsonArray(returnData)]; diff --git a/packages/nodes-base/nodes/Discourse/Discourse.node.ts b/packages/nodes-base/nodes/Discourse/Discourse.node.ts index 7110e0759b..4d695e4268 100644 --- a/packages/nodes-base/nodes/Discourse/Discourse.node.ts +++ b/packages/nodes-base/nodes/Discourse/Discourse.node.ts @@ -150,351 +150,359 @@ export class Discourse implements INodeType { 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 === 'category') { - //https://docs.discourse.org/#tag/Categories/paths/~1categories.json/post - if (operation === 'create') { - const name = this.getNodeParameter('name', i) as string; - const color = this.getNodeParameter('color', i) as string; - const textColor = this.getNodeParameter('textColor', i) as string; + try { + if (resource === 'category') { + //https://docs.discourse.org/#tag/Categories/paths/~1categories.json/post + if (operation === 'create') { + const name = this.getNodeParameter('name', i) as string; + const color = this.getNodeParameter('color', i) as string; + const textColor = this.getNodeParameter('textColor', i) as string; - const body: IDataObject = { - name, - color, - text_color: textColor, - }; + const body: IDataObject = { + name, + color, + text_color: textColor, + }; - responseData = await discourseApiRequest.call( - this, - 'POST', - `/categories.json`, - body, - ); + responseData = await discourseApiRequest.call( + this, + 'POST', + `/categories.json`, + body, + ); - responseData = responseData.category; - } - //https://docs.discourse.org/#tag/Categories/paths/~1categories.json/get - if (operation === 'getAll') { - const returnAll = this.getNodeParameter('returnAll', i) as boolean; + responseData = responseData.category; + } + //https://docs.discourse.org/#tag/Categories/paths/~1categories.json/get + if (operation === 'getAll') { + const returnAll = this.getNodeParameter('returnAll', i) as boolean; - responseData = await discourseApiRequest.call( - this, - 'GET', - `/categories.json`, - {}, - qs, - ); + responseData = await discourseApiRequest.call( + this, + 'GET', + `/categories.json`, + {}, + qs, + ); - responseData = responseData.category_list.categories; + responseData = responseData.category_list.categories; - if (returnAll === false) { - const limit = this.getNodeParameter('limit', i) as number; - responseData = responseData.splice(0, limit); + if (returnAll === false) { + const limit = this.getNodeParameter('limit', i) as number; + responseData = responseData.splice(0, limit); + } + } + //https://docs.discourse.org/#tag/Categories/paths/~1categories~1{id}/put + if (operation === 'update') { + const categoryId = this.getNodeParameter('categoryId', i) as string; + + const name = this.getNodeParameter('name', i) as string; + + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + + const body: IDataObject = { + name, + }; + + Object.assign(body, updateFields); + + responseData = await discourseApiRequest.call( + this, + 'PUT', + `/categories/${categoryId}.json`, + body, + ); + + responseData = responseData.category; } } - //https://docs.discourse.org/#tag/Categories/paths/~1categories~1{id}/put - if (operation === 'update') { - const categoryId = this.getNodeParameter('categoryId', i) as string; + if (resource === 'group') { + //https://docs.discourse.org/#tag/Posts/paths/~1posts.json/post + if (operation === 'create') { + const name = this.getNodeParameter('name', i) as string; - const name = this.getNodeParameter('name', i) as string; + const body: IDataObject = { + name, + }; - const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + responseData = await discourseApiRequest.call( + this, + 'POST', + `/admin/groups.json`, + { group: body }, + ); - const body: IDataObject = { - name, - }; + responseData = responseData.basic_group; + } + //https://docs.discourse.org/#tag/Groups/paths/~1groups~1{name}.json/get + if (operation === 'get') { + const name = this.getNodeParameter('name', i) as string; - Object.assign(body, updateFields); + responseData = await discourseApiRequest.call( + this, + 'GET', + `/groups/${name}`, + {}, + qs, + ); - responseData = await discourseApiRequest.call( - this, - 'PUT', - `/categories/${categoryId}.json`, - body, - ); + responseData = responseData.group; - responseData = responseData.category; - } - } - if (resource === 'group') { - //https://docs.discourse.org/#tag/Posts/paths/~1posts.json/post - if (operation === 'create') { - const name = this.getNodeParameter('name', i) as string; + } + //https://docs.discourse.org/#tag/Groups/paths/~1groups.json/get + if (operation === 'getAll') { + const returnAll = this.getNodeParameter('returnAll', i) as boolean; - const body: IDataObject = { - name, - }; + responseData = await discourseApiRequest.call( + this, + 'GET', + `/groups.json`, + {}, + qs, + ); - responseData = await discourseApiRequest.call( - this, - 'POST', - `/admin/groups.json`, - { group: body }, - ); + responseData = responseData.groups; - responseData = responseData.basic_group; - } - //https://docs.discourse.org/#tag/Groups/paths/~1groups~1{name}.json/get - if (operation === 'get') { - const name = this.getNodeParameter('name', i) as string; + if (returnAll === false) { + const limit = this.getNodeParameter('limit', i) as number; + responseData = responseData.splice(0, limit); + } + } + //https://docs.discourse.org/#tag/Posts/paths/~1posts~1{id}.json/put + if (operation === 'update') { + const groupId = this.getNodeParameter('groupId', i) as string; - responseData = await discourseApiRequest.call( - this, - 'GET', - `/groups/${name}`, - {}, - qs, - ); + const name = this.getNodeParameter('name', i) as string; - responseData = responseData.group; + const body: IDataObject = { + name, + }; - } - //https://docs.discourse.org/#tag/Groups/paths/~1groups.json/get - if (operation === 'getAll') { - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - - responseData = await discourseApiRequest.call( - this, - 'GET', - `/groups.json`, - {}, - qs, - ); - - responseData = responseData.groups; - - if (returnAll === false) { - const limit = this.getNodeParameter('limit', i) as number; - responseData = responseData.splice(0, limit); + responseData = await discourseApiRequest.call( + this, + 'PUT', + `/groups/${groupId}.json`, + { group: body }, + ); } } - //https://docs.discourse.org/#tag/Posts/paths/~1posts~1{id}.json/put - if (operation === 'update') { - const groupId = this.getNodeParameter('groupId', i) as string; + if (resource === 'post') { + //https://docs.discourse.org/#tag/Posts/paths/~1posts.json/post + if (operation === 'create') { + const content = this.getNodeParameter('content', i) as string; + const title = this.getNodeParameter('title', i) as string; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const name = this.getNodeParameter('name', i) as string; + const body: IDataObject = { + title, + raw: content, + }; - const body: IDataObject = { - name, - }; + Object.assign(body, additionalFields); - responseData = await discourseApiRequest.call( - this, - 'PUT', - `/groups/${groupId}.json`, - { group: body }, - ); - } - } - if (resource === 'post') { - //https://docs.discourse.org/#tag/Posts/paths/~1posts.json/post - if (operation === 'create') { - const content = this.getNodeParameter('content', i) as string; - const title = this.getNodeParameter('title', i) as string; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + responseData = await discourseApiRequest.call( + this, + 'POST', + `/posts.json`, + body, + ); + } + //https://docs.discourse.org/#tag/Posts/paths/~1posts~1{id}.json/get + if (operation === 'get') { + const postId = this.getNodeParameter('postId', i) as string; - const body: IDataObject = { - title, - raw: content, - }; + responseData = await discourseApiRequest.call( + this, + 'GET', + `/posts/${postId}`, + {}, + qs, + ); + } + //https://docs.discourse.org/#tag/Posts/paths/~1posts.json/get + if (operation === 'getAll') { + const returnAll = this.getNodeParameter('returnAll', i) as boolean; - Object.assign(body, additionalFields); + responseData = await discourseApiRequest.call( + this, + 'GET', + `/posts.json`, + {}, + qs, + ); - responseData = await discourseApiRequest.call( - this, - 'POST', - `/posts.json`, - body, - ); - } - //https://docs.discourse.org/#tag/Posts/paths/~1posts~1{id}.json/get - if (operation === 'get') { - const postId = this.getNodeParameter('postId', i) as string; + responseData = responseData.latest_posts; - responseData = await discourseApiRequest.call( - this, - 'GET', - `/posts/${postId}`, - {}, - qs, - ); - } - //https://docs.discourse.org/#tag/Posts/paths/~1posts.json/get - if (operation === 'getAll') { - const returnAll = this.getNodeParameter('returnAll', i) as boolean; + if (returnAll === false) { + const limit = this.getNodeParameter('limit', i) as number; + responseData = responseData.splice(0, limit); + } + } + //https://docs.discourse.org/#tag/Posts/paths/~1posts~1{id}.json/put + if (operation === 'update') { + const postId = this.getNodeParameter('postId', i) as string; - responseData = await discourseApiRequest.call( - this, - 'GET', - `/posts.json`, - {}, - qs, - ); + const content = this.getNodeParameter('content', i) as string; - responseData = responseData.latest_posts; + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; - if (returnAll === false) { - const limit = this.getNodeParameter('limit', i) as number; - responseData = responseData.splice(0, limit); + const body: IDataObject = { + raw: content, + }; + + Object.assign(body, updateFields); + + responseData = await discourseApiRequest.call( + this, + 'PUT', + `/posts/${postId}.json`, + body, + ); + + responseData = responseData.post; } } - //https://docs.discourse.org/#tag/Posts/paths/~1posts~1{id}.json/put - if (operation === 'update') { - const postId = this.getNodeParameter('postId', i) as string; + // TODO figure how to paginate the results + // if (resource === 'search') { + // //https://docs.discourse.org/#tag/Search/paths/~1search~1query/get + // if (operation === 'query') { + // qs.term = this.getNodeParameter('term', i) as string; - const content = this.getNodeParameter('content', i) as string; + // const simple = this.getNodeParameter('simple', i) as boolean; - const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + // const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; - const body: IDataObject = { - raw: content, - }; + // Object.assign(qs, updateFields); - Object.assign(body, updateFields); + // qs.page = 1; - responseData = await discourseApiRequest.call( - this, - 'PUT', - `/posts/${postId}.json`, - body, - ); + // responseData = await discourseApiRequest.call( + // this, + // 'GET', + // `/search/query`, + // {}, + // qs, + // ); - responseData = responseData.post; - } - } - // TODO figure how to paginate the results - // if (resource === 'search') { - // //https://docs.discourse.org/#tag/Search/paths/~1search~1query/get - // if (operation === 'query') { - // qs.term = this.getNodeParameter('term', i) as string; - - // const simple = this.getNodeParameter('simple', i) as boolean; - - // const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; - - // Object.assign(qs, updateFields); - - // qs.page = 1; - - // responseData = await discourseApiRequest.call( - // this, - // 'GET', - // `/search/query`, - // {}, - // qs, - // ); - - // if (simple === true) { - // const response = []; - // for (const key of Object.keys(responseData)) { - // console.log(key) - // for (const data of responseData[key]) { - // response.push(Object.assign(data, { __type: key })); - // } - // } - // responseData = response; - // } - // } - // } - if (resource === 'user') { - //https://docs.discourse.org/#tag/Users/paths/~1users/post - if (operation === 'create') { - const name = this.getNodeParameter('name', i) as string; - const email = this.getNodeParameter('email', i) as string; - const password = this.getNodeParameter('password', i) as string; - const username = this.getNodeParameter('username', i) as string; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - - const body: IDataObject = { - name, - password, - email, - username, - }; - - Object.assign(body, additionalFields); - - responseData = await discourseApiRequest.call( - this, - 'POST', - `/users.json`, - body, - ); - } - //https://docs.discourse.org/#tag/Users/paths/~1users~1{username}.json/get - if (operation === 'get') { - const by = this.getNodeParameter('by', i) as string; - let endpoint = ''; - if (by === 'username') { + // if (simple === true) { + // const response = []; + // for (const key of Object.keys(responseData)) { + // console.log(key) + // for (const data of responseData[key]) { + // response.push(Object.assign(data, { __type: key })); + // } + // } + // responseData = response; + // } + // } + // } + if (resource === 'user') { + //https://docs.discourse.org/#tag/Users/paths/~1users/post + if (operation === 'create') { + const name = this.getNodeParameter('name', i) as string; + const email = this.getNodeParameter('email', i) as string; + const password = this.getNodeParameter('password', i) as string; const username = this.getNodeParameter('username', i) as string; - endpoint = `/users/${username}`; - } else if (by === 'externalId') { - const externalId = this.getNodeParameter('externalId', i) as string; - endpoint = `/u/by-external/${externalId}.json`; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + + const body: IDataObject = { + name, + password, + email, + username, + }; + + Object.assign(body, additionalFields); + + responseData = await discourseApiRequest.call( + this, + 'POST', + `/users.json`, + body, + ); } + //https://docs.discourse.org/#tag/Users/paths/~1users~1{username}.json/get + if (operation === 'get') { + const by = this.getNodeParameter('by', i) as string; + let endpoint = ''; + if (by === 'username') { + const username = this.getNodeParameter('username', i) as string; + endpoint = `/users/${username}`; + } else if (by === 'externalId') { + const externalId = this.getNodeParameter('externalId', i) as string; + endpoint = `/u/by-external/${externalId}.json`; + } - responseData = await discourseApiRequest.call( - this, - 'GET', - endpoint, - ); - } - //https://docs.discourse.org/#tag/Users/paths/~1admin~1users~1{id}.json/delete - if (operation === 'getAll') { - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - const flag = this.getNodeParameter('flag', i) as boolean; + responseData = await discourseApiRequest.call( + this, + 'GET', + endpoint, + ); + } + //https://docs.discourse.org/#tag/Users/paths/~1admin~1users~1{id}.json/delete + if (operation === 'getAll') { + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + const flag = this.getNodeParameter('flag', i) as boolean; - responseData = await discourseApiRequest.call( - this, - 'GET', - `/admin/users/list/${flag}.json`, - {}, - qs, - ); + responseData = await discourseApiRequest.call( + this, + 'GET', + `/admin/users/list/${flag}.json`, + {}, + qs, + ); - if (returnAll === false) { - const limit = this.getNodeParameter('limit', i) as number; - responseData = responseData.splice(0, limit); + if (returnAll === false) { + const limit = this.getNodeParameter('limit', i) as number; + responseData = responseData.splice(0, limit); + } } } - } - if (resource === 'userGroup') { - //https://docs.discourse.org/#tag/Groups/paths/~1groups~1{group_id}~1members.json/put - if (operation === 'add') { - const usernames = this.getNodeParameter('usernames', i) as string; - const groupId = this.getNodeParameter('groupId', i) as string; - const body: IDataObject = { - usernames, - }; + if (resource === 'userGroup') { + //https://docs.discourse.org/#tag/Groups/paths/~1groups~1{group_id}~1members.json/put + if (operation === 'add') { + const usernames = this.getNodeParameter('usernames', i) as string; + const groupId = this.getNodeParameter('groupId', i) as string; + const body: IDataObject = { + usernames, + }; - responseData = await discourseApiRequest.call( - this, - 'PUT', - `/groups/${groupId}/members.json`, - body, - ); - } - //https://docs.discourse.org/#tag/Groups/paths/~1groups~1{group_id}~1members.json/delete - if (operation === 'remove') { - const usernames = this.getNodeParameter('usernames', i) as string; - const groupId = this.getNodeParameter('groupId', i) as string; - const body: IDataObject = { - usernames, - }; + responseData = await discourseApiRequest.call( + this, + 'PUT', + `/groups/${groupId}/members.json`, + body, + ); + } + //https://docs.discourse.org/#tag/Groups/paths/~1groups~1{group_id}~1members.json/delete + if (operation === 'remove') { + const usernames = this.getNodeParameter('usernames', i) as string; + const groupId = this.getNodeParameter('groupId', i) as string; + const body: IDataObject = { + usernames, + }; - responseData = await discourseApiRequest.call( - this, - 'DELETE', - `/groups/${groupId}/members.json`, - body, - ); + responseData = await discourseApiRequest.call( + this, + 'DELETE', + `/groups/${groupId}/members.json`, + body, + ); + } } + if (Array.isArray(responseData)) { + returnData.push.apply(returnData, responseData as IDataObject[]); + } else if (responseData !== undefined) { + returnData.push(responseData as IDataObject); + } + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else if (responseData !== undefined) { - returnData.push(responseData as IDataObject); - } return [this.helpers.returnJsonArray(returnData)]; } } diff --git a/packages/nodes-base/nodes/Disqus/Disqus.node.ts b/packages/nodes-base/nodes/Disqus/Disqus.node.ts index dc92b80fb6..200cd3fe8a 100644 --- a/packages/nodes-base/nodes/Disqus/Disqus.node.ts +++ b/packages/nodes-base/nodes/Disqus/Disqus.node.ts @@ -647,136 +647,144 @@ export class Disqus implements INodeType { for (let i = 0; i < items.length; i++) { - body = {}; - qs = {}; + try { + body = {}; + qs = {}; - if (resource === 'forum') { - if (operation === 'get') { - // ---------------------------------- - // get - // ---------------------------------- + if (resource === 'forum') { + if (operation === 'get') { + // ---------------------------------- + // get + // ---------------------------------- - requestMethod = 'GET'; + requestMethod = 'GET'; - endpoint = 'forums/details.json'; + endpoint = 'forums/details.json'; - const id = this.getNodeParameter('id', i) as string; - qs.forum = id; + const id = this.getNodeParameter('id', i) as string; + qs.forum = id; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - Object.assign(qs, additionalFields); + Object.assign(qs, additionalFields); - try { - const responseData = await disqusApiRequest.call(this, requestMethod, qs, endpoint); - returnData.push(responseData.response); - } catch (error) { - throw error; - } - - } else if (operation === 'getPosts') { - // ---------------------------------- - // getPosts - // ---------------------------------- - - requestMethod = 'GET'; - - endpoint = 'forums/listPosts.json'; - - const id = this.getNodeParameter('id', i) as string; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - Object.assign(qs, additionalFields); - - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - - qs.forum = id; - qs.limit = 100; - - try { - let responseData: IDataObject = {}; - if(returnAll) { - responseData.response = await disqusApiRequestAllItems.call(this, requestMethod, qs, endpoint); - } else { - const limit = this.getNodeParameter('limit', i) as string; - qs.limit = limit; - responseData = await disqusApiRequest.call(this, requestMethod, qs, endpoint); + try { + const responseData = await disqusApiRequest.call(this, requestMethod, qs, endpoint); + returnData.push(responseData.response); + } catch (error) { + throw error; } - returnData.push.apply(returnData, responseData.response as IDataObject[]); - } catch (error) { - throw error; - } - } else if (operation === 'getCategories') { - // ---------------------------------- - // getCategories - // ---------------------------------- + } else if (operation === 'getPosts') { + // ---------------------------------- + // getPosts + // ---------------------------------- - requestMethod = 'GET'; + requestMethod = 'GET'; - endpoint = 'forums/listCategories.json'; + endpoint = 'forums/listPosts.json'; - const id = this.getNodeParameter('id', i) as string; - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - Object.assign(qs, additionalFields); + const id = this.getNodeParameter('id', i) as string; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + Object.assign(qs, additionalFields); - qs.forum = id; - qs.limit = 100; + const returnAll = this.getNodeParameter('returnAll', i) as boolean; - try { - let responseData: IDataObject = {}; + qs.forum = id; + qs.limit = 100; - if(returnAll) { - responseData.response = await disqusApiRequestAllItems.call(this, requestMethod, qs, endpoint); - } else { - const limit = this.getNodeParameter('limit', i) as string; - qs.limit = limit; - responseData = await disqusApiRequest.call(this, requestMethod, qs, endpoint) as IDataObject; + try { + let responseData: IDataObject = {}; + if(returnAll) { + responseData.response = await disqusApiRequestAllItems.call(this, requestMethod, qs, endpoint); + } else { + const limit = this.getNodeParameter('limit', i) as string; + qs.limit = limit; + responseData = await disqusApiRequest.call(this, requestMethod, qs, endpoint); + } + returnData.push.apply(returnData, responseData.response as IDataObject[]); + } catch (error) { + throw error; } - returnData.push.apply(returnData, responseData.response as IDataObject[]) ; - } catch (error) { - throw error; - } - } else if (operation === 'getThreads') { - // ---------------------------------- - // getThreads - // ---------------------------------- + } else if (operation === 'getCategories') { + // ---------------------------------- + // getCategories + // ---------------------------------- - requestMethod = 'GET'; + requestMethod = 'GET'; - endpoint = 'forums/listThreads.json'; + endpoint = 'forums/listCategories.json'; - const id = this.getNodeParameter('id', i) as string; - const returnAll = this.getNodeParameter('returnAll', i) as boolean; + const id = this.getNodeParameter('id', i) as string; + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + Object.assign(qs, additionalFields); - qs.forum = id; - qs.limit = 100; + qs.forum = id; + qs.limit = 100; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + try { + let responseData: IDataObject = {}; - Object.assign(qs, additionalFields); - - try { - let responseData: IDataObject = {}; - if(returnAll) { - responseData.response = await disqusApiRequestAllItems.call(this, requestMethod, qs, endpoint); - } else { - const limit = this.getNodeParameter('limit', i) as string; - qs.limit = limit; - responseData = await disqusApiRequest.call(this, requestMethod, qs, endpoint); + if(returnAll) { + responseData.response = await disqusApiRequestAllItems.call(this, requestMethod, qs, endpoint); + } else { + const limit = this.getNodeParameter('limit', i) as string; + qs.limit = limit; + responseData = await disqusApiRequest.call(this, requestMethod, qs, endpoint) as IDataObject; + } + returnData.push.apply(returnData, responseData.response as IDataObject[]) ; + } catch (error) { + throw error; } - returnData.push.apply(returnData, responseData.response as IDataObject[]); - } catch (error) { - throw error; + + } else if (operation === 'getThreads') { + // ---------------------------------- + // getThreads + // ---------------------------------- + + requestMethod = 'GET'; + + endpoint = 'forums/listThreads.json'; + + const id = this.getNodeParameter('id', i) as string; + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + + qs.forum = id; + qs.limit = 100; + + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + + Object.assign(qs, additionalFields); + + try { + let responseData: IDataObject = {}; + if(returnAll) { + responseData.response = await disqusApiRequestAllItems.call(this, requestMethod, qs, endpoint); + } else { + const limit = this.getNodeParameter('limit', i) as string; + qs.limit = limit; + responseData = await disqusApiRequest.call(this, requestMethod, qs, endpoint); + } + returnData.push.apply(returnData, responseData.response as IDataObject[]); + } catch (error) { + throw error; + } + + } else { + throw new NodeOperationError(this.getNode(), `The operation "${operation}" is not known!`); } } else { - throw new NodeOperationError(this.getNode(), `The operation "${operation}" is not known!`); + throw new NodeOperationError(this.getNode(), `The resource "${resource}" is not known!`); } - - } else { - throw new NodeOperationError(this.getNode(), `The resource "${resource}" is not known!`); + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } } diff --git a/packages/nodes-base/nodes/Drift/Drift.node.ts b/packages/nodes-base/nodes/Drift/Drift.node.ts index f91de68978..7c4d7a0718 100644 --- a/packages/nodes-base/nodes/Drift/Drift.node.ts +++ b/packages/nodes-base/nodes/Drift/Drift.node.ts @@ -102,62 +102,70 @@ export class Drift implements INodeType { 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 === 'contact') { - //https://devdocs.drift.com/docs/creating-a-contact - if (operation === 'create') { - const email = this.getNodeParameter('email', i) as string; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const body: IContact = { - email, - }; - if (additionalFields.name) { - body.name = additionalFields.name as string; + try { + if (resource === 'contact') { + //https://devdocs.drift.com/docs/creating-a-contact + if (operation === 'create') { + const email = this.getNodeParameter('email', i) as string; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const body: IContact = { + email, + }; + if (additionalFields.name) { + body.name = additionalFields.name as string; + } + if (additionalFields.phone) { + body.phone = additionalFields.phone as string; + } + responseData = await driftApiRequest.call(this, 'POST', '/contacts', { attributes: body }); + responseData = responseData.data; } - if (additionalFields.phone) { - body.phone = additionalFields.phone as string; + //https://devdocs.drift.com/docs/updating-a-contact + if (operation === 'update') { + const contactId = this.getNodeParameter('contactId', i) as string; + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + const body: IContact = {}; + if (updateFields.name) { + body.name = updateFields.name as string; + } + if (updateFields.phone) { + body.phone = updateFields.phone as string; + } + if (updateFields.email) { + body.email = updateFields.email as string; + } + responseData = await driftApiRequest.call(this, 'PATCH', `/contacts/${contactId}`, { attributes: body }); + responseData = responseData.data; } - responseData = await driftApiRequest.call(this, 'POST', '/contacts', { attributes: body }); - responseData = responseData.data; - } - //https://devdocs.drift.com/docs/updating-a-contact - if (operation === 'update') { - const contactId = this.getNodeParameter('contactId', i) as string; - const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; - const body: IContact = {}; - if (updateFields.name) { - body.name = updateFields.name as string; + //https://devdocs.drift.com/docs/retrieving-contact + if (operation === 'get') { + const contactId = this.getNodeParameter('contactId', i) as string; + responseData = await driftApiRequest.call(this, 'GET', `/contacts/${contactId}`); + responseData = responseData.data; } - if (updateFields.phone) { - body.phone = updateFields.phone as string; + //https://devdocs.drift.com/docs/listing-custom-attributes + if (operation === 'getCustomAttributes') { + responseData = await driftApiRequest.call(this, 'GET', '/contacts/attributes'); + responseData = responseData.data.properties; } - if (updateFields.email) { - body.email = updateFields.email as string; + //https://devdocs.drift.com/docs/removing-a-contact + if (operation === 'delete') { + const contactId = this.getNodeParameter('contactId', i) as string; + responseData = await driftApiRequest.call(this, 'DELETE', `/contacts/${contactId}`); + responseData = { success: true }; } - responseData = await driftApiRequest.call(this, 'PATCH', `/contacts/${contactId}`, { attributes: body }); - responseData = responseData.data; } - //https://devdocs.drift.com/docs/retrieving-contact - if (operation === 'get') { - const contactId = this.getNodeParameter('contactId', i) as string; - responseData = await driftApiRequest.call(this, 'GET', `/contacts/${contactId}`); - responseData = responseData.data; + if (Array.isArray(responseData)) { + returnData.push.apply(returnData, responseData as IDataObject[]); + } else { + returnData.push(responseData as IDataObject); } - //https://devdocs.drift.com/docs/listing-custom-attributes - if (operation === 'getCustomAttributes') { - responseData = await driftApiRequest.call(this, 'GET', '/contacts/attributes'); - responseData = responseData.data.properties; + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; } - //https://devdocs.drift.com/docs/removing-a-contact - if (operation === 'delete') { - const contactId = this.getNodeParameter('contactId', i) as string; - responseData = await driftApiRequest.call(this, 'DELETE', `/contacts/${contactId}`); - responseData = { success: true }; - } - } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else { - returnData.push(responseData as IDataObject); + throw error; } } return [this.helpers.returnJsonArray(returnData)]; diff --git a/packages/nodes-base/nodes/Dropbox/Dropbox.node.ts b/packages/nodes-base/nodes/Dropbox/Dropbox.node.ts index fcb3b2f7a5..383402e0ee 100644 --- a/packages/nodes-base/nodes/Dropbox/Dropbox.node.ts +++ b/packages/nodes-base/nodes/Dropbox/Dropbox.node.ts @@ -811,258 +811,270 @@ export class Dropbox implements INodeType { } for (let i = 0; i < items.length; i++) { - body = {}; + try { + body = {}; - if (resource === 'file') { - if (operation === 'download') { - // ---------------------------------- - // download - // ---------------------------------- + if (resource === 'file') { + if (operation === 'download') { + // ---------------------------------- + // download + // ---------------------------------- - requestMethod = 'POST'; + requestMethod = 'POST'; - query.arg = JSON.stringify({ - path: this.getNodeParameter('path', i) as string, - }); + query.arg = JSON.stringify({ + path: this.getNodeParameter('path', i) as string, + }); - endpoint = 'https://content.dropboxapi.com/2/files/download'; + endpoint = 'https://content.dropboxapi.com/2/files/download'; - } else if (operation === 'upload') { - // ---------------------------------- - // upload - // ---------------------------------- + } else if (operation === 'upload') { + // ---------------------------------- + // upload + // ---------------------------------- - requestMethod = 'POST'; - headers['Content-Type'] = 'application/octet-stream'; + requestMethod = 'POST'; + headers['Content-Type'] = 'application/octet-stream'; - query.arg = JSON.stringify({ - mode: 'overwrite', - path: this.getNodeParameter('path', i) as string, - }); + query.arg = JSON.stringify({ + mode: 'overwrite', + path: this.getNodeParameter('path', i) as string, + }); - endpoint = 'https://content.dropboxapi.com/2/files/upload'; + endpoint = 'https://content.dropboxapi.com/2/files/upload'; - options = { json: false }; + options = { json: false }; - if (this.getNodeParameter('binaryData', i) === true) { + if (this.getNodeParameter('binaryData', i) === true) { - // Is binary file to upload - const item = items[i]; + // Is binary file to upload + const item = items[i]; - if (item.binary === undefined) { - throw new NodeOperationError(this.getNode(), 'No binary data exists on item!'); - } + if (item.binary === undefined) { + throw new NodeOperationError(this.getNode(), 'No binary data exists on item!'); + } - const propertyNameUpload = this.getNodeParameter('binaryPropertyName', i) as string; + const propertyNameUpload = this.getNodeParameter('binaryPropertyName', i) as string; - if (item.binary[propertyNameUpload] === undefined) { - throw new NodeOperationError(this.getNode(), `No binary data property "${propertyNameUpload}" does not exists on item!`); - } + if (item.binary[propertyNameUpload] === undefined) { + throw new NodeOperationError(this.getNode(), `No binary data property "${propertyNameUpload}" does not exists on item!`); + } - body = Buffer.from(item.binary[propertyNameUpload].data, BINARY_ENCODING); - } else { - // Is text file - body = Buffer.from(this.getNodeParameter('fileContent', i) as string, 'utf8'); - } - } - } else if (resource === 'folder') { - if (operation === 'create') { - // ---------------------------------- - // create - // ---------------------------------- - - requestMethod = 'POST'; - body = { - path: this.getNodeParameter('path', i) as string, - }; - - endpoint = 'https://api.dropboxapi.com/2/files/create_folder_v2'; - - } else if (operation === 'list') { - // ---------------------------------- - // list - // ---------------------------------- - - returnAll = this.getNodeParameter('returnAll', 0) as boolean; - - const filters = this.getNodeParameter('filters', i) as IDataObject; - - property = 'entries'; - - requestMethod = 'POST'; - body = { - path: this.getNodeParameter('path', i) as string, - limit: 1000, - }; - - if (returnAll === false) { - const limit = this.getNodeParameter('limit', 0) as number; - body.limit = limit; - } - - Object.assign(body, filters); - - endpoint = 'https://api.dropboxapi.com/2/files/list_folder'; - - } - } else if (resource === 'search') { - if (operation === 'query') { - // ---------------------------------- - // query - // ---------------------------------- - - returnAll = this.getNodeParameter('returnAll', 0) as boolean; - - simple = this.getNodeParameter('simple', 0) as boolean; - - const filters = this.getNodeParameter('filters', i) as IDataObject; - - property = 'matches'; - - requestMethod = 'POST'; - body = { - query: this.getNodeParameter('query', i) as string, - options: { - filename_only: true, - }, - }; - - if (filters.file_extensions) { - filters.file_extensions = (filters.file_extensions as string).split(','); - } - - Object.assign(body.options, filters); - - if (returnAll === false) { - const limit = this.getNodeParameter('limit', i) as number; - Object.assign(body.options, { max_results: limit }); - } - - endpoint = 'https://api.dropboxapi.com/2/files/search_v2'; - } - } - if (['file', 'folder', 'search'].includes(resource)) { - if (operation === 'copy') { - // ---------------------------------- - // copy - // ---------------------------------- - - requestMethod = 'POST'; - body = { - from_path: this.getNodeParameter('path', i) as string, - to_path: this.getNodeParameter('toPath', i) as string, - }; - - endpoint = 'https://api.dropboxapi.com/2/files/copy_v2'; - - } else if (operation === 'delete') { - // ---------------------------------- - // delete - // ---------------------------------- - - requestMethod = 'POST'; - body = { - path: this.getNodeParameter('path', i) as string, - }; - - endpoint = 'https://api.dropboxapi.com/2/files/delete_v2'; - - } else if (operation === 'move') { - // ---------------------------------- - // move - // ---------------------------------- - - requestMethod = 'POST'; - body = { - from_path: this.getNodeParameter('path', i) as string, - to_path: this.getNodeParameter('toPath', i) as string, - }; - - endpoint = 'https://api.dropboxapi.com/2/files/move_v2'; - } - } else { - throw new NodeOperationError(this.getNode(), `The resource "${resource}" is not known!`); - } - - if (resource === 'file' && operation === 'download') { - // Return the data as a buffer - options = { encoding: null }; - } - - let responseData; - - if (returnAll === true) { - responseData = await dropboxpiRequestAllItems.call(this, property, requestMethod, endpoint, body, query, headers); - } else { - responseData = await dropboxApiRequest.call(this, requestMethod, endpoint, body, query, headers, options); - } - - if (resource === 'file' && operation === 'upload') { - responseData = JSON.parse(responseData); - } - - if (resource === 'file' && operation === 'download') { - - const newItem: INodeExecutionData = { - json: items[i].json, - binary: {}, - }; - - if (items[i].binary !== undefined) { - // Create a shallow copy of the binary data so that the old - // data references which do not get changed still stay behind - // but the incoming data does not get changed. - Object.assign(newItem.binary, items[i].binary); - } - - items[i] = newItem; - - const dataPropertyNameDownload = this.getNodeParameter('binaryPropertyName', i) as string; - - const filePathDownload = this.getNodeParameter('path', i) as string; - items[i].binary![dataPropertyNameDownload] = await this.helpers.prepareBinaryData(Buffer.from(responseData), filePathDownload); - - } else if (resource === 'folder' && operation === 'list') { - - const propNames: { [key: string]: string } = { - 'id': 'id', - 'name': 'name', - 'client_modified': 'lastModifiedClient', - 'server_modified': 'lastModifiedServer', - 'rev': 'rev', - 'size': 'contentSize', - '.tag': 'type', - 'content_hash': 'contentHash', - 'path_lower': 'pathLower', - 'path_display': 'pathDisplay', - 'has_explicit_shared_members': 'hasExplicitSharedMembers', - 'is_downloadable': 'isDownloadable', - }; - - if (returnAll === false) { - responseData = responseData.entries; - } - - for (const item of responseData) { - const newItem: IDataObject = {}; - - // Get the props and save them under a proper name - for (const propName of Object.keys(propNames)) { - if (item[propName] !== undefined) { - newItem[propNames[propName]] = item[propName]; + body = Buffer.from(item.binary[propertyNameUpload].data, BINARY_ENCODING); + } else { + // Is text file + body = Buffer.from(this.getNodeParameter('fileContent', i) as string, 'utf8'); } } + } else if (resource === 'folder') { + if (operation === 'create') { + // ---------------------------------- + // create + // ---------------------------------- - returnData.push(newItem as IDataObject); + requestMethod = 'POST'; + body = { + path: this.getNodeParameter('path', i) as string, + }; + + endpoint = 'https://api.dropboxapi.com/2/files/create_folder_v2'; + + } else if (operation === 'list') { + // ---------------------------------- + // list + // ---------------------------------- + + returnAll = this.getNodeParameter('returnAll', 0) as boolean; + + const filters = this.getNodeParameter('filters', i) as IDataObject; + + property = 'entries'; + + requestMethod = 'POST'; + body = { + path: this.getNodeParameter('path', i) as string, + limit: 1000, + }; + + if (returnAll === false) { + const limit = this.getNodeParameter('limit', 0) as number; + body.limit = limit; + } + + Object.assign(body, filters); + + endpoint = 'https://api.dropboxapi.com/2/files/list_folder'; + + } + } else if (resource === 'search') { + if (operation === 'query') { + // ---------------------------------- + // query + // ---------------------------------- + + returnAll = this.getNodeParameter('returnAll', 0) as boolean; + + simple = this.getNodeParameter('simple', 0) as boolean; + + const filters = this.getNodeParameter('filters', i) as IDataObject; + + property = 'matches'; + + requestMethod = 'POST'; + body = { + query: this.getNodeParameter('query', i) as string, + options: { + filename_only: true, + }, + }; + + if (filters.file_extensions) { + filters.file_extensions = (filters.file_extensions as string).split(','); + } + + Object.assign(body.options, filters); + + if (returnAll === false) { + const limit = this.getNodeParameter('limit', i) as number; + Object.assign(body.options, { max_results: limit }); + } + + endpoint = 'https://api.dropboxapi.com/2/files/search_v2'; + } } - } else if (resource === 'search' && operation === 'query') { - if (returnAll === true) { - returnData.push.apply(returnData, (simple === true) ? simplify(responseData) : responseData); + if (['file', 'folder', 'search'].includes(resource)) { + if (operation === 'copy') { + // ---------------------------------- + // copy + // ---------------------------------- + + requestMethod = 'POST'; + body = { + from_path: this.getNodeParameter('path', i) as string, + to_path: this.getNodeParameter('toPath', i) as string, + }; + + endpoint = 'https://api.dropboxapi.com/2/files/copy_v2'; + + } else if (operation === 'delete') { + // ---------------------------------- + // delete + // ---------------------------------- + + requestMethod = 'POST'; + body = { + path: this.getNodeParameter('path', i) as string, + }; + + endpoint = 'https://api.dropboxapi.com/2/files/delete_v2'; + + } else if (operation === 'move') { + // ---------------------------------- + // move + // ---------------------------------- + + requestMethod = 'POST'; + body = { + from_path: this.getNodeParameter('path', i) as string, + to_path: this.getNodeParameter('toPath', i) as string, + }; + + endpoint = 'https://api.dropboxapi.com/2/files/move_v2'; + } } else { - returnData.push.apply(returnData, (simple === true) ? simplify(responseData[property]) : responseData[property]); + throw new NodeOperationError(this.getNode(), `The resource "${resource}" is not known!`); } - } else { - returnData.push(responseData); + + if (resource === 'file' && operation === 'download') { + // Return the data as a buffer + options = { encoding: null }; + } + + let responseData; + + if (returnAll === true) { + responseData = await dropboxpiRequestAllItems.call(this, property, requestMethod, endpoint, body, query, headers); + } else { + responseData = await dropboxApiRequest.call(this, requestMethod, endpoint, body, query, headers, options); + } + + if (resource === 'file' && operation === 'upload') { + responseData = JSON.parse(responseData); + } + + if (resource === 'file' && operation === 'download') { + + const newItem: INodeExecutionData = { + json: items[i].json, + binary: {}, + }; + + if (items[i].binary !== undefined) { + // Create a shallow copy of the binary data so that the old + // data references which do not get changed still stay behind + // but the incoming data does not get changed. + Object.assign(newItem.binary, items[i].binary); + } + + items[i] = newItem; + + const dataPropertyNameDownload = this.getNodeParameter('binaryPropertyName', i) as string; + + const filePathDownload = this.getNodeParameter('path', i) as string; + items[i].binary![dataPropertyNameDownload] = await this.helpers.prepareBinaryData(Buffer.from(responseData), filePathDownload); + + } else if (resource === 'folder' && operation === 'list') { + + const propNames: { [key: string]: string } = { + 'id': 'id', + 'name': 'name', + 'client_modified': 'lastModifiedClient', + 'server_modified': 'lastModifiedServer', + 'rev': 'rev', + 'size': 'contentSize', + '.tag': 'type', + 'content_hash': 'contentHash', + 'path_lower': 'pathLower', + 'path_display': 'pathDisplay', + 'has_explicit_shared_members': 'hasExplicitSharedMembers', + 'is_downloadable': 'isDownloadable', + }; + + if (returnAll === false) { + responseData = responseData.entries; + } + + for (const item of responseData) { + const newItem: IDataObject = {}; + + // Get the props and save them under a proper name + for (const propName of Object.keys(propNames)) { + if (item[propName] !== undefined) { + newItem[propNames[propName]] = item[propName]; + } + } + + returnData.push(newItem as IDataObject); + } + } else if (resource === 'search' && operation === 'query') { + if (returnAll === true) { + returnData.push.apply(returnData, (simple === true) ? simplify(responseData) : responseData); + } else { + returnData.push.apply(returnData, (simple === true) ? simplify(responseData[property]) : responseData[property]); + } + } else { + returnData.push(responseData); + } + } catch (error) { + if (this.continueOnFail()) { + if (resource === 'file' && operation === 'download'){ + items[i].json = { error: error.message }; + }else{ + returnData.push({ error: error.message }); + } + continue; + } + throw error; } } diff --git a/packages/nodes-base/nodes/EditImage.node.ts b/packages/nodes-base/nodes/EditImage.node.ts index f23f42bb7b..a8add5a351 100644 --- a/packages/nodes-base/nodes/EditImage.node.ts +++ b/packages/nodes-base/nodes/EditImage.node.ts @@ -957,292 +957,302 @@ export class EditImage implements INodeType { let item: INodeExecutionData; for (let itemIndex = 0; itemIndex < length; itemIndex++) { - item = items[itemIndex]; + + try { + + item = items[itemIndex]; - const operation = this.getNodeParameter('operation', itemIndex) as string; - const dataPropertyName = this.getNodeParameter('dataPropertyName', itemIndex) as string; + const operation = this.getNodeParameter('operation', itemIndex) as string; + const dataPropertyName = this.getNodeParameter('dataPropertyName', itemIndex) as string; - const options = this.getNodeParameter('options', itemIndex,{}) as IDataObject; + const options = this.getNodeParameter('options', itemIndex,{}) as IDataObject; - const cleanupFunctions: Array<() => void> = []; + const cleanupFunctions: Array<() => void> = []; - let gmInstance: gm.State; + let gmInstance: gm.State; - const requiredOperationParameters: { - [key: string]: string[], - } = { - blur: [ - 'blur', - 'sigma', - ], - border: [ - 'borderColor', - 'borderWidth', - 'borderHeight', - ], - create: [ - 'backgroundColor', - 'height', - 'width', - ], - crop: [ - 'height', - 'positionX', - 'positionY', - 'width', - ], - composite: [ - 'dataPropertyNameComposite', - 'positionX', - 'positionY', - ], - draw: [ - 'color', - 'cornerRadius', - 'endPositionX', - 'endPositionY', - 'primitive', - 'startPositionX', - 'startPositionY', - ], - information: [], - resize: [ - 'height', - 'resizeOption', - 'width', - ], - rotate: [ - 'backgroundColor', - 'rotate', - ], - shear: [ - 'degreesX', - 'degreesY', - ], - text: [ - 'font', - 'fontColor', - 'fontSize', - 'lineLength', - 'positionX', - 'positionY', - 'text', - ], - }; + const requiredOperationParameters: { + [key: string]: string[], + } = { + blur: [ + 'blur', + 'sigma', + ], + border: [ + 'borderColor', + 'borderWidth', + 'borderHeight', + ], + create: [ + 'backgroundColor', + 'height', + 'width', + ], + crop: [ + 'height', + 'positionX', + 'positionY', + 'width', + ], + composite: [ + 'dataPropertyNameComposite', + 'positionX', + 'positionY', + ], + draw: [ + 'color', + 'cornerRadius', + 'endPositionX', + 'endPositionY', + 'primitive', + 'startPositionX', + 'startPositionY', + ], + information: [], + resize: [ + 'height', + 'resizeOption', + 'width', + ], + rotate: [ + 'backgroundColor', + 'rotate', + ], + shear: [ + 'degreesX', + 'degreesY', + ], + text: [ + 'font', + 'fontColor', + 'fontSize', + 'lineLength', + 'positionX', + 'positionY', + 'text', + ], + }; - let operations: IDataObject[] = []; - if (operation === 'multiStep') { - // Operation parameters are already in the correct format - const operationsData = this.getNodeParameter('operations', itemIndex ,{ operations: [] }) as IDataObject; - operations = operationsData.operations as IDataObject[]; - } else { - // Operation parameters have to first get collected - const operationParameters: IDataObject = {}; - requiredOperationParameters[operation].forEach(parameterName => { - try { - operationParameters[parameterName] = this.getNodeParameter(parameterName, itemIndex); - } catch (error) {} - }); - - operations = [ - { - operation, - ...operationParameters, - }, - ]; - } - - if (operations[0].operation !== 'create') { - // "create" generates a new image so does not require any incoming data. - if (item.binary === undefined) { - throw new NodeOperationError(this.getNode(), 'Item does not contain any binary data.'); - } - - if (item.binary[dataPropertyName as string] === undefined) { - throw new NodeOperationError(this.getNode(), `Item does not contain any binary data with the name "${dataPropertyName}".`); - } - - gmInstance = gm(Buffer.from(item.binary![dataPropertyName as string].data, BINARY_ENCODING)); - gmInstance = gmInstance.background('transparent'); - } - - if (operation === 'information') { - // Just return the information - const imageData = await new Promise((resolve, reject) => { - gmInstance = gmInstance.identify((error, imageData) => { - if (error) { - reject(error); - return; - } - resolve(imageData as unknown as IDataObject); + let operations: IDataObject[] = []; + if (operation === 'multiStep') { + // Operation parameters are already in the correct format + const operationsData = this.getNodeParameter('operations', itemIndex ,{ operations: [] }) as IDataObject; + operations = operationsData.operations as IDataObject[]; + } else { + // Operation parameters have to first get collected + const operationParameters: IDataObject = {}; + requiredOperationParameters[operation].forEach(parameterName => { + try { + operationParameters[parameterName] = this.getNodeParameter(parameterName, itemIndex); + } catch (error) {} }); - }); - item.json = imageData; - returnData.push(item); - } + operations = [ + { + operation, + ...operationParameters, + }, + ]; + } - for (let i = 0; i < operations.length; i++) { - const operationData = operations[i]; - if (operationData.operation === 'blur') { - gmInstance = gmInstance!.blur(operationData.blur as number, operationData.sigma as number); - } else if (operationData.operation === 'border') { - gmInstance = gmInstance!.borderColor(operationData.borderColor as string).border(operationData.borderWidth as number, operationData.borderHeight as number); - } else if (operationData.operation === 'composite') { - const positionX = operationData.positionX as number; - const positionY = operationData.positionY as number; - - const geometryString = (positionX >= 0 ? '+' : '') + positionX + (positionY >= 0 ? '+' : '') + positionY; - - if (item.binary![operationData.dataPropertyNameComposite as string] === undefined) { - throw new NodeOperationError(this.getNode(), `Item does not contain any binary data with the name "${operationData.dataPropertyNameComposite}".`); + if (operations[0].operation !== 'create') { + // "create" generates a new image so does not require any incoming data. + if (item.binary === undefined) { + throw new NodeOperationError(this.getNode(), 'Item does not contain any binary data.'); } - const { fd, path, cleanup } = await file(); - cleanupFunctions.push(cleanup); - await fsWriteFileAsync(fd, Buffer.from(item.binary![operationData.dataPropertyNameComposite as string].data, BINARY_ENCODING)); - - if (operations[0].operation === 'create') { - // It seems like if the image gets created newly we have to create a new gm instance - // else it fails for some reason - gmInstance = gm(gmInstance!.stream('png')).geometry(geometryString).composite(path); - } else { - gmInstance = gmInstance!.geometry(geometryString).composite(path); + if (item.binary[dataPropertyName as string] === undefined) { + throw new NodeOperationError(this.getNode(), `Item does not contain any binary data with the name "${dataPropertyName}".`); } - if (operations.length !== i + 1) { - // If there are other operations after the current one create a new gm instance - // because else things do get messed up - gmInstance = gm(gmInstance.stream()); - } - } else if (operationData.operation === 'create') { - gmInstance = gm(operationData.width as number, operationData.height as number, operationData.backgroundColor as string); - if (!options.format) { - options.format = 'png'; - } - } else if (operationData.operation === 'crop') { - gmInstance = gmInstance!.crop(operationData.width as number, operationData.height as number, operationData.positionX as number, operationData.positionY as number); - } else if (operationData.operation === 'draw') { - gmInstance = gmInstance!.fill(operationData.color as string); + gmInstance = gm(Buffer.from(item.binary![dataPropertyName as string].data, BINARY_ENCODING)); + gmInstance = gmInstance.background('transparent'); + } - if (operationData.primitive === 'line') { - gmInstance = gmInstance.drawLine(operationData.startPositionX as number, operationData.startPositionY as number, operationData.endPositionX as number, operationData.endPositionY as number); - } else if (operationData.primitive === 'rectangle') { - gmInstance = gmInstance.drawRectangle(operationData.startPositionX as number, operationData.startPositionY as number, operationData.endPositionX as number, operationData.endPositionY as number, operationData.cornerRadius as number || undefined); - } - } else if (operationData.operation === 'resize') { - const resizeOption = operationData.resizeOption as string; - - // By default use "maximumArea" - let option: gm.ResizeOption = '@'; - if (resizeOption === 'ignoreAspectRatio') { - option = '!'; - } else if (resizeOption === 'minimumArea') { - option = '^'; - } else if (resizeOption === 'onlyIfSmaller') { - option = '<'; - } else if (resizeOption === 'onlyIfLarger') { - option = '>'; - } else if (resizeOption === 'percent') { - option = '%'; - } - - gmInstance = gmInstance!.resize(operationData.width as number, operationData.height as number, option); - } else if (operationData.operation === 'rotate') { - gmInstance = gmInstance!.rotate(operationData.backgroundColor as string, operationData.rotate as number); - } else if (operationData.operation === 'shear') { - gmInstance = gmInstance!.shear(operationData.degreesX as number, operationData.degreesY as number); - } else if (operationData.operation === 'text') { - // Split the text in multiple lines - const lines: string[] = []; - let currentLine = ''; - (operationData.text as string).split('\n').forEach((textLine: string) => { - textLine.split(' ').forEach((textPart: string) => { - if ((currentLine.length + textPart.length + 1) > (operationData.lineLength as number)) { - lines.push(currentLine.trim()); - currentLine = `${textPart} `; + if (operation === 'information') { + // Just return the information + const imageData = await new Promise((resolve, reject) => { + gmInstance = gmInstance.identify((error, imageData) => { + if (error) { + reject(error); return; } - currentLine += `${textPart} `; + resolve(imageData as unknown as IDataObject); }); - - lines.push(currentLine.trim()); - currentLine = ''; }); - // Combine the lines to a single string - const renderText = lines.join('\n'); - - const font = options.font || operationData.font; - - if (font && font !== 'default') { - gmInstance = gmInstance!.font(font as string); - } - - gmInstance = gmInstance! - .fill(operationData.fontColor as string) - .fontSize(operationData.fontSize as number) - .drawText(operationData.positionX as number, operationData.positionY as number, renderText); + item.json = imageData; + returnData.push(item); } - } - const newItem: INodeExecutionData = { - json: item.json, - binary: {}, - }; + for (let i = 0; i < operations.length; i++) { + const operationData = operations[i]; + if (operationData.operation === 'blur') { + gmInstance = gmInstance!.blur(operationData.blur as number, operationData.sigma as number); + } else if (operationData.operation === 'border') { + gmInstance = gmInstance!.borderColor(operationData.borderColor as string).border(operationData.borderWidth as number, operationData.borderHeight as number); + } else if (operationData.operation === 'composite') { + const positionX = operationData.positionX as number; + const positionY = operationData.positionY as number; - if (item.binary !== undefined) { - // Create a shallow copy of the binary data so that the old - // data references which do not get changed still stay behind - // but the incoming data does not get changed. - Object.assign(newItem.binary, item.binary); - // Make a deep copy of the binary data we change - if (newItem.binary![dataPropertyName as string]) { - newItem.binary![dataPropertyName as string] = JSON.parse(JSON.stringify(newItem.binary![dataPropertyName as string])); - } - } + const geometryString = (positionX >= 0 ? '+' : '') + positionX + (positionY >= 0 ? '+' : '') + positionY; - if (newItem.binary![dataPropertyName as string] === undefined) { - newItem.binary![dataPropertyName as string] = { - data: '', - mimeType: '', - }; - } - - if (options.quality !== undefined) { - gmInstance = gmInstance!.quality(options.quality as number); - } - - if (options.format !== undefined) { - gmInstance = gmInstance!.setFormat(options.format as string); - newItem.binary![dataPropertyName as string].fileExtension = options.format as string; - newItem.binary![dataPropertyName as string].mimeType = `image/${options.format}`; - const fileName = newItem.binary![dataPropertyName as string].fileName; - if (fileName && fileName.includes('.')) { - newItem.binary![dataPropertyName as string].fileName = fileName.split('.').slice(0, -1).join('.') + '.' + options.format; - } - } - - if (options.fileName !== undefined) { - newItem.binary![dataPropertyName as string].fileName = options.fileName as string; - } - - returnData.push(await (new Promise((resolve, reject) => { - gmInstance - .toBuffer((error: Error | null, buffer: Buffer) => { - cleanupFunctions.forEach(async cleanup => await cleanup()); - - if (error) { - return reject(error); + if (item.binary![operationData.dataPropertyNameComposite as string] === undefined) { + throw new NodeOperationError(this.getNode(), `Item does not contain any binary data with the name "${operationData.dataPropertyNameComposite}".`); } - newItem.binary![dataPropertyName as string].data = buffer.toString(BINARY_ENCODING); + const { fd, path, cleanup } = await file(); + cleanupFunctions.push(cleanup); + await fsWriteFileAsync(fd, Buffer.from(item.binary![operationData.dataPropertyNameComposite as string].data, BINARY_ENCODING)); - return resolve(newItem); - }); - }))); + if (operations[0].operation === 'create') { + // It seems like if the image gets created newly we have to create a new gm instance + // else it fails for some reason + gmInstance = gm(gmInstance!.stream('png')).geometry(geometryString).composite(path); + } else { + gmInstance = gmInstance!.geometry(geometryString).composite(path); + } + if (operations.length !== i + 1) { + // If there are other operations after the current one create a new gm instance + // because else things do get messed up + gmInstance = gm(gmInstance.stream()); + } + } else if (operationData.operation === 'create') { + gmInstance = gm(operationData.width as number, operationData.height as number, operationData.backgroundColor as string); + if (!options.format) { + options.format = 'png'; + } + } else if (operationData.operation === 'crop') { + gmInstance = gmInstance!.crop(operationData.width as number, operationData.height as number, operationData.positionX as number, operationData.positionY as number); + } else if (operationData.operation === 'draw') { + gmInstance = gmInstance!.fill(operationData.color as string); + + if (operationData.primitive === 'line') { + gmInstance = gmInstance.drawLine(operationData.startPositionX as number, operationData.startPositionY as number, operationData.endPositionX as number, operationData.endPositionY as number); + } else if (operationData.primitive === 'rectangle') { + gmInstance = gmInstance.drawRectangle(operationData.startPositionX as number, operationData.startPositionY as number, operationData.endPositionX as number, operationData.endPositionY as number, operationData.cornerRadius as number || undefined); + } + } else if (operationData.operation === 'resize') { + const resizeOption = operationData.resizeOption as string; + + // By default use "maximumArea" + let option: gm.ResizeOption = '@'; + if (resizeOption === 'ignoreAspectRatio') { + option = '!'; + } else if (resizeOption === 'minimumArea') { + option = '^'; + } else if (resizeOption === 'onlyIfSmaller') { + option = '<'; + } else if (resizeOption === 'onlyIfLarger') { + option = '>'; + } else if (resizeOption === 'percent') { + option = '%'; + } + + gmInstance = gmInstance!.resize(operationData.width as number, operationData.height as number, option); + } else if (operationData.operation === 'rotate') { + gmInstance = gmInstance!.rotate(operationData.backgroundColor as string, operationData.rotate as number); + } else if (operationData.operation === 'shear') { + gmInstance = gmInstance!.shear(operationData.degreesX as number, operationData.degreesY as number); + } else if (operationData.operation === 'text') { + // Split the text in multiple lines + const lines: string[] = []; + let currentLine = ''; + (operationData.text as string).split('\n').forEach((textLine: string) => { + textLine.split(' ').forEach((textPart: string) => { + if ((currentLine.length + textPart.length + 1) > (operationData.lineLength as number)) { + lines.push(currentLine.trim()); + currentLine = `${textPart} `; + return; + } + currentLine += `${textPart} `; + }); + + lines.push(currentLine.trim()); + currentLine = ''; + }); + + // Combine the lines to a single string + const renderText = lines.join('\n'); + + const font = options.font || operationData.font; + + if (font && font !== 'default') { + gmInstance = gmInstance!.font(font as string); + } + + gmInstance = gmInstance! + .fill(operationData.fontColor as string) + .fontSize(operationData.fontSize as number) + .drawText(operationData.positionX as number, operationData.positionY as number, renderText); + } + } + + const newItem: INodeExecutionData = { + json: item.json, + binary: {}, + }; + + if (item.binary !== undefined) { + // Create a shallow copy of the binary data so that the old + // data references which do not get changed still stay behind + // but the incoming data does not get changed. + Object.assign(newItem.binary, item.binary); + // Make a deep copy of the binary data we change + if (newItem.binary![dataPropertyName as string]) { + newItem.binary![dataPropertyName as string] = JSON.parse(JSON.stringify(newItem.binary![dataPropertyName as string])); + } + } + + if (newItem.binary![dataPropertyName as string] === undefined) { + newItem.binary![dataPropertyName as string] = { + data: '', + mimeType: '', + }; + } + + if (options.quality !== undefined) { + gmInstance = gmInstance!.quality(options.quality as number); + } + + if (options.format !== undefined) { + gmInstance = gmInstance!.setFormat(options.format as string); + newItem.binary![dataPropertyName as string].fileExtension = options.format as string; + newItem.binary![dataPropertyName as string].mimeType = `image/${options.format}`; + const fileName = newItem.binary![dataPropertyName as string].fileName; + if (fileName && fileName.includes('.')) { + newItem.binary![dataPropertyName as string].fileName = fileName.split('.').slice(0, -1).join('.') + '.' + options.format; + } + } + + if (options.fileName !== undefined) { + newItem.binary![dataPropertyName as string].fileName = options.fileName as string; + } + + returnData.push(await (new Promise((resolve, reject) => { + gmInstance + .toBuffer((error: Error | null, buffer: Buffer) => { + cleanupFunctions.forEach(async cleanup => await cleanup()); + + if (error) { + return reject(error); + } + + newItem.binary![dataPropertyName as string].data = buffer.toString(BINARY_ENCODING); + + return resolve(newItem); + }); + }))); + + } catch (error) { + if (this.continueOnFail()) { + returnData.push({json:{ error: error.message }}); + continue; + } + throw error; + } } return this.prepareOutputData(returnData); } diff --git a/packages/nodes-base/nodes/EmailSend.node.ts b/packages/nodes-base/nodes/EmailSend.node.ts index bceb617006..701f42c912 100644 --- a/packages/nodes-base/nodes/EmailSend.node.ts +++ b/packages/nodes-base/nodes/EmailSend.node.ts @@ -133,84 +133,93 @@ export class EmailSend implements INodeType { let item: INodeExecutionData; for (let itemIndex = 0; itemIndex < length; itemIndex++) { + try { - item = items[itemIndex]; + item = items[itemIndex]; - const fromEmail = this.getNodeParameter('fromEmail', itemIndex) as string; - const toEmail = this.getNodeParameter('toEmail', itemIndex) as string; - const ccEmail = this.getNodeParameter('ccEmail', itemIndex) as string; - const bccEmail = this.getNodeParameter('bccEmail', itemIndex) as string; - const subject = this.getNodeParameter('subject', itemIndex) as string; - const text = this.getNodeParameter('text', itemIndex) as string; - const html = this.getNodeParameter('html', itemIndex) as string; - const attachmentPropertyString = this.getNodeParameter('attachments', itemIndex) as string; - const options = this.getNodeParameter('options', itemIndex, {}) as IDataObject; + const fromEmail = this.getNodeParameter('fromEmail', itemIndex) as string; + const toEmail = this.getNodeParameter('toEmail', itemIndex) as string; + const ccEmail = this.getNodeParameter('ccEmail', itemIndex) as string; + const bccEmail = this.getNodeParameter('bccEmail', itemIndex) as string; + const subject = this.getNodeParameter('subject', itemIndex) as string; + const text = this.getNodeParameter('text', itemIndex) as string; + const html = this.getNodeParameter('html', itemIndex) as string; + const attachmentPropertyString = this.getNodeParameter('attachments', itemIndex) as string; + const options = this.getNodeParameter('options', itemIndex, {}) as IDataObject; - const credentials = this.getCredentials('smtp'); + const credentials = this.getCredentials('smtp'); - if (credentials === undefined) { - throw new NodeOperationError(this.getNode(), 'No credentials got returned!'); - } - - const connectionOptions: SMTPTransport.Options = { - host: credentials.host as string, - port: credentials.port as number, - secure: credentials.secure as boolean, - }; - - if (credentials.user || credentials.password) { - // @ts-ignore - connectionOptions.auth = { - user: credentials.user as string, - pass: credentials.password as string, - }; - } - - if (options.allowUnauthorizedCerts === true) { - connectionOptions.tls = { - rejectUnauthorized: false, - }; - } - - const transporter = createTransport(connectionOptions); - - // setup email data with unicode symbols - const mailOptions = { - from: fromEmail, - to: toEmail, - cc: ccEmail, - bcc: bccEmail, - subject, - text, - html, - }; - - if (attachmentPropertyString && item.binary) { - const attachments = []; - const attachmentProperties: string[] = attachmentPropertyString.split(',').map((propertyName) => { - return propertyName.trim(); - }); - - for (const propertyName of attachmentProperties) { - if (!item.binary.hasOwnProperty(propertyName)) { - continue; - } - attachments.push({ - filename: item.binary[propertyName].fileName || 'unknown', - content: Buffer.from(item.binary[propertyName].data, BINARY_ENCODING), - }); + if (credentials === undefined) { + throw new NodeOperationError(this.getNode(), 'No credentials got returned!'); } - if (attachments.length) { + const connectionOptions: SMTPTransport.Options = { + host: credentials.host as string, + port: credentials.port as number, + secure: credentials.secure as boolean, + }; + + if (credentials.user || credentials.password) { // @ts-ignore - mailOptions.attachments = attachments; + connectionOptions.auth = { + user: credentials.user as string, + pass: credentials.password as string, + }; } + + if (options.allowUnauthorizedCerts === true) { + connectionOptions.tls = { + rejectUnauthorized: false, + }; + } + + const transporter = createTransport(connectionOptions); + + // setup email data with unicode symbols + const mailOptions = { + from: fromEmail, + to: toEmail, + cc: ccEmail, + bcc: bccEmail, + subject, + text, + html, + }; + + if (attachmentPropertyString && item.binary) { + const attachments = []; + const attachmentProperties: string[] = attachmentPropertyString.split(',').map((propertyName) => { + return propertyName.trim(); + }); + + for (const propertyName of attachmentProperties) { + if (!item.binary.hasOwnProperty(propertyName)) { + continue; + } + attachments.push({ + filename: item.binary[propertyName].fileName || 'unknown', + content: Buffer.from(item.binary[propertyName].data, BINARY_ENCODING), + }); + } + + if (attachments.length) { + // @ts-ignore + mailOptions.attachments = attachments; + } + } + + // Send the email + const info = await transporter.sendMail(mailOptions); + + returnData.push({ json: info as unknown as IDataObject }); + + }catch (error) { + if (this.continueOnFail()) { + returnData.push({json:{ error: error.message }}); + continue; + } + throw error; } - - // Send the email - const info = await transporter.sendMail(mailOptions); - - returnData.push({ json: info as unknown as IDataObject }); } return this.prepareOutputData(returnData); diff --git a/packages/nodes-base/nodes/ExecuteCommand.node.ts b/packages/nodes-base/nodes/ExecuteCommand.node.ts index acf72d9dc7..3ea81c8936 100644 --- a/packages/nodes-base/nodes/ExecuteCommand.node.ts +++ b/packages/nodes-base/nodes/ExecuteCommand.node.ts @@ -3,6 +3,7 @@ import { INodeExecutionData, INodeType, INodeTypeDescription, + NodeOperationError } from 'n8n-workflow'; import { exec } from 'child_process'; @@ -24,6 +25,7 @@ export interface IExecReturnData { */ function execPromise(command: string): Promise { const returnData: IExecReturnData = { + error: undefined, exitCode: 0, stderr: '', stdout: '', @@ -94,24 +96,39 @@ export class ExecuteCommand implements INodeType { const returnItems: INodeExecutionData[] = []; for (let itemIndex = 0; itemIndex < items.length; itemIndex++) { - command = this.getNodeParameter('command', itemIndex) as string; - const { - // error, TODO: Later make it possible to select if it should fail on error or not - exitCode, - stdout, - stderr, - } = await execPromise(command); + try{ - returnItems.push( - { - json: { - exitCode, - stderr, - stdout, + command = this.getNodeParameter('command', itemIndex) as string; + + const { + error, + exitCode, + stdout, + stderr, + } = await execPromise(command); + + if (error !== undefined) { + throw new NodeOperationError(this.getNode(), error.message); + } + + returnItems.push( + { + json: { + exitCode, + stderr, + stdout, + }, }, - }, - ); + ); + + } catch (error) { + if (this.continueOnFail()) { + returnItems.push({json:{ error: error.message }}); + continue; + } + throw error; + } } return this.prepareOutputData(returnItems); diff --git a/packages/nodes-base/nodes/ExecuteWorkflow.node.ts b/packages/nodes-base/nodes/ExecuteWorkflow.node.ts index 7ca01e8327..02271ed8a7 100644 --- a/packages/nodes-base/nodes/ExecuteWorkflow.node.ts +++ b/packages/nodes-base/nodes/ExecuteWorkflow.node.ts @@ -149,53 +149,64 @@ export class ExecuteWorkflow implements INodeType { const source = this.getNodeParameter('source', 0) as string; const workflowInfo: IExecuteWorkflowInfo = {}; - if (source === 'database') { - // Read workflow from database - workflowInfo.id = this.getNodeParameter('workflowId', 0) as string; - } else if (source === 'localFile') { - // Read workflow from filesystem - const workflowPath = this.getNodeParameter('workflowPath', 0) as string; + try { - let workflowJson; - try { - workflowJson = await fsReadFile(workflowPath, { encoding: 'utf8' }) as string; - } catch (error) { - if (error.code === 'ENOENT') { - throw new NodeOperationError(this.getNode(), `The file "${workflowPath}" could not be found.`); + if (source === 'database') { + // Read workflow from database + workflowInfo.id = this.getNodeParameter('workflowId', 0) as string; + + } else if (source === 'localFile') { + // Read workflow from filesystem + const workflowPath = this.getNodeParameter('workflowPath', 0) as string; + + let workflowJson; + try { + workflowJson = await fsReadFile(workflowPath, { encoding: 'utf8' }) as string; + } catch (error) { + if (error.code === 'ENOENT') { + throw new NodeOperationError(this.getNode(), `The file "${workflowPath}" could not be found.`); + } + + throw error; } - throw error; + workflowInfo.code = JSON.parse(workflowJson) as IWorkflowBase; + } else if (source === 'parameter') { + // Read workflow from parameter + const workflowJson = this.getNodeParameter('workflowJson', 0) as string; + workflowInfo.code = JSON.parse(workflowJson) as IWorkflowBase; + + } else if (source === 'url') { + // Read workflow from url + const workflowUrl = this.getNodeParameter('workflowUrl', 0) as string; + + + const requestOptions = { + headers: { + 'accept': 'application/json,text/*;q=0.99', + }, + method: 'GET', + uri: workflowUrl, + json: true, + gzip: true, + }; + + const response = await this.helpers.request(requestOptions); + workflowInfo.code = response; + } - workflowInfo.code = JSON.parse(workflowJson) as IWorkflowBase; - } else if (source === 'parameter') { - // Read workflow from parameter - const workflowJson = this.getNodeParameter('workflowJson', 0) as string; - workflowInfo.code = JSON.parse(workflowJson) as IWorkflowBase; + const receivedData = await this.executeWorkflow(workflowInfo, items); - } else if (source === 'url') { - // Read workflow from url - const workflowUrl = this.getNodeParameter('workflowUrl', 0) as string; + return receivedData; + } catch (error) { + if (this.continueOnFail()) { + return this.prepareOutputData([{json:{ error: error.message }}]); + } - const requestOptions = { - headers: { - 'accept': 'application/json,text/*;q=0.99', - }, - method: 'GET', - uri: workflowUrl, - json: true, - gzip: true, - }; - - const response = await this.helpers.request(requestOptions); - workflowInfo.code = response; - + throw error; } - - const receivedData = await this.executeWorkflow(workflowInfo, items); - - return receivedData; } } diff --git a/packages/nodes-base/nodes/Freshdesk/Freshdesk.node.ts b/packages/nodes-base/nodes/Freshdesk/Freshdesk.node.ts index 57f6aa1041..fdbda06ae3 100644 --- a/packages/nodes-base/nodes/Freshdesk/Freshdesk.node.ts +++ b/packages/nodes-base/nodes/Freshdesk/Freshdesk.node.ts @@ -1148,283 +1148,291 @@ export class Freshdesk implements INodeType { const resource = this.getNodeParameter('resource', 0) as string; const operation = this.getNodeParameter('operation', 0) as string; for (let i = 0; i < items.length; i++) { - if (resource === 'ticket') { - //https://developers.freshdesk.com/api/#create_ticket - if (operation === 'create') { - const requester = this.getNodeParameter('requester', i) as string; - const value = this.getNodeParameter('requesterIdentificationValue', i) as string; - const status = this.getNodeParameter('status', i) as string; - const priority = this.getNodeParameter('priority', i) as string; - const source = this.getNodeParameter('source', i) as string; - const options = this.getNodeParameter('options', i) as IDataObject; - //const jsonActive = this.getNodeParameter('jsonParameters') as boolean; - const body: ICreateTicketBody = { - // @ts-ignore - status: Status[capitalize(status)], - // @ts-ignore - priority: Priority[capitalize(priority)], - // @ts-ignore - source: Source[capitalize(source)], - }; - - if (requester === 'requesterId') { - // @ts-ignore - if (isNaN(value)) { - throw new NodeOperationError(this.getNode(), 'Requester Id must be a number'); - } - body.requester_id = parseInt(value, 10); - } else if (requester === 'email') { - body.email = value; - } else if (requester === 'facebookId') { - body.facebook_id = value; - } else if (requester === 'phone') { - body.phone = value; - } else if (requester === 'twitterId') { - body.twitter_id = value; - } else if (requester === 'uniqueExternalId') { - body.unique_external_id = value; - } - - // if (!jsonActive) { - // const customFieldsUi = this.getNodeParameter('customFieldsUi') as IDataObject; - // if (Object.keys(customFieldsUi).length > 0) { - // const aux: IDataObject = {}; - // // @ts-ignore - // customFieldsUi.customFieldsValues.forEach( o => { - // aux[`${o.key}`] = o.value; - // return aux; - // }); - // body.custom_fields = aux; - // } else { - // body.custom_fields = validateJSON(this.getNodeParameter('customFielsJson') as string); - // } - - if (options.name) { - body.name = options.name as string; - } - if (options.subject) { - body.subject = options.subject as string; - } else { - body.subject = 'null'; - } - if (options.type) { - body.type = options.type as string; - } - if (options.description) { - body.description = options.description as string; - } else { - body.description = 'null'; - } - if (options.agent) { - body.responder_id = options.agent as number; - } - if (options.company) { - body.company_id = options.company as number; - } - if (options.product) { - body.product_id = options.product as number; - } - if (options.group) { - body.group_id = options.group as number; - } - if (options.frDueBy) { - body.fr_due_by = options.frDueBy as string; - } - if (options.emailConfigId) { - body.email_config_id = options.emailConfigId as number; - } - if (options.dueBy) { - body.due_by = options.dueBy as string; - } - if (options.tags) { - body.tags = (options.tags as string).split(',') as [string]; - } - if (options.ccEmails) { - body.cc_emails = (options.ccEmails as string).split(',') as [string]; - } - responseData = await freshdeskApiRequest.call(this, 'POST', '/tickets', body); - } - //https://developers.freshdesk.com/api/#update_ticket - if (operation === 'update') { - const ticketId = this.getNodeParameter('ticketId', i) as string; - const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; - const body: ICreateTicketBody = {}; - - if (updateFields.requester) { - const value = updateFields.requesterIdentificationValue as string; - if (updateFields.requester === 'requesterId') { + try { + if (resource === 'ticket') { + //https://developers.freshdesk.com/api/#create_ticket + if (operation === 'create') { + const requester = this.getNodeParameter('requester', i) as string; + const value = this.getNodeParameter('requesterIdentificationValue', i) as string; + const status = this.getNodeParameter('status', i) as string; + const priority = this.getNodeParameter('priority', i) as string; + const source = this.getNodeParameter('source', i) as string; + const options = this.getNodeParameter('options', i) as IDataObject; + //const jsonActive = this.getNodeParameter('jsonParameters') as boolean; + const body: ICreateTicketBody = { // @ts-ignore - if (isNaN(parseInt(value, 10))) { + status: Status[capitalize(status)], + // @ts-ignore + priority: Priority[capitalize(priority)], + // @ts-ignore + source: Source[capitalize(source)], + }; + + if (requester === 'requesterId') { + // @ts-ignore + if (isNaN(value)) { throw new NodeOperationError(this.getNode(), 'Requester Id must be a number'); } - body.requester_id = parseInt(value as string, 10); - } else if (updateFields.requester === 'email') { - body.email = value as string; - } else if (updateFields.requester === 'facebookId') { - body.facebook_id = value as string; - } else if (updateFields.requester === 'phone') { - body.phone = value as string; - } else if (updateFields.requester === 'twitterId') { - body.twitter_id = value as string; - } else if (updateFields.requester === 'uniqueExternalId') { - body.unique_external_id = value as string; + body.requester_id = parseInt(value, 10); + } else if (requester === 'email') { + body.email = value; + } else if (requester === 'facebookId') { + body.facebook_id = value; + } else if (requester === 'phone') { + body.phone = value; + } else if (requester === 'twitterId') { + body.twitter_id = value; + } else if (requester === 'uniqueExternalId') { + body.unique_external_id = value; } - } - if (updateFields.status) { - //@ts-ignore - body.status = Status[capitalize(updateFields.status)]; - } - if (updateFields.priority) { - //@ts-ignore - body.priority = Priority[capitalize(updateFields.priority)]; - } - if (updateFields.source) { - //@ts-ignore - body.source = Source[capitalize(updateFields.source)]; - } - if (updateFields.name) { - body.name = updateFields.name as string; - } - if (updateFields.type) { - body.type = updateFields.type as string; - } - if (updateFields.agent) { - body.responder_id = updateFields.agent as number; - } - if (updateFields.company) { - body.company_id = updateFields.company as number; - } - if (updateFields.product) { - body.product_id = updateFields.product as number; - } - if (updateFields.group) { - body.group_id = updateFields.group as number; - } - if (updateFields.frDueBy) { - body.fr_due_by = updateFields.frDueBy as string; - } - if (updateFields.emailConfigId) { - body.email_config_id = updateFields.emailConfigId as number; - } - if (updateFields.dueBy) { - body.due_by = updateFields.dueBy as string; - } - if (updateFields.tags) { - body.tags = (updateFields.tags as string).split(',') as [string]; - } - if (updateFields.ccEmails) { - body.cc_emails = (updateFields.ccEmails as string).split(',') as [string]; - } - responseData = await freshdeskApiRequest.call(this, 'PUT', `/tickets/${ticketId}`, body); - } - //https://developers.freshdesk.com/api/#view_a_ticket - if (operation === 'get') { - const ticketId = this.getNodeParameter('ticketId', i) as string; - responseData = await freshdeskApiRequest.call(this, 'GET', `/tickets/${ticketId}`); - } - //https://developers.freshdesk.com/api/#list_all_tickets - if (operation === 'getAll') { - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - const options = this.getNodeParameter('options', i) as IDataObject; - if (options.requesterId) { - qs.requester_id = options.requesterId as string; - } - if (options.requesterEmail) { - qs.email = options.requesterEmail as string; - } - if (options.companyId) { - qs.company_id = options.companyId as string; - } - if (options.updatedSince) { - qs.updated_since = options.updatedSince as string; - } - if (options.orderBy) { - qs.order_by = options.orderBy as string; - } - if (options.order) { - qs.order_type = options.order as string; - } - if (options.include) { - if ((options.include as string[]).length !== 0) { - qs.include = (options.include as string[]).join(','); - } - } - if (returnAll === true) { - responseData = await freshdeskApiRequestAllItems.call(this, 'GET', '/tickets', {}, qs); - } else { - qs.per_page = this.getNodeParameter('limit', i) as number; - responseData = await freshdeskApiRequest.call(this, 'GET', '/tickets', {}, qs); - } - } - //https://developers.freshdesk.com/api/#delete_a_ticket - if (operation === 'delete') { - const ticketId = this.getNodeParameter('ticketId', i) as string; - responseData = await freshdeskApiRequest.call(this, 'DELETE', `/tickets/${ticketId}`); - } - } else if (resource === 'contact') { - //https://developers.freshdesk.com/api/#create_contact - if (operation === 'create') { - const name = this.getNodeParameter('name', i) as string; - const email = this.getNodeParameter('email', i) as string; - const additionalFields = this.getNodeParameter('additionalFields', i, {}) as IDataObject; - if (additionalFields.customFields) { - const metadata = (additionalFields.customFields as IDataObject).customField as IDataObject[]; - additionalFields.custom_fields = {}; - for (const data of metadata) { + // if (!jsonActive) { + // const customFieldsUi = this.getNodeParameter('customFieldsUi') as IDataObject; + // if (Object.keys(customFieldsUi).length > 0) { + // const aux: IDataObject = {}; + // // @ts-ignore + // customFieldsUi.customFieldsValues.forEach( o => { + // aux[`${o.key}`] = o.value; + // return aux; + // }); + // body.custom_fields = aux; + // } else { + // body.custom_fields = validateJSON(this.getNodeParameter('customFielsJson') as string); + // } + + if (options.name) { + body.name = options.name as string; + } + if (options.subject) { + body.subject = options.subject as string; + } else { + body.subject = 'null'; + } + if (options.type) { + body.type = options.type as string; + } + if (options.description) { + body.description = options.description as string; + } else { + body.description = 'null'; + } + if (options.agent) { + body.responder_id = options.agent as number; + } + if (options.company) { + body.company_id = options.company as number; + } + if (options.product) { + body.product_id = options.product as number; + } + if (options.group) { + body.group_id = options.group as number; + } + if (options.frDueBy) { + body.fr_due_by = options.frDueBy as string; + } + if (options.emailConfigId) { + body.email_config_id = options.emailConfigId as number; + } + if (options.dueBy) { + body.due_by = options.dueBy as string; + } + if (options.tags) { + body.tags = (options.tags as string).split(',') as [string]; + } + if (options.ccEmails) { + body.cc_emails = (options.ccEmails as string).split(',') as [string]; + } + responseData = await freshdeskApiRequest.call(this, 'POST', '/tickets', body); + } + //https://developers.freshdesk.com/api/#update_ticket + if (operation === 'update') { + const ticketId = this.getNodeParameter('ticketId', i) as string; + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + const body: ICreateTicketBody = {}; + + if (updateFields.requester) { + const value = updateFields.requesterIdentificationValue as string; + if (updateFields.requester === 'requesterId') { + // @ts-ignore + if (isNaN(parseInt(value, 10))) { + throw new NodeOperationError(this.getNode(), 'Requester Id must be a number'); + } + body.requester_id = parseInt(value as string, 10); + } else if (updateFields.requester === 'email') { + body.email = value as string; + } else if (updateFields.requester === 'facebookId') { + body.facebook_id = value as string; + } else if (updateFields.requester === 'phone') { + body.phone = value as string; + } else if (updateFields.requester === 'twitterId') { + body.twitter_id = value as string; + } else if (updateFields.requester === 'uniqueExternalId') { + body.unique_external_id = value as string; + } + } + if (updateFields.status) { //@ts-ignore - additionalFields.custom_fields[data.name as string] = data.value; + body.status = Status[capitalize(updateFields.status)]; } - delete additionalFields.customFields; - } - - const body: ICreateContactBody = additionalFields; - body.name = name; - if (email) { - body.email = email; - } - responseData = await freshdeskApiRequest.call(this, 'POST', '/contacts', body); - //https://developers.freshdesk.com/api/#delete_contact - } else if (operation === 'delete') { - const contactId = this.getNodeParameter('contactId', i) as string; - responseData = await freshdeskApiRequest.call(this, 'DELETE', `/contacts/${contactId}`, {}); - } else if (operation === 'get') { - const contactId = this.getNodeParameter('contactId', i) as string; - responseData = await freshdeskApiRequest.call(this, 'GET', `/contacts/${contactId}`, {}); - //https://developers.freshdesk.com/api/#list_all_contacts - } else if (operation === 'getAll') { - const qs = this.getNodeParameter('filters', i, {}) as IDataObject; - responseData = await freshdeskApiRequest.call(this, 'GET', '/contacts', {}, qs); - //https://developers.freshdesk.com/api/#update_contact - } else if (operation === 'update') { - const contactId = this.getNodeParameter('contactId', i) as string; - const additionalFields = this.getNodeParameter('additionalFields', i, {}) as IDataObject; - - if (additionalFields.customFields) { - const metadata = (additionalFields.customFields as IDataObject).customField as IDataObject[]; - additionalFields.custom_fields = {}; - for (const data of metadata) { + if (updateFields.priority) { //@ts-ignore - additionalFields.custom_fields[data.name as string] = data.value; + body.priority = Priority[capitalize(updateFields.priority)]; } - delete additionalFields.customFields; + if (updateFields.source) { + //@ts-ignore + body.source = Source[capitalize(updateFields.source)]; + } + if (updateFields.name) { + body.name = updateFields.name as string; + } + if (updateFields.type) { + body.type = updateFields.type as string; + } + if (updateFields.agent) { + body.responder_id = updateFields.agent as number; + } + if (updateFields.company) { + body.company_id = updateFields.company as number; + } + if (updateFields.product) { + body.product_id = updateFields.product as number; + } + if (updateFields.group) { + body.group_id = updateFields.group as number; + } + if (updateFields.frDueBy) { + body.fr_due_by = updateFields.frDueBy as string; + } + if (updateFields.emailConfigId) { + body.email_config_id = updateFields.emailConfigId as number; + } + if (updateFields.dueBy) { + body.due_by = updateFields.dueBy as string; + } + if (updateFields.tags) { + body.tags = (updateFields.tags as string).split(',') as [string]; + } + if (updateFields.ccEmails) { + body.cc_emails = (updateFields.ccEmails as string).split(',') as [string]; + } + responseData = await freshdeskApiRequest.call(this, 'PUT', `/tickets/${ticketId}`, body); + } + //https://developers.freshdesk.com/api/#view_a_ticket + if (operation === 'get') { + const ticketId = this.getNodeParameter('ticketId', i) as string; + responseData = await freshdeskApiRequest.call(this, 'GET', `/tickets/${ticketId}`); + } + //https://developers.freshdesk.com/api/#list_all_tickets + if (operation === 'getAll') { + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + const options = this.getNodeParameter('options', i) as IDataObject; + if (options.requesterId) { + qs.requester_id = options.requesterId as string; + } + if (options.requesterEmail) { + qs.email = options.requesterEmail as string; + } + if (options.companyId) { + qs.company_id = options.companyId as string; + } + if (options.updatedSince) { + qs.updated_since = options.updatedSince as string; + } + if (options.orderBy) { + qs.order_by = options.orderBy as string; + } + if (options.order) { + qs.order_type = options.order as string; + } + if (options.include) { + if ((options.include as string[]).length !== 0) { + qs.include = (options.include as string[]).join(','); + } + } + if (returnAll === true) { + responseData = await freshdeskApiRequestAllItems.call(this, 'GET', '/tickets', {}, qs); + } else { + qs.per_page = this.getNodeParameter('limit', i) as number; + responseData = await freshdeskApiRequest.call(this, 'GET', '/tickets', {}, qs); + } + } + //https://developers.freshdesk.com/api/#delete_a_ticket + if (operation === 'delete') { + const ticketId = this.getNodeParameter('ticketId', i) as string; + responseData = await freshdeskApiRequest.call(this, 'DELETE', `/tickets/${ticketId}`); + } + } else if (resource === 'contact') { + //https://developers.freshdesk.com/api/#create_contact + if (operation === 'create') { + const name = this.getNodeParameter('name', i) as string; + const email = this.getNodeParameter('email', i) as string; + const additionalFields = this.getNodeParameter('additionalFields', i, {}) as IDataObject; + + if (additionalFields.customFields) { + const metadata = (additionalFields.customFields as IDataObject).customField as IDataObject[]; + additionalFields.custom_fields = {}; + for (const data of metadata) { + //@ts-ignore + additionalFields.custom_fields[data.name as string] = data.value; + } + delete additionalFields.customFields; + } + + const body: ICreateContactBody = additionalFields; + body.name = name; + if (email) { + body.email = email; + } + responseData = await freshdeskApiRequest.call(this, 'POST', '/contacts', body); + //https://developers.freshdesk.com/api/#delete_contact + } else if (operation === 'delete') { + const contactId = this.getNodeParameter('contactId', i) as string; + responseData = await freshdeskApiRequest.call(this, 'DELETE', `/contacts/${contactId}`, {}); + } else if (operation === 'get') { + const contactId = this.getNodeParameter('contactId', i) as string; + responseData = await freshdeskApiRequest.call(this, 'GET', `/contacts/${contactId}`, {}); + //https://developers.freshdesk.com/api/#list_all_contacts + } else if (operation === 'getAll') { + const qs = this.getNodeParameter('filters', i, {}) as IDataObject; + responseData = await freshdeskApiRequest.call(this, 'GET', '/contacts', {}, qs); + //https://developers.freshdesk.com/api/#update_contact + } else if (operation === 'update') { + const contactId = this.getNodeParameter('contactId', i) as string; + const additionalFields = this.getNodeParameter('additionalFields', i, {}) as IDataObject; + + if (additionalFields.customFields) { + const metadata = (additionalFields.customFields as IDataObject).customField as IDataObject[]; + additionalFields.custom_fields = {}; + for (const data of metadata) { + //@ts-ignore + additionalFields.custom_fields[data.name as string] = data.value; + } + delete additionalFields.customFields; + } + + const body: ICreateContactBody = additionalFields; + responseData = await freshdeskApiRequest.call(this, 'PUT', `/contacts/${contactId}`, body); + } + } + + if (Array.isArray(responseData)) { + returnData.push.apply(returnData, responseData as IDataObject[]); + } else { + if (responseData === undefined) { + responseData = { + success: true, + }; } - const body: ICreateContactBody = additionalFields; - responseData = await freshdeskApiRequest.call(this, 'PUT', `/contacts/${contactId}`, body); + returnData.push(responseData as IDataObject); } - } - - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else { - if (responseData === undefined) { - responseData = { - success: true, - }; + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; } - - returnData.push(responseData as IDataObject); + throw error; } } return [this.helpers.returnJsonArray(returnData)]; diff --git a/packages/nodes-base/nodes/Ftp.node.ts b/packages/nodes-base/nodes/Ftp.node.ts index 27f20a079e..9540f33c3c 100644 --- a/packages/nodes-base/nodes/Ftp.node.ts +++ b/packages/nodes-base/nodes/Ftp.node.ts @@ -378,263 +378,271 @@ export class Ftp implements INodeType { } else { credentials = this.getCredentials('ftp'); } + try { - if (credentials === undefined) { - throw new NodeOperationError(this.getNode(), 'Failed to get credentials!'); - } - - let ftp : ftpClient; - let sftp : sftpClient; - - if (protocol === 'sftp') { - sftp = new sftpClient(); - await sftp.connect({ - host: credentials.host as string, - port: credentials.port as number, - username: credentials.username as string, - password: credentials.password as string, - privateKey: credentials.privateKey as string | undefined, - passphrase: credentials.passphrase as string | undefined, - }); - - } else { - ftp = new ftpClient(); - await ftp.connect({ - host: credentials.host as string, - port: credentials.port as number, - user: credentials.username as string, - password: credentials.password as string, - }); - } - - for (let i = 0; i < items.length; i++) { - const newItem: INodeExecutionData = { - json: items[i].json, - binary: {}, - }; - - if (items[i].binary !== undefined) { - // Create a shallow copy of the binary data so that the old - // data references which do not get changed still stay behind - // but the incoming data does not get changed. - Object.assign(newItem.binary, items[i].binary); + if (credentials === undefined) { + throw new NodeOperationError(this.getNode(), 'Failed to get credentials!'); } - items[i] = newItem; + let ftp : ftpClient; + let sftp : sftpClient; if (protocol === 'sftp') { + sftp = new sftpClient(); + await sftp.connect({ + host: credentials.host as string, + port: credentials.port as number, + username: credentials.username as string, + password: credentials.password as string, + privateKey: credentials.privateKey as string | undefined, + passphrase: credentials.passphrase as string | undefined, + }); - if (operation === 'list') { - const path = this.getNodeParameter('path', i) as string; + } else { + ftp = new ftpClient(); + await ftp.connect({ + host: credentials.host as string, + port: credentials.port as number, + user: credentials.username as string, + password: credentials.password as string, + }); + } - const recursive = this.getNodeParameter('recursive', i) as boolean; + for (let i = 0; i < items.length; i++) { + const newItem: INodeExecutionData = { + json: items[i].json, + binary: {}, + }; - if (recursive) { - responseData = await callRecursiveList(path, sftp!, normalizeSFtpItem); - returnItems.push.apply(returnItems, this.helpers.returnJsonArray(responseData as unknown as IDataObject[])); - } else { - responseData = await sftp!.list(path); - responseData.forEach(item => normalizeSFtpItem(item as sftpClient.FileInfo, path)); - returnItems.push.apply(returnItems, this.helpers.returnJsonArray(responseData as unknown as IDataObject[])); - } + if (items[i].binary !== undefined) { + // Create a shallow copy of the binary data so that the old + // data references which do not get changed still stay behind + // but the incoming data does not get changed. + Object.assign(newItem.binary, items[i].binary); } - if (operation === 'delete') { - const path = this.getNodeParameter('path', i) as string; - const options = this.getNodeParameter('options', i) as IDataObject; + items[i] = newItem; - if (options.folder === true) { - responseData = await sftp!.rmdir(path, !!options.recursive); - } else { - responseData = await sftp!.delete(path); + if (protocol === 'sftp') { + + if (operation === 'list') { + const path = this.getNodeParameter('path', i) as string; + + const recursive = this.getNodeParameter('recursive', i) as boolean; + + if (recursive) { + responseData = await callRecursiveList(path, sftp!, normalizeSFtpItem); + returnItems.push.apply(returnItems, this.helpers.returnJsonArray(responseData as unknown as IDataObject[])); + } else { + responseData = await sftp!.list(path); + responseData.forEach(item => normalizeSFtpItem(item as sftpClient.FileInfo, path)); + returnItems.push.apply(returnItems, this.helpers.returnJsonArray(responseData as unknown as IDataObject[])); + } } - returnItems.push({ json: { success: true } }); - } + if (operation === 'delete') { + const path = this.getNodeParameter('path', i) as string; + const options = this.getNodeParameter('options', i) as IDataObject; - if (operation === 'rename') { - const oldPath = this.getNodeParameter('oldPath', i) as string; - - const newPath = this.getNodeParameter('newPath', i) as string; - - responseData = await sftp!.rename(oldPath, newPath); - - returnItems.push({ json: { success: true } }); - } - - if (operation === 'download') { - const path = this.getNodeParameter('path', i) as string; - - responseData = await sftp!.get(path); - - const dataPropertyNameDownload = this.getNodeParameter('binaryPropertyName', i) as string; - - const filePathDownload = this.getNodeParameter('path', i) as string; - items[i].binary![dataPropertyNameDownload] = await this.helpers.prepareBinaryData(responseData as Buffer, filePathDownload); - - returnItems.push(items[i]); - } - - if (operation === 'upload') { - const remotePath = this.getNodeParameter('path', i) as string; - - // Check if dir path exists - const dirPath = dirname(remotePath); - const dirExists = await sftp!.exists(dirPath); - - // If dir does not exist, create all recursively in path - if (!dirExists) { - // Create directory - await sftp!.mkdir(dirPath, true); - } - - if (this.getNodeParameter('binaryData', i) === true) { - // Is binary file to upload - const item = items[i]; - - if (item.binary === undefined) { - throw new NodeOperationError(this.getNode(), 'No binary data exists on item!'); + if (options.folder === true) { + responseData = await sftp!.rmdir(path, !!options.recursive); + } else { + responseData = await sftp!.delete(path); } - const propertyNameUpload = this.getNodeParameter('binaryPropertyName', i) as string; - - if (item.binary[propertyNameUpload] === undefined) { - throw new NodeOperationError(this.getNode(), `No binary data property "${propertyNameUpload}" does not exists on item!`); - } - - const buffer = Buffer.from(item.binary[propertyNameUpload].data, BINARY_ENCODING) as Buffer; - await sftp!.put(buffer, remotePath); - } else { - // Is text file - const buffer = Buffer.from(this.getNodeParameter('fileContent', i) as string, 'utf8') as Buffer; - await sftp!.put(buffer, remotePath); + returnItems.push({ json: { success: true } }); } - returnItems.push(items[i]); + if (operation === 'rename') { + const oldPath = this.getNodeParameter('oldPath', i) as string; + + const newPath = this.getNodeParameter('newPath', i) as string; + + responseData = await sftp!.rename(oldPath, newPath); + + returnItems.push({ json: { success: true } }); + } + + if (operation === 'download') { + const path = this.getNodeParameter('path', i) as string; + + responseData = await sftp!.get(path); + + const dataPropertyNameDownload = this.getNodeParameter('binaryPropertyName', i) as string; + + const filePathDownload = this.getNodeParameter('path', i) as string; + items[i].binary![dataPropertyNameDownload] = await this.helpers.prepareBinaryData(responseData as Buffer, filePathDownload); + + returnItems.push(items[i]); + } + + if (operation === 'upload') { + const remotePath = this.getNodeParameter('path', i) as string; + + // Check if dir path exists + const dirPath = dirname(remotePath); + const dirExists = await sftp!.exists(dirPath); + + // If dir does not exist, create all recursively in path + if (!dirExists) { + // Create directory + await sftp!.mkdir(dirPath, true); + } + + if (this.getNodeParameter('binaryData', i) === true) { + // Is binary file to upload + const item = items[i]; + + if (item.binary === undefined) { + throw new NodeOperationError(this.getNode(), 'No binary data exists on item!'); + } + + const propertyNameUpload = this.getNodeParameter('binaryPropertyName', i) as string; + + if (item.binary[propertyNameUpload] === undefined) { + throw new NodeOperationError(this.getNode(), `No binary data property "${propertyNameUpload}" does not exists on item!`); + } + + const buffer = Buffer.from(item.binary[propertyNameUpload].data, BINARY_ENCODING) as Buffer; + await sftp!.put(buffer, remotePath); + } else { + // Is text file + const buffer = Buffer.from(this.getNodeParameter('fileContent', i) as string, 'utf8') as Buffer; + await sftp!.put(buffer, remotePath); + } + + returnItems.push(items[i]); + } + } + + if (protocol === 'ftp') { + + if (operation === 'list') { + const path = this.getNodeParameter('path', i) as string; + + const recursive = this.getNodeParameter('recursive', i) as boolean; + + if (recursive) { + responseData = await callRecursiveList(path, ftp!, normalizeFtpItem); + returnItems.push.apply(returnItems, this.helpers.returnJsonArray(responseData as unknown as IDataObject[])); + } else { + responseData = await ftp!.list(path); + responseData.forEach(item => normalizeFtpItem(item as ftpClient.ListingElement, path)); + returnItems.push.apply(returnItems, this.helpers.returnJsonArray(responseData as unknown as IDataObject[])); + } + } + + if (operation === 'delete') { + const path = this.getNodeParameter('path', i) as string; + const options = this.getNodeParameter('options', i) as IDataObject; + + if (options.folder === true) { + responseData = await ftp!.rmdir(path, !!options.recursive); + } else { + responseData = await ftp!.delete(path); + } + + returnItems.push({ json: { success: true } }); + } + + if (operation === 'download') { + const path = this.getNodeParameter('path', i) as string; + + responseData = await ftp!.get(path); + + // Convert readable stream to buffer so that can be displayed properly + const chunks = []; + for await (const chunk of responseData) { + chunks.push(chunk); + } + + // @ts-ignore + responseData = Buffer.concat(chunks); + + const dataPropertyNameDownload = this.getNodeParameter('binaryPropertyName', i) as string; + + const filePathDownload = this.getNodeParameter('path', i) as string; + items[i].binary![dataPropertyNameDownload] = await this.helpers.prepareBinaryData(responseData, filePathDownload); + + returnItems.push(items[i]); + } + + if (operation === 'rename') { + + const oldPath = this.getNodeParameter('oldPath', i) as string; + + const newPath = this.getNodeParameter('newPath', i) as string; + + responseData = await ftp!.rename(oldPath, newPath); + + returnItems.push({ json: { success: true } }); + } + + if (operation === 'upload') { + const remotePath = this.getNodeParameter('path', i) as string; + const fileName = basename(remotePath); + const dirPath = remotePath.replace(fileName, ''); + + if (this.getNodeParameter('binaryData', i) === true) { + // Is binary file to upload + const item = items[i]; + + if (item.binary === undefined) { + throw new NodeOperationError(this.getNode(), 'No binary data exists on item!'); + } + + const propertyNameUpload = this.getNodeParameter('binaryPropertyName', i) as string; + + if (item.binary[propertyNameUpload] === undefined) { + throw new NodeOperationError(this.getNode(), `No binary data property "${propertyNameUpload}" does not exists on item!`); + } + + const buffer = Buffer.from(item.binary[propertyNameUpload].data, BINARY_ENCODING) as Buffer; + + try { + await ftp!.put(buffer, remotePath); + } catch (error) { + if (error.code === 553) { + // Create directory + await ftp!.mkdir(dirPath, true); + await ftp!.put(buffer, remotePath); + } else { + throw new NodeApiError(this.getNode(), error); + } + } + } else { + // Is text file + const buffer = Buffer.from(this.getNodeParameter('fileContent', i) as string, 'utf8') as Buffer; + try { + await ftp!.put(buffer, remotePath); + } catch (error) { + if (error.code === 553) { + // Create directory + await ftp!.mkdir(dirPath, true); + await ftp!.put(buffer, remotePath); + } else { + throw new NodeApiError(this.getNode(), error); + } + } + } + returnItems.push(items[i]); + } } } - if (protocol === 'ftp') { - - if (operation === 'list') { - const path = this.getNodeParameter('path', i) as string; - - const recursive = this.getNodeParameter('recursive', i) as boolean; - - if (recursive) { - responseData = await callRecursiveList(path, ftp!, normalizeFtpItem); - returnItems.push.apply(returnItems, this.helpers.returnJsonArray(responseData as unknown as IDataObject[])); - } else { - responseData = await ftp!.list(path); - responseData.forEach(item => normalizeFtpItem(item as ftpClient.ListingElement, path)); - returnItems.push.apply(returnItems, this.helpers.returnJsonArray(responseData as unknown as IDataObject[])); - } - } - - if (operation === 'delete') { - const path = this.getNodeParameter('path', i) as string; - const options = this.getNodeParameter('options', i) as IDataObject; - - if (options.folder === true) { - responseData = await ftp!.rmdir(path, !!options.recursive); - } else { - responseData = await ftp!.delete(path); - } - - returnItems.push({ json: { success: true } }); - } - - if (operation === 'download') { - const path = this.getNodeParameter('path', i) as string; - - responseData = await ftp!.get(path); - - // Convert readable stream to buffer so that can be displayed properly - const chunks = []; - for await (const chunk of responseData) { - chunks.push(chunk); - } - - // @ts-ignore - responseData = Buffer.concat(chunks); - - const dataPropertyNameDownload = this.getNodeParameter('binaryPropertyName', i) as string; - - const filePathDownload = this.getNodeParameter('path', i) as string; - items[i].binary![dataPropertyNameDownload] = await this.helpers.prepareBinaryData(responseData, filePathDownload); - - returnItems.push(items[i]); - } - - if (operation === 'rename') { - - const oldPath = this.getNodeParameter('oldPath', i) as string; - - const newPath = this.getNodeParameter('newPath', i) as string; - - responseData = await ftp!.rename(oldPath, newPath); - - returnItems.push({ json: { success: true } }); - } - - if (operation === 'upload') { - const remotePath = this.getNodeParameter('path', i) as string; - const fileName = basename(remotePath); - const dirPath = remotePath.replace(fileName, ''); - - if (this.getNodeParameter('binaryData', i) === true) { - // Is binary file to upload - const item = items[i]; - - if (item.binary === undefined) { - throw new NodeOperationError(this.getNode(), 'No binary data exists on item!'); - } - - const propertyNameUpload = this.getNodeParameter('binaryPropertyName', i) as string; - - if (item.binary[propertyNameUpload] === undefined) { - throw new NodeOperationError(this.getNode(), `No binary data property "${propertyNameUpload}" does not exists on item!`); - } - - const buffer = Buffer.from(item.binary[propertyNameUpload].data, BINARY_ENCODING) as Buffer; - - try { - await ftp!.put(buffer, remotePath); - } catch (error) { - if (error.code === 553) { - // Create directory - await ftp!.mkdir(dirPath, true); - await ftp!.put(buffer, remotePath); - } else { - throw new NodeApiError(this.getNode(), error); - } - } - } else { - // Is text file - const buffer = Buffer.from(this.getNodeParameter('fileContent', i) as string, 'utf8') as Buffer; - try { - await ftp!.put(buffer, remotePath); - } catch (error) { - if (error.code === 553) { - // Create directory - await ftp!.mkdir(dirPath, true); - await ftp!.put(buffer, remotePath); - } else { - throw new NodeApiError(this.getNode(), error); - } - } - } - returnItems.push(items[i]); - } + if (protocol === 'sftp') { + await sftp!.end(); + } else { + await ftp!.end(); } - } - if (protocol === 'sftp') { - await sftp!.end(); - } else { - await ftp!.end(); - } + } catch (error) { + if (this.continueOnFail()) { + return this.prepareOutputData([{json:{ error: error.message }}]); + } + throw error; + } return [returnItems]; } } diff --git a/packages/nodes-base/nodes/Function.node.ts b/packages/nodes-base/nodes/Function.node.ts index 6fcb75a244..f1a1b6aac1 100644 --- a/packages/nodes-base/nodes/Function.node.ts +++ b/packages/nodes-base/nodes/Function.node.ts @@ -102,32 +102,37 @@ return items;`, try { // Execute the function code items = (await vm.run(`module.exports = async function() {${functionCode}}()`, __dirname)); - } catch (error) { - return Promise.reject(error); - } - - - // Do very basic validation of the data - if (items === undefined) { - throw new NodeOperationError(this.getNode(), 'No data got returned. Always return an Array of items!'); - } - if (!Array.isArray(items)) { - throw new NodeOperationError(this.getNode(), 'Always an Array of items has to be returned!'); - } - for (const item of items) { - if (item.json === undefined) { - throw new NodeOperationError(this.getNode(), 'All returned items have to contain a property named "json"!'); + // Do very basic validation of the data + if (items === undefined) { + throw new NodeOperationError(this.getNode(), 'No data got returned. Always return an Array of items!'); } - if (typeof item.json !== 'object') { - throw new NodeOperationError(this.getNode(), 'The json-property has to be an object!'); + if (!Array.isArray(items)) { + throw new NodeOperationError(this.getNode(), 'Always an Array of items has to be returned!'); } - if (item.binary !== undefined) { - if (Array.isArray(item.binary) || typeof item.binary !== 'object') { - throw new NodeOperationError(this.getNode(), 'The binary-property has to be an object!'); + for (const item of items) { + if (item.json === undefined) { + throw new NodeOperationError(this.getNode(), 'All returned items have to contain a property named "json"!'); + } + if (typeof item.json !== 'object') { + throw new NodeOperationError(this.getNode(), 'The json-property has to be an object!'); + } + if (item.binary !== undefined) { + if (Array.isArray(item.binary) || typeof item.binary !== 'object') { + throw new NodeOperationError(this.getNode(), 'The binary-property has to be an object!'); + } } } + } catch (error) { + if (this.continueOnFail()) { + items=[{json:{ error: error.message }}]; + } else { + return Promise.reject(error); + } } + + + return this.prepareOutputData(items); } } diff --git a/packages/nodes-base/nodes/FunctionItem.node.ts b/packages/nodes-base/nodes/FunctionItem.node.ts index 64cb55be2f..b536c8daf7 100644 --- a/packages/nodes-base/nodes/FunctionItem.node.ts +++ b/packages/nodes-base/nodes/FunctionItem.node.ts @@ -58,80 +58,92 @@ return item;`, let item: INodeExecutionData; for (let itemIndex = 0; itemIndex < length; itemIndex++) { - - item = items[itemIndex]; - - // Copy the items as they may get changed in the functions - item = JSON.parse(JSON.stringify(item)); - - // Define the global objects for the custom function - const sandbox = { - getBinaryData: (): IBinaryKeyData | undefined => { - return item.binary; - }, - getNodeParameter: this.getNodeParameter, - getWorkflowStaticData: this.getWorkflowStaticData, - helpers: this.helpers, - item: item.json, - setBinaryData: (data: IBinaryKeyData) => { - item.binary = data; - }, - }; - - // Make it possible to access data via $node, $parameter, ... - const dataProxy = this.getWorkflowDataProxy(itemIndex); - Object.assign(sandbox, dataProxy); - - const mode = this.getMode(); - - const options = { - console: (mode === 'manual') ? 'redirect' : 'inherit', - sandbox, - require: { - external: false as boolean | { modules: string[] }, - builtin: [] as string[], - }, - }; - - if (process.env.NODE_FUNCTION_ALLOW_BUILTIN) { - options.require.builtin = process.env.NODE_FUNCTION_ALLOW_BUILTIN.split(','); - } - - if (process.env.NODE_FUNCTION_ALLOW_EXTERNAL) { - options.require.external = { modules: process.env.NODE_FUNCTION_ALLOW_EXTERNAL.split(',') }; - } - - const vm = new NodeVM(options); - - if (mode === 'manual') { - vm.on('console.log', this.sendMessageToUI); - } - - // Get the code to execute - const functionCode = this.getNodeParameter('functionCode', itemIndex) as string; - - let jsonData: IDataObject; try { - // Execute the function code - jsonData = await vm.run(`module.exports = async function() {${functionCode}}()`, __dirname); + item = items[itemIndex]; + + // Copy the items as they may get changed in the functions + item = JSON.parse(JSON.stringify(item)); + + // Define the global objects for the custom function + const sandbox = { + getBinaryData: (): IBinaryKeyData | undefined => { + return item.binary; + }, + getNodeParameter: this.getNodeParameter, + getWorkflowStaticData: this.getWorkflowStaticData, + helpers: this.helpers, + item: item.json, + setBinaryData: (data: IBinaryKeyData) => { + item.binary = data; + }, + }; + + // Make it possible to access data via $node, $parameter, ... + const dataProxy = this.getWorkflowDataProxy(itemIndex); + Object.assign(sandbox, dataProxy); + + const mode = this.getMode(); + + const options = { + console: (mode === 'manual') ? 'redirect' : 'inherit', + sandbox, + require: { + external: false as boolean | { modules: string[] }, + builtin: [] as string[], + }, + }; + + if (process.env.NODE_FUNCTION_ALLOW_BUILTIN) { + options.require.builtin = process.env.NODE_FUNCTION_ALLOW_BUILTIN.split(','); + } + + if (process.env.NODE_FUNCTION_ALLOW_EXTERNAL) { + options.require.external = { modules: process.env.NODE_FUNCTION_ALLOW_EXTERNAL.split(',') }; + } + + const vm = new NodeVM(options); + + if (mode === 'manual') { + vm.on('console.log', this.sendMessageToUI); + } + + // Get the code to execute + const functionCode = this.getNodeParameter('functionCode', itemIndex) as string; + + let jsonData: IDataObject; + try { + // Execute the function code + jsonData = await vm.run(`module.exports = async function() {${functionCode}}()`, __dirname); + } catch (error) { + if (this.continueOnFail()) { + returnData.push({json:{ error: error.message }}); + continue; + } else { + return Promise.reject(error); + } + } + + // Do very basic validation of the data + if (jsonData === undefined) { + throw new NodeOperationError(this.getNode(), 'No data got returned. Always an object has to be returned!'); + } + + const returnItem: INodeExecutionData = { + json: jsonData, + }; + + if (item.binary) { + returnItem.binary = item.binary; + } + + returnData.push(returnItem); } catch (error) { - return Promise.reject(error); + if (this.continueOnFail()) { + returnData.push({json:{ error: error.message }}); + continue; + } + throw error; } - - // Do very basic validation of the data - if (jsonData === undefined) { - throw new NodeOperationError(this.getNode(), 'No data got returned. Always an object has to be returned!'); - } - - const returnItem: INodeExecutionData = { - json: jsonData, - }; - - if (item.binary) { - returnItem.binary = item.binary; - } - - returnData.push(returnItem); } return this.prepareOutputData(returnData); } diff --git a/packages/nodes-base/nodes/GetResponse/GetResponse.node.ts b/packages/nodes-base/nodes/GetResponse/GetResponse.node.ts index 0cdbc66ef5..75869b2542 100644 --- a/packages/nodes-base/nodes/GetResponse/GetResponse.node.ts +++ b/packages/nodes-base/nodes/GetResponse/GetResponse.node.ts @@ -169,150 +169,157 @@ export class GetResponse implements INodeType { const resource = this.getNodeParameter('resource', 0) as string; const operation = this.getNodeParameter('operation', 0) as string; for (let i = 0; i < length; i++) { + try { + if (resource === 'contact') { + //https://apireference.getresponse.com/#operation/createContact + if (operation === 'create') { + const email = this.getNodeParameter('email', i) as string; - if (resource === 'contact') { - //https://apireference.getresponse.com/#operation/createContact - if (operation === 'create') { - const email = this.getNodeParameter('email', i) as string; + const campaignId = this.getNodeParameter('campaignId', i) as string; - const campaignId = this.getNodeParameter('campaignId', i) as string; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const body: IDataObject = { + email, + campaign: { + campaignId, + }, + }; - const body: IDataObject = { - email, - campaign: { - campaignId, - }, - }; + Object.assign(body, additionalFields); - Object.assign(body, additionalFields); - - if (additionalFields.customFieldsUi) { - const customFieldValues = (additionalFields.customFieldsUi as IDataObject).customFieldValues as IDataObject[]; - if (customFieldValues) { - body.customFieldValues = customFieldValues; - for (let i = 0; i < customFieldValues.length; i++) { - if (!Array.isArray(customFieldValues[i].value)) { - customFieldValues[i].value = [customFieldValues[i].value]; + if (additionalFields.customFieldsUi) { + const customFieldValues = (additionalFields.customFieldsUi as IDataObject).customFieldValues as IDataObject[]; + if (customFieldValues) { + body.customFieldValues = customFieldValues; + for (let i = 0; i < customFieldValues.length; i++) { + if (!Array.isArray(customFieldValues[i].value)) { + customFieldValues[i].value = [customFieldValues[i].value]; + } } + delete body.customFieldsUi; } - delete body.customFieldsUi; } + + responseData = await getresponseApiRequest.call(this, 'POST', '/contacts', body); + + responseData = { success: true }; } + //https://apireference.getresponse.com/?_ga=2.160836350.2102802044.1604719933-1897033509.1604598019#operation/deleteContact + if (operation === 'delete') { + const contactId = this.getNodeParameter('contactId', i) as string; - responseData = await getresponseApiRequest.call(this, 'POST', '/contacts', body); + const options = this.getNodeParameter('options', i) as IDataObject; - responseData = { success: true }; - } - //https://apireference.getresponse.com/?_ga=2.160836350.2102802044.1604719933-1897033509.1604598019#operation/deleteContact - if (operation === 'delete') { - const contactId = this.getNodeParameter('contactId', i) as string; + Object.assign(qs, options); - const options = this.getNodeParameter('options', i) as IDataObject; + responseData = await getresponseApiRequest.call(this, 'DELETE', `/contacts/${contactId}`, {}, qs); - Object.assign(qs, options); + responseData = { success: true }; + } + //https://apireference.getresponse.com/?_ga=2.160836350.2102802044.1604719933-1897033509.1604598019#operation/getContactById + if (operation === 'get') { + const contactId = this.getNodeParameter('contactId', i) as string; - responseData = await getresponseApiRequest.call(this, 'DELETE', `/contacts/${contactId}`, {}, qs); + const options = this.getNodeParameter('options', i) as IDataObject; - responseData = { success: true }; - } - //https://apireference.getresponse.com/?_ga=2.160836350.2102802044.1604719933-1897033509.1604598019#operation/getContactById - if (operation === 'get') { - const contactId = this.getNodeParameter('contactId', i) as string; + Object.assign(qs, options); - const options = this.getNodeParameter('options', i) as IDataObject; + responseData = await getresponseApiRequest.call(this, 'GET', `/contacts/${contactId}`, {}, qs); + } + //https://apireference.getresponse.com/?_ga=2.160836350.2102802044.1604719933-1897033509.1604598019#operation/getContactList + if (operation === 'getAll') { + const returnAll = this.getNodeParameter('returnAll', i) as boolean; - Object.assign(qs, options); + const options = this.getNodeParameter('options', i) as IDataObject; - responseData = await getresponseApiRequest.call(this, 'GET', `/contacts/${contactId}`, {}, qs); - } - //https://apireference.getresponse.com/?_ga=2.160836350.2102802044.1604719933-1897033509.1604598019#operation/getContactList - if (operation === 'getAll') { - const returnAll = this.getNodeParameter('returnAll', i) as boolean; + const timezone = this.getTimezone(); - const options = this.getNodeParameter('options', i) as IDataObject; + Object.assign(qs, options); - const timezone = this.getTimezone(); + const isNotQuery = [ + 'sortBy', + 'sortOrder', + 'additionalFlags', + 'fields', + 'exactMatch', + ]; - Object.assign(qs, options); + const isDate = [ + 'createdOnFrom', + 'createdOnTo', + 'changeOnFrom', + 'changeOnTo', + ]; - const isNotQuery = [ - 'sortBy', - 'sortOrder', - 'additionalFlags', - 'fields', - 'exactMatch', - ]; + const dateMapToKey: { [key: string]: string; } = { + 'createdOnFrom': '[createdOn][from]', + 'createdOnTo': '[createdOn][to]', + 'changeOnFrom': '[changeOn][from]', + 'changeOnTo': '[changeOn][to]', + }; - const isDate = [ - 'createdOnFrom', - 'createdOnTo', - 'changeOnFrom', - 'changeOnTo', - ]; - - const dateMapToKey: { [key: string]: string; } = { - 'createdOnFrom': '[createdOn][from]', - 'createdOnTo': '[createdOn][to]', - 'changeOnFrom': '[changeOn][from]', - 'changeOnTo': '[changeOn][to]', - }; - - for (const key of Object.keys(qs)) { - if (!isNotQuery.includes(key)) { - if (isDate.includes(key)) { - qs[`query${dateMapToKey[key]}`] = moment.tz(qs[key], timezone).format('YYYY-MM-DDTHH:mm:ssZZ'); - } else { - qs[`query[${key}]`] = qs[key]; + for (const key of Object.keys(qs)) { + if (!isNotQuery.includes(key)) { + if (isDate.includes(key)) { + qs[`query${dateMapToKey[key]}`] = moment.tz(qs[key], timezone).format('YYYY-MM-DDTHH:mm:ssZZ'); + } else { + qs[`query[${key}]`] = qs[key]; + } + delete qs[key]; } - delete qs[key]; + } + + if (qs.sortBy) { + qs[`sort[${qs.sortBy}]`] = qs.sortOrder || 'ASC'; + } + + if (qs.exactMatch === true) { + qs['additionalFlags'] = 'exactMatch'; + delete qs.exactMatch; + } + + if (returnAll) { + responseData = await getResponseApiRequestAllItems.call(this, 'GET', `/contacts`, {}, qs); + } else { + qs.perPage = this.getNodeParameter('limit', i) as number; + responseData = await getresponseApiRequest.call(this, 'GET', `/contacts`, {}, qs); } } + //https://apireference.getresponse.com/?_ga=2.160836350.2102802044.1604719933-1897033509.1604598019#operation/updateContact + if (operation === 'update') { - if (qs.sortBy) { - qs[`sort[${qs.sortBy}]`] = qs.sortOrder || 'ASC'; - } + const contactId = this.getNodeParameter('contactId', i) as string; - if (qs.exactMatch === true) { - qs['additionalFlags'] = 'exactMatch'; - delete qs.exactMatch; - } + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; - if (returnAll) { - responseData = await getResponseApiRequestAllItems.call(this, 'GET', `/contacts`, {}, qs); - } else { - qs.perPage = this.getNodeParameter('limit', i) as number; - responseData = await getresponseApiRequest.call(this, 'GET', `/contacts`, {}, qs); - } - } - //https://apireference.getresponse.com/?_ga=2.160836350.2102802044.1604719933-1897033509.1604598019#operation/updateContact - if (operation === 'update') { + const body: IDataObject = {}; - const contactId = this.getNodeParameter('contactId', i) as string; + Object.assign(body, updateFields); - const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; - - const body: IDataObject = {}; - - Object.assign(body, updateFields); - - if (updateFields.customFieldsUi) { - const customFieldValues = (updateFields.customFieldsUi as IDataObject).customFieldValues as IDataObject[]; - if (customFieldValues) { - body.customFieldValues = customFieldValues; - delete body.customFieldsUi; + if (updateFields.customFieldsUi) { + const customFieldValues = (updateFields.customFieldsUi as IDataObject).customFieldValues as IDataObject[]; + if (customFieldValues) { + body.customFieldValues = customFieldValues; + delete body.customFieldsUi; + } } + + responseData = await getresponseApiRequest.call(this, 'POST', `/contacts/${contactId}`, body); } - - responseData = await getresponseApiRequest.call(this, 'POST', `/contacts/${contactId}`, body); } - } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); + if (Array.isArray(responseData)) { + returnData.push.apply(returnData, responseData as IDataObject[]); - } else if (responseData !== undefined) { - returnData.push(responseData as IDataObject); + } else if (responseData !== undefined) { + returnData.push(responseData as IDataObject); + } + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } } return [this.helpers.returnJsonArray(returnData)]; diff --git a/packages/nodes-base/nodes/Ghost/Ghost.node.ts b/packages/nodes-base/nodes/Ghost/Ghost.node.ts index 0e52947639..f4a3239440 100644 --- a/packages/nodes-base/nodes/Ghost/Ghost.node.ts +++ b/packages/nodes-base/nodes/Ghost/Ghost.node.ts @@ -156,196 +156,204 @@ export class Ghost implements INodeType { const resource = this.getNodeParameter('resource', 0) as string; const operation = this.getNodeParameter('operation', 0) as string; const source = this.getNodeParameter('source', 0) as string; + for (let i = 0; i < length; i++) { + try { + if (source === 'contentApi') { + if (resource === 'post') { + if (operation === 'get') { - if (source === 'contentApi') { - if (resource === 'post') { - if (operation === 'get') { - for (let i = 0; i < items.length; i++) { - const by = this.getNodeParameter('by', i) as string; + const by = this.getNodeParameter('by', i) as string; - const identifier = this.getNodeParameter('identifier', i) as string; + const identifier = this.getNodeParameter('identifier', i) as string; - const options = this.getNodeParameter('options', i) as IDataObject; + const options = this.getNodeParameter('options', i) as IDataObject; - Object.assign(qs, options); + Object.assign(qs, options); - let endpoint; + let endpoint; - if (by === 'slug') { - endpoint = `/content/posts/slug/${identifier}`; - } else { - endpoint = `/content/posts/${identifier}`; - } - responseData = await ghostApiRequest.call(this, 'GET', endpoint, {}, qs); - - returnData.push.apply(returnData, responseData.posts); - } - } - - if (operation === 'getAll') { - for (let i = 0; i < items.length; i++) { - - const returnAll = this.getNodeParameter('returnAll', 0) as boolean; - - const options = this.getNodeParameter('options', i) as IDataObject; - - Object.assign(qs, options); - - if (returnAll) { - responseData = await ghostApiRequestAllItems.call(this, 'posts', 'GET', '/content/posts', {} ,qs); - } else { - qs.limit = this.getNodeParameter('limit', 0); - responseData = await ghostApiRequest.call(this, 'GET', '/content/posts', {}, qs); - responseData = responseData.posts; - } - - returnData.push.apply(returnData, responseData); - } - } - } - } - - if (source === 'adminApi') { - if (resource === 'post') { - if (operation === 'create') { - for (let i = 0; i < length; i++) { - const title = this.getNodeParameter('title', i) as string; - - const contentFormat = this.getNodeParameter('contentFormat', i) as string; - - const content = this.getNodeParameter('content', i) as string; - - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - - const post: IDataObject = { - title, - }; - - if (contentFormat === 'html') { - post.html = content; - qs.source = 'html'; - } else { - const mobileDoc = validateJSON(content); - if (mobileDoc === undefined) { - throw new NodeOperationError(this.getNode(), 'Content must be a valid JSON'); + if (by === 'slug') { + endpoint = `/content/posts/slug/${identifier}`; + } else { + endpoint = `/content/posts/${identifier}`; } - post.mobiledoc = content; + responseData = await ghostApiRequest.call(this, 'GET', endpoint, {}, qs); + + returnData.push.apply(returnData, responseData.posts); + } - delete post.content; + if (operation === 'getAll') { - Object.assign(post, additionalFields); + const returnAll = this.getNodeParameter('returnAll', 0) as boolean; - if (post.published_at) { - post.published_at = moment.tz(post.published_at, timezone).utc().format(); - } + const options = this.getNodeParameter('options', i) as IDataObject; - if (post.status === 'scheduled' && post.published_at === undefined) { - throw new NodeOperationError(this.getNode(), 'Published at must be define when status is scheduled'); - } + Object.assign(qs, options); - responseData = await ghostApiRequest.call(this, 'POST', '/admin/posts', { posts: [post] }, qs); - - returnData.push.apply(returnData, responseData.posts); - } - } - - if (operation === 'delete') { - for (let i = 0; i < length; i++) { - const postId = this.getNodeParameter('postId', i) as string; - - responseData = await ghostApiRequest.call(this, 'DELETE', `/admin/posts/${postId}`); - - returnData.push({ success: true }); - } - } - - if (operation === 'get') { - for (let i = 0; i < length; i++) { - const by = this.getNodeParameter('by', i) as string; - - const identifier = this.getNodeParameter('identifier', i) as string; - - const options = this.getNodeParameter('options', i) as IDataObject; - - Object.assign(qs, options); - - let endpoint; - - if (by === 'slug') { - endpoint = `/admin/posts/slug/${identifier}`; - } else { - endpoint = `/admin/posts/${identifier}`; - } - responseData = await ghostApiRequest.call(this, 'GET', endpoint, {}, qs); - - returnData.push.apply(returnData, responseData.posts); - } - } - - if (operation === 'getAll') { - for (let i = 0; i < length; i++) { - - const returnAll = this.getNodeParameter('returnAll', 0) as boolean; - - const options = this.getNodeParameter('options', i) as IDataObject; - - Object.assign(qs, options); - - if (returnAll) { - responseData = await ghostApiRequestAllItems.call(this, 'posts', 'GET', '/admin/posts', {} ,qs); - } else { - qs.limit = this.getNodeParameter('limit', 0); - responseData = await ghostApiRequest.call(this, 'GET', '/admin/posts', {}, qs); - responseData = responseData.posts; - } - - returnData.push.apply(returnData, responseData); - } - } - - if (operation === 'update') { - for (let i = 0; i < length; i++) { - const postId = this.getNodeParameter('postId', i) as string; - - const contentFormat = this.getNodeParameter('contentFormat', i) as string; - - const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; - - const post: IDataObject = {}; - - if (contentFormat === 'html') { - post.html = updateFields.content || ''; - qs.source = 'html'; - delete updateFields.content; - } else { - const mobileDoc = validateJSON(updateFields.contentJson as string || undefined); - if (mobileDoc === undefined) { - throw new NodeOperationError(this.getNode(), 'Content must be a valid JSON'); + if (returnAll) { + responseData = await ghostApiRequestAllItems.call(this, 'posts', 'GET', '/content/posts', {} ,qs); + } else { + qs.limit = this.getNodeParameter('limit', 0); + responseData = await ghostApiRequest.call(this, 'GET', '/content/posts', {}, qs); + responseData = responseData.posts; } - post.mobiledoc = updateFields.contentJson; - delete updateFields.contentJson; + + returnData.push.apply(returnData, responseData); + } - - Object.assign(post, updateFields); - - const { posts } = await ghostApiRequest.call(this, 'GET', `/admin/posts/${postId}`, {}, { fields: 'id, updated_at' }); - - if (post.published_at) { - post.published_at = moment.tz(post.published_at, timezone).utc().format(); - } - - if (post.status === 'scheduled' && post.published_at === undefined) { - throw new NodeOperationError(this.getNode(), 'Published at must be define when status is scheduled'); - } - - post.updated_at = posts[0].updated_at; - - responseData = await ghostApiRequest.call(this, 'PUT', `/admin/posts/${postId}`, { posts: [post] }, qs); - - returnData.push.apply(returnData, responseData.posts); } } + + if (source === 'adminApi') { + if (resource === 'post') { + if (operation === 'create') { + + const title = this.getNodeParameter('title', i) as string; + + const contentFormat = this.getNodeParameter('contentFormat', i) as string; + + const content = this.getNodeParameter('content', i) as string; + + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + + const post: IDataObject = { + title, + }; + + if (contentFormat === 'html') { + post.html = content; + qs.source = 'html'; + } else { + const mobileDoc = validateJSON(content); + if (mobileDoc === undefined) { + throw new NodeOperationError(this.getNode(), 'Content must be a valid JSON'); + } + post.mobiledoc = content; + } + + delete post.content; + + Object.assign(post, additionalFields); + + if (post.published_at) { + post.published_at = moment.tz(post.published_at, timezone).utc().format(); + } + + if (post.status === 'scheduled' && post.published_at === undefined) { + throw new NodeOperationError(this.getNode(), 'Published at must be define when status is scheduled'); + } + + responseData = await ghostApiRequest.call(this, 'POST', '/admin/posts', { posts: [post] }, qs); + + returnData.push.apply(returnData, responseData.posts); + + } + + if (operation === 'delete') { + + const postId = this.getNodeParameter('postId', i) as string; + + responseData = await ghostApiRequest.call(this, 'DELETE', `/admin/posts/${postId}`); + + returnData.push({ success: true }); + + } + + if (operation === 'get') { + + const by = this.getNodeParameter('by', i) as string; + + const identifier = this.getNodeParameter('identifier', i) as string; + + const options = this.getNodeParameter('options', i) as IDataObject; + + Object.assign(qs, options); + + let endpoint; + + if (by === 'slug') { + endpoint = `/admin/posts/slug/${identifier}`; + } else { + endpoint = `/admin/posts/${identifier}`; + } + responseData = await ghostApiRequest.call(this, 'GET', endpoint, {}, qs); + + returnData.push.apply(returnData, responseData.posts); + + } + + if (operation === 'getAll') { + + + const returnAll = this.getNodeParameter('returnAll', 0) as boolean; + + const options = this.getNodeParameter('options', i) as IDataObject; + + Object.assign(qs, options); + + if (returnAll) { + responseData = await ghostApiRequestAllItems.call(this, 'posts', 'GET', '/admin/posts', {} ,qs); + } else { + qs.limit = this.getNodeParameter('limit', 0); + responseData = await ghostApiRequest.call(this, 'GET', '/admin/posts', {}, qs); + responseData = responseData.posts; + } + + returnData.push.apply(returnData, responseData); + + } + + if (operation === 'update') { + + const postId = this.getNodeParameter('postId', i) as string; + + const contentFormat = this.getNodeParameter('contentFormat', i) as string; + + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + + const post: IDataObject = {}; + + if (contentFormat === 'html') { + post.html = updateFields.content || ''; + qs.source = 'html'; + delete updateFields.content; + } else { + const mobileDoc = validateJSON(updateFields.contentJson as string || undefined); + if (mobileDoc === undefined) { + throw new NodeOperationError(this.getNode(), 'Content must be a valid JSON'); + } + post.mobiledoc = updateFields.contentJson; + delete updateFields.contentJson; + } + + Object.assign(post, updateFields); + + const { posts } = await ghostApiRequest.call(this, 'GET', `/admin/posts/${postId}`, {}, { fields: 'id, updated_at' }); + + if (post.published_at) { + post.published_at = moment.tz(post.published_at, timezone).utc().format(); + } + + if (post.status === 'scheduled' && post.published_at === undefined) { + throw new NodeOperationError(this.getNode(), 'Published at must be define when status is scheduled'); + } + + post.updated_at = posts[0].updated_at; + + responseData = await ghostApiRequest.call(this, 'PUT', `/admin/posts/${postId}`, { posts: [post] }, qs); + + returnData.push.apply(returnData, responseData.posts); + + } + } + } + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } } return [this.helpers.returnJsonArray(returnData)]; diff --git a/packages/nodes-base/nodes/Github/Github.node.ts b/packages/nodes-base/nodes/Github/Github.node.ts index d39fa72b5f..8b2564d8b3 100644 --- a/packages/nodes-base/nodes/Github/Github.node.ts +++ b/packages/nodes-base/nodes/Github/Github.node.ts @@ -1754,421 +1754,434 @@ export class Github implements INodeType { const fullOperation = `${resource}:${operation}`; for (let i = 0; i < items.length; i++) { - // Reset all values - requestMethod = 'GET'; - endpoint = ''; - body = {}; - qs = {}; + try { + // Reset all values + requestMethod = 'GET'; + endpoint = ''; + body = {}; + qs = {}; - let owner = ''; - if (fullOperation !== 'user:invite') { - // Request the parameters which almost all operations need - owner = this.getNodeParameter('owner', i) as string; - } + let owner = ''; + if (fullOperation !== 'user:invite') { + // Request the parameters which almost all operations need + owner = this.getNodeParameter('owner', i) as string; + } - let repository = ''; - if (fullOperation !== 'user:getRepositories' && fullOperation !== 'user:invite') { - repository = this.getNodeParameter('repository', i) as string; - } + let repository = ''; + if (fullOperation !== 'user:getRepositories' && fullOperation !== 'user:invite') { + repository = this.getNodeParameter('repository', i) as string; + } - if (resource === 'file') { - if (['create', 'edit'].includes(operation)) { - // ---------------------------------- - // create/edit - // ---------------------------------- + if (resource === 'file') { + if (['create', 'edit'].includes(operation)) { + // ---------------------------------- + // create/edit + // ---------------------------------- - requestMethod = 'PUT'; + requestMethod = 'PUT'; - const filePath = this.getNodeParameter('filePath', i) as string; + const filePath = this.getNodeParameter('filePath', i) as string; - const additionalParameters = this.getNodeParameter('additionalParameters', i, {}) as IDataObject; - if (additionalParameters.author) { - body.author = additionalParameters.author; - } - if (additionalParameters.committer) { - body.committer = additionalParameters.committer; - } - if (additionalParameters.branch && (additionalParameters.branch as IDataObject).branch) { - body.branch = (additionalParameters.branch as IDataObject).branch; - } - - if (operation === 'edit') { - // If the file should be updated the request has to contain the SHA - // of the file which gets replaced. - body.sha = await getFileSha.call(this, owner, repository, filePath, body.branch as string | undefined); - } - - body.message = this.getNodeParameter('commitMessage', i) as string; - - if (this.getNodeParameter('binaryData', i) === true) { - // Is binary file to upload - const item = items[i]; - - if (item.binary === undefined) { - throw new NodeOperationError(this.getNode(), 'No binary data exists on item!'); + const additionalParameters = this.getNodeParameter('additionalParameters', i, {}) as IDataObject; + if (additionalParameters.author) { + body.author = additionalParameters.author; + } + if (additionalParameters.committer) { + body.committer = additionalParameters.committer; + } + if (additionalParameters.branch && (additionalParameters.branch as IDataObject).branch) { + body.branch = (additionalParameters.branch as IDataObject).branch; } + if (operation === 'edit') { + // If the file should be updated the request has to contain the SHA + // of the file which gets replaced. + body.sha = await getFileSha.call(this, owner, repository, filePath, body.branch as string | undefined); + } + + body.message = this.getNodeParameter('commitMessage', i) as string; + + if (this.getNodeParameter('binaryData', i) === true) { + // Is binary file to upload + const item = items[i]; + + if (item.binary === undefined) { + throw new NodeOperationError(this.getNode(), 'No binary data exists on item!'); + } + + const binaryPropertyName = this.getNodeParameter('binaryPropertyName', i) as string; + + if (item.binary[binaryPropertyName] === undefined) { + throw new NodeOperationError(this.getNode(), `No binary data property "${binaryPropertyName}" does not exists on item!`); + } + + // Currently internally n8n uses base64 and also Github expects it base64 encoded. + // If that ever changes the data has to get converted here. + body.content = item.binary[binaryPropertyName].data; + } else { + // Is text file + // body.content = Buffer.from(this.getNodeParameter('fileContent', i) as string, 'base64'); + body.content = Buffer.from(this.getNodeParameter('fileContent', i) as string).toString('base64'); + } + + endpoint = `/repos/${owner}/${repository}/contents/${encodeURI(filePath)}`; + } else if (operation === 'delete') { + // ---------------------------------- + // delete + // ---------------------------------- + + requestMethod = 'DELETE'; + + const additionalParameters = this.getNodeParameter('additionalParameters', i, {}) as IDataObject; + if (additionalParameters.author) { + body.author = additionalParameters.author; + } + if (additionalParameters.committer) { + body.committer = additionalParameters.committer; + } + if (additionalParameters.branch && (additionalParameters.branch as IDataObject).branch) { + body.branch = (additionalParameters.branch as IDataObject).branch; + } + + const filePath = this.getNodeParameter('filePath', i) as string; + body.message = this.getNodeParameter('commitMessage', i) as string; + + body.sha = await getFileSha.call(this, owner, repository, filePath, body.branch as string | undefined); + + endpoint = `/repos/${owner}/${repository}/contents/${encodeURI(filePath)}`; + } else if (operation === 'get') { + requestMethod = 'GET'; + + const filePath = this.getNodeParameter('filePath', i) as string; + + endpoint = `/repos/${owner}/${repository}/contents/${encodeURI(filePath)}`; + } + } else if (resource === 'issue') { + if (operation === 'create') { + // ---------------------------------- + // create + // ---------------------------------- + + requestMethod = 'POST'; + + body.title = this.getNodeParameter('title', i) as string; + body.body = this.getNodeParameter('body', i) as string; + const labels = this.getNodeParameter('labels', i) as IDataObject[]; + + const assignees = this.getNodeParameter('assignees', i) as IDataObject[]; + + body.labels = labels.map((data) => data['label']); + body.assignees = assignees.map((data) => data['assignee']); + + endpoint = `/repos/${owner}/${repository}/issues`; + } else if (operation === 'createComment') { + // ---------------------------------- + // createComment + // ---------------------------------- + requestMethod = 'POST'; + + const issueNumber = this.getNodeParameter('issueNumber', i) as string; + + body.body = this.getNodeParameter('body', i) as string; + + endpoint = `/repos/${owner}/${repository}/issues/${issueNumber}/comments`; + } else if (operation === 'edit') { + // ---------------------------------- + // edit + // ---------------------------------- + + requestMethod = 'PATCH'; + + const issueNumber = this.getNodeParameter('issueNumber', i) as string; + + body = this.getNodeParameter('editFields', i, {}) as IDataObject; + + if (body.labels !== undefined) { + body.labels = (body.labels as IDataObject[]).map((data) => data['label']); + } + if (body.assignees !== undefined) { + body.assignees = (body.assignees as IDataObject[]).map((data) => data['assignee']); + } + + endpoint = `/repos/${owner}/${repository}/issues/${issueNumber}`; + } else if (operation === 'get') { + // ---------------------------------- + // get + // ---------------------------------- + + requestMethod = 'GET'; + + const issueNumber = this.getNodeParameter('issueNumber', i) as string; + + endpoint = `/repos/${owner}/${repository}/issues/${issueNumber}`; + } else if (operation === 'lock') { + // ---------------------------------- + // lock + // ---------------------------------- + + requestMethod = 'PUT'; + + const issueNumber = this.getNodeParameter('issueNumber', i) as string; + + qs.lock_reason = this.getNodeParameter('lockReason', i) as string; + + endpoint = `/repos/${owner}/${repository}/issues/${issueNumber}/lock`; + } + } else if (resource === 'release') { + if (operation === 'create') { + // ---------------------------------- + // create + // ---------------------------------- + + requestMethod = 'POST'; + + body = this.getNodeParameter('additionalFields', i, {}) as IDataObject; + + body.tag_name = this.getNodeParameter('releaseTag', i) as string; + + endpoint = `/repos/${owner}/${repository}/releases`; + } + if (operation === 'delete') { + // ---------------------------------- + // delete + // ---------------------------------- + + requestMethod = 'DELETE'; + + const releaseId = this.getNodeParameter('release_id', i) as string; + + endpoint = `/repos/${owner}/${repository}/releases/${releaseId}`; + } + if (operation === 'get') { + // ---------------------------------- + // get + // ---------------------------------- + + requestMethod = 'GET'; + + const releaseId = this.getNodeParameter('release_id', i) as string; + + endpoint = `/repos/${owner}/${repository}/releases/${releaseId}`; + } + if (operation === 'getAll') { + // ---------------------------------- + // getAll + // ---------------------------------- + + requestMethod = 'GET'; + + endpoint = `/repos/${owner}/${repository}/releases`; + + returnAll = this.getNodeParameter('returnAll', 0) as boolean; + + if (returnAll === false) { + qs.per_page = this.getNodeParameter('limit', 0) as number; + } + } + if (operation === 'update') { + // ---------------------------------- + // update + // ---------------------------------- + + requestMethod = 'PATCH'; + + const releaseId = this.getNodeParameter('release_id', i) as string; + + body = this.getNodeParameter('additionalFields', i, {}) as IDataObject; + + endpoint = `/repos/${owner}/${repository}/releases/${releaseId}`; + } + } else if (resource === 'repository') { + if (operation === 'listPopularPaths') { + // ---------------------------------- + // listPopularPaths + // ---------------------------------- + + requestMethod = 'GET'; + + endpoint = `/repos/${owner}/${repository}/traffic/popular/paths`; + } else if (operation === 'listReferrers') { + // ---------------------------------- + // listReferrers + // ---------------------------------- + + requestMethod = 'GET'; + + endpoint = `/repos/${owner}/${repository}/traffic/popular/referrers`; + } else if (operation === 'get') { + // ---------------------------------- + // get + // ---------------------------------- + + requestMethod = 'GET'; + + endpoint = `/repos/${owner}/${repository}`; + } else if (operation === 'getLicense') { + // ---------------------------------- + // getLicense + // ---------------------------------- + + requestMethod = 'GET'; + + endpoint = `/repos/${owner}/${repository}/license`; + } else if (operation === 'getIssues') { + // ---------------------------------- + // getIssues + // ---------------------------------- + + requestMethod = 'GET'; + + qs = this.getNodeParameter('getRepositoryIssuesFilters', i) as IDataObject; + + endpoint = `/repos/${owner}/${repository}/issues`; + + returnAll = this.getNodeParameter('returnAll', 0) as boolean; + + if (returnAll === false) { + qs.per_page = this.getNodeParameter('limit', 0) as number; + } + } + } else if (resource === 'review') { + if (operation === 'get') { + // ---------------------------------- + // get + // ---------------------------------- + requestMethod = 'GET'; + + const reviewId = this.getNodeParameter('reviewId', i) as string; + + const pullRequestNumber = this.getNodeParameter('pullRequestNumber', i) as string; + + endpoint = `/repos/${owner}/${repository}/pulls/${pullRequestNumber}/reviews/${reviewId}`; + + } else if (operation === 'getAll') { + // ---------------------------------- + // getAll + // ---------------------------------- + requestMethod = 'GET'; + + returnAll = this.getNodeParameter('returnAll', 0) as boolean; + + const pullRequestNumber = this.getNodeParameter('pullRequestNumber', i) as string; + + if (returnAll === false) { + qs.per_page = this.getNodeParameter('limit', 0) as number; + } + + endpoint = `/repos/${owner}/${repository}/pulls/${pullRequestNumber}/reviews`; + } else if (operation === 'create') { + // ---------------------------------- + // create + // ---------------------------------- + requestMethod = 'POST'; + + const pullRequestNumber = this.getNodeParameter('pullRequestNumber', i) as string; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + Object.assign(body, additionalFields); + + body.event = snakeCase(this.getNodeParameter('event', i) as string).toUpperCase(); + if (body.event === 'REQUEST_CHANGES' || body.event === 'COMMENT') { + body.body = this.getNodeParameter('body', i) as string; + } + + endpoint = `/repos/${owner}/${repository}/pulls/${pullRequestNumber}/reviews`; + } else if (operation === 'update') { + // ---------------------------------- + // update + // ---------------------------------- + requestMethod = 'PUT'; + + const pullRequestNumber = this.getNodeParameter('pullRequestNumber', i) as string; + const reviewId = this.getNodeParameter('reviewId', i) as string; + + body.body = this.getNodeParameter('body', i) as string; + + endpoint = `/repos/${owner}/${repository}/pulls/${pullRequestNumber}/reviews/${reviewId}`; + } + } else if (resource === 'user') { + if (operation === 'getRepositories') { + // ---------------------------------- + // getRepositories + // ---------------------------------- + + requestMethod = 'GET'; + + endpoint = `/users/${owner}/repos`; + + returnAll = this.getNodeParameter('returnAll', 0) as boolean; + + if (returnAll === false) { + qs.per_page = this.getNodeParameter('limit', 0) as number; + } + + } else if (operation === 'invite') { + // ---------------------------------- + // invite + // ---------------------------------- + + requestMethod = 'POST'; + const org = this.getNodeParameter('organization', i) as string; + endpoint = `/orgs/${org}/invitations`; + body.email = this.getNodeParameter('email', i) as string; + + } + + } else { + throw new NodeOperationError(this.getNode(), `The resource "${resource}" is not known!`); + } + + if (returnAll === true) { + responseData = await githubApiRequestAllItems.call(this, requestMethod, endpoint, body, qs); + } else { + responseData = await githubApiRequest.call(this, requestMethod, endpoint, body, qs); + } + + if (fullOperation === 'file:get') { + const asBinaryProperty = this.getNodeParameter('asBinaryProperty', i); + + if (asBinaryProperty === true) { + // Add the returned data to the item as binary property const binaryPropertyName = this.getNodeParameter('binaryPropertyName', i) as string; - if (item.binary[binaryPropertyName] === undefined) { - throw new NodeOperationError(this.getNode(), `No binary data property "${binaryPropertyName}" does not exists on item!`); + const newItem: INodeExecutionData = { + json: items[i].json, + binary: {}, + }; + + if (items[i].binary !== undefined) { + // Create a shallow copy of the binary data so that the old + // data references which do not get changed still stay behind + // but the incoming data does not get changed. + Object.assign(newItem.binary, items[i].binary); } - // Currently internally n8n uses base64 and also Github expects it base64 encoded. - // If that ever changes the data has to get converted here. - body.content = item.binary[binaryPropertyName].data; + newItem.binary![binaryPropertyName] = await this.helpers.prepareBinaryData(Buffer.from(responseData.content, 'base64'), responseData.path); + + items[i] = newItem; + + return this.prepareOutputData(items); + } + } + if (fullOperation === 'release:delete') { + responseData = { success: true }; + } + + if (overwriteDataOperations.includes(fullOperation)) { + returnData.push(responseData); + } else if (overwriteDataOperationsArray.includes(fullOperation)) { + returnData.push.apply(returnData, responseData); + } + + } catch (error) { + if (this.continueOnFail()) { + if (overwriteDataOperations.includes(fullOperation) || overwriteDataOperationsArray.includes(fullOperation)) { + returnData.push({ error: error.message }); } else { - // Is text file - // body.content = Buffer.from(this.getNodeParameter('fileContent', i) as string, 'base64'); - body.content = Buffer.from(this.getNodeParameter('fileContent', i) as string).toString('base64'); + items[i].json = { error: error.message }; } - - endpoint = `/repos/${owner}/${repository}/contents/${encodeURI(filePath)}`; - } else if (operation === 'delete') { - // ---------------------------------- - // delete - // ---------------------------------- - - requestMethod = 'DELETE'; - - const additionalParameters = this.getNodeParameter('additionalParameters', i, {}) as IDataObject; - if (additionalParameters.author) { - body.author = additionalParameters.author; - } - if (additionalParameters.committer) { - body.committer = additionalParameters.committer; - } - if (additionalParameters.branch && (additionalParameters.branch as IDataObject).branch) { - body.branch = (additionalParameters.branch as IDataObject).branch; - } - - const filePath = this.getNodeParameter('filePath', i) as string; - body.message = this.getNodeParameter('commitMessage', i) as string; - - body.sha = await getFileSha.call(this, owner, repository, filePath, body.branch as string | undefined); - - endpoint = `/repos/${owner}/${repository}/contents/${encodeURI(filePath)}`; - } else if (operation === 'get') { - requestMethod = 'GET'; - - const filePath = this.getNodeParameter('filePath', i) as string; - - endpoint = `/repos/${owner}/${repository}/contents/${encodeURI(filePath)}`; + continue; } - } else if (resource === 'issue') { - if (operation === 'create') { - // ---------------------------------- - // create - // ---------------------------------- - - requestMethod = 'POST'; - - body.title = this.getNodeParameter('title', i) as string; - body.body = this.getNodeParameter('body', i) as string; - const labels = this.getNodeParameter('labels', i) as IDataObject[]; - - const assignees = this.getNodeParameter('assignees', i) as IDataObject[]; - - body.labels = labels.map((data) => data['label']); - body.assignees = assignees.map((data) => data['assignee']); - - endpoint = `/repos/${owner}/${repository}/issues`; - } else if (operation === 'createComment') { - // ---------------------------------- - // createComment - // ---------------------------------- - requestMethod = 'POST'; - - const issueNumber = this.getNodeParameter('issueNumber', i) as string; - - body.body = this.getNodeParameter('body', i) as string; - - endpoint = `/repos/${owner}/${repository}/issues/${issueNumber}/comments`; - } else if (operation === 'edit') { - // ---------------------------------- - // edit - // ---------------------------------- - - requestMethod = 'PATCH'; - - const issueNumber = this.getNodeParameter('issueNumber', i) as string; - - body = this.getNodeParameter('editFields', i, {}) as IDataObject; - - if (body.labels !== undefined) { - body.labels = (body.labels as IDataObject[]).map((data) => data['label']); - } - if (body.assignees !== undefined) { - body.assignees = (body.assignees as IDataObject[]).map((data) => data['assignee']); - } - - endpoint = `/repos/${owner}/${repository}/issues/${issueNumber}`; - } else if (operation === 'get') { - // ---------------------------------- - // get - // ---------------------------------- - - requestMethod = 'GET'; - - const issueNumber = this.getNodeParameter('issueNumber', i) as string; - - endpoint = `/repos/${owner}/${repository}/issues/${issueNumber}`; - } else if (operation === 'lock') { - // ---------------------------------- - // lock - // ---------------------------------- - - requestMethod = 'PUT'; - - const issueNumber = this.getNodeParameter('issueNumber', i) as string; - - qs.lock_reason = this.getNodeParameter('lockReason', i) as string; - - endpoint = `/repos/${owner}/${repository}/issues/${issueNumber}/lock`; - } - } else if (resource === 'release') { - if (operation === 'create') { - // ---------------------------------- - // create - // ---------------------------------- - - requestMethod = 'POST'; - - body = this.getNodeParameter('additionalFields', i, {}) as IDataObject; - - body.tag_name = this.getNodeParameter('releaseTag', i) as string; - - endpoint = `/repos/${owner}/${repository}/releases`; - } - if (operation === 'delete') { - // ---------------------------------- - // delete - // ---------------------------------- - - requestMethod = 'DELETE'; - - const releaseId = this.getNodeParameter('release_id', i) as string; - - endpoint = `/repos/${owner}/${repository}/releases/${releaseId}`; - } - if (operation === 'get') { - // ---------------------------------- - // get - // ---------------------------------- - - requestMethod = 'GET'; - - const releaseId = this.getNodeParameter('release_id', i) as string; - - endpoint = `/repos/${owner}/${repository}/releases/${releaseId}`; - } - if (operation === 'getAll') { - // ---------------------------------- - // getAll - // ---------------------------------- - - requestMethod = 'GET'; - - endpoint = `/repos/${owner}/${repository}/releases`; - - returnAll = this.getNodeParameter('returnAll', 0) as boolean; - - if (returnAll === false) { - qs.per_page = this.getNodeParameter('limit', 0) as number; - } - } - if (operation === 'update') { - // ---------------------------------- - // update - // ---------------------------------- - - requestMethod = 'PATCH'; - - const releaseId = this.getNodeParameter('release_id', i) as string; - - body = this.getNodeParameter('additionalFields', i, {}) as IDataObject; - - endpoint = `/repos/${owner}/${repository}/releases/${releaseId}`; - } - } else if (resource === 'repository') { - if (operation === 'listPopularPaths') { - // ---------------------------------- - // listPopularPaths - // ---------------------------------- - - requestMethod = 'GET'; - - endpoint = `/repos/${owner}/${repository}/traffic/popular/paths`; - } else if (operation === 'listReferrers') { - // ---------------------------------- - // listReferrers - // ---------------------------------- - - requestMethod = 'GET'; - - endpoint = `/repos/${owner}/${repository}/traffic/popular/referrers`; - } else if (operation === 'get') { - // ---------------------------------- - // get - // ---------------------------------- - - requestMethod = 'GET'; - - endpoint = `/repos/${owner}/${repository}`; - } else if (operation === 'getLicense') { - // ---------------------------------- - // getLicense - // ---------------------------------- - - requestMethod = 'GET'; - - endpoint = `/repos/${owner}/${repository}/license`; - } else if (operation === 'getIssues') { - // ---------------------------------- - // getIssues - // ---------------------------------- - - requestMethod = 'GET'; - - qs = this.getNodeParameter('getRepositoryIssuesFilters', i) as IDataObject; - - endpoint = `/repos/${owner}/${repository}/issues`; - - returnAll = this.getNodeParameter('returnAll', 0) as boolean; - - if (returnAll === false) { - qs.per_page = this.getNodeParameter('limit', 0) as number; - } - } - } else if (resource === 'review') { - if (operation === 'get') { - // ---------------------------------- - // get - // ---------------------------------- - requestMethod = 'GET'; - - const reviewId = this.getNodeParameter('reviewId', i) as string; - - const pullRequestNumber = this.getNodeParameter('pullRequestNumber', i) as string; - - endpoint = `/repos/${owner}/${repository}/pulls/${pullRequestNumber}/reviews/${reviewId}`; - - } else if (operation === 'getAll') { - // ---------------------------------- - // getAll - // ---------------------------------- - requestMethod = 'GET'; - - returnAll = this.getNodeParameter('returnAll', 0) as boolean; - - const pullRequestNumber = this.getNodeParameter('pullRequestNumber', i) as string; - - if (returnAll === false) { - qs.per_page = this.getNodeParameter('limit', 0) as number; - } - - endpoint = `/repos/${owner}/${repository}/pulls/${pullRequestNumber}/reviews`; - } else if (operation === 'create') { - // ---------------------------------- - // create - // ---------------------------------- - requestMethod = 'POST'; - - const pullRequestNumber = this.getNodeParameter('pullRequestNumber', i) as string; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - Object.assign(body, additionalFields); - - body.event = snakeCase(this.getNodeParameter('event', i) as string).toUpperCase(); - if (body.event === 'REQUEST_CHANGES' || body.event === 'COMMENT') { - body.body = this.getNodeParameter('body', i) as string; - } - - endpoint = `/repos/${owner}/${repository}/pulls/${pullRequestNumber}/reviews`; - } else if (operation === 'update') { - // ---------------------------------- - // update - // ---------------------------------- - requestMethod = 'PUT'; - - const pullRequestNumber = this.getNodeParameter('pullRequestNumber', i) as string; - const reviewId = this.getNodeParameter('reviewId', i) as string; - - body.body = this.getNodeParameter('body', i) as string; - - endpoint = `/repos/${owner}/${repository}/pulls/${pullRequestNumber}/reviews/${reviewId}`; - } - } else if (resource === 'user') { - if (operation === 'getRepositories') { - // ---------------------------------- - // getRepositories - // ---------------------------------- - - requestMethod = 'GET'; - - endpoint = `/users/${owner}/repos`; - - returnAll = this.getNodeParameter('returnAll', 0) as boolean; - - if (returnAll === false) { - qs.per_page = this.getNodeParameter('limit', 0) as number; - } - - } else if (operation === 'invite') { - // ---------------------------------- - // invite - // ---------------------------------- - - requestMethod = 'POST'; - const org = this.getNodeParameter('organization', i) as string; - endpoint = `/orgs/${org}/invitations`; - body.email = this.getNodeParameter('email', i) as string; - - } - - } else { - throw new NodeOperationError(this.getNode(), `The resource "${resource}" is not known!`); - } - - if (returnAll === true) { - responseData = await githubApiRequestAllItems.call(this, requestMethod, endpoint, body, qs); - } else { - responseData = await githubApiRequest.call(this, requestMethod, endpoint, body, qs); - } - - if (fullOperation === 'file:get') { - const asBinaryProperty = this.getNodeParameter('asBinaryProperty', i); - - if (asBinaryProperty === true) { - // Add the returned data to the item as binary property - const binaryPropertyName = this.getNodeParameter('binaryPropertyName', i) as string; - - const newItem: INodeExecutionData = { - json: items[i].json, - binary: {}, - }; - - if (items[i].binary !== undefined) { - // Create a shallow copy of the binary data so that the old - // data references which do not get changed still stay behind - // but the incoming data does not get changed. - Object.assign(newItem.binary, items[i].binary); - } - - newItem.binary![binaryPropertyName] = await this.helpers.prepareBinaryData(Buffer.from(responseData.content, 'base64'), responseData.path); - - items[i] = newItem; - - return this.prepareOutputData(items); - } - } - if (fullOperation === 'release:delete') { - responseData = { success: true }; - } - - if (overwriteDataOperations.includes(fullOperation)) { - returnData.push(responseData); - } else if (overwriteDataOperationsArray.includes(fullOperation)) { - returnData.push.apply(returnData, responseData); + throw error; } } diff --git a/packages/nodes-base/nodes/Gitlab/Gitlab.node.ts b/packages/nodes-base/nodes/Gitlab/Gitlab.node.ts index fc2a175430..dda2651879 100644 --- a/packages/nodes-base/nodes/Gitlab/Gitlab.node.ts +++ b/packages/nodes-base/nodes/Gitlab/Gitlab.node.ts @@ -1114,6 +1114,9 @@ export class Gitlab implements INodeType { } } } catch (error) { + if (this.continueOnFail()) { + return [this.helpers.returnJsonArray([{ error: error.message }])]; + } throw new NodeOperationError(this.getNode(), error); } @@ -1152,218 +1155,230 @@ export class Gitlab implements INodeType { const fullOperation = `${resource}:${operation}`; for (let i = 0; i < items.length; i++) { - // Reset all values - requestMethod = 'GET'; - endpoint = ''; - body = {}; - qs = {}; + try { + // Reset all values + requestMethod = 'GET'; + endpoint = ''; + body = {}; + qs = {}; - // Request the parameters which almost all operations need - let owner = this.getNodeParameter('owner', i) as string; + // Request the parameters which almost all operations need + let owner = this.getNodeParameter('owner', i) as string; - // Replace all slashes to work with subgroups - owner = owner.replace(new RegExp(/\//g), '%2F'); + // Replace all slashes to work with subgroups + owner = owner.replace(new RegExp(/\//g), '%2F'); - let repository = ''; - if (fullOperation !== 'user:getRepositories') { - repository = this.getNodeParameter('repository', i) as string; - } + let repository = ''; + if (fullOperation !== 'user:getRepositories') { + repository = this.getNodeParameter('repository', i) as string; + } - const baseEndpoint = `/projects/${owner}%2F${repository}`; + const baseEndpoint = `/projects/${owner}%2F${repository}`; - if (resource === 'issue') { - if (operation === 'create') { - // ---------------------------------- - // create - // ---------------------------------- + if (resource === 'issue') { + if (operation === 'create') { + // ---------------------------------- + // create + // ---------------------------------- - requestMethod = 'POST'; + requestMethod = 'POST'; - body.title = this.getNodeParameter('title', i) as string; - body.description = this.getNodeParameter('body', i) as string; - body.due_date = this.getNodeParameter('due_date', i) as string; - const labels = this.getNodeParameter('labels', i) as IDataObject[]; + body.title = this.getNodeParameter('title', i) as string; + body.description = this.getNodeParameter('body', i) as string; + body.due_date = this.getNodeParameter('due_date', i) as string; + const labels = this.getNodeParameter('labels', i) as IDataObject[]; - const assigneeIds = this.getNodeParameter('assignee_ids', i) as IDataObject[]; + const assigneeIds = this.getNodeParameter('assignee_ids', i) as IDataObject[]; - body.labels = labels.map((data) => data['label']).join(','); - body.assignee_ids = assigneeIds.map((data) => data['assignee']); + body.labels = labels.map((data) => data['label']).join(','); + body.assignee_ids = assigneeIds.map((data) => data['assignee']); - endpoint = `${baseEndpoint}/issues`; - } else if (operation === 'createComment') { - // ---------------------------------- - // createComment - // ---------------------------------- - requestMethod = 'POST'; + endpoint = `${baseEndpoint}/issues`; + } else if (operation === 'createComment') { + // ---------------------------------- + // createComment + // ---------------------------------- + requestMethod = 'POST'; - const issueNumber = this.getNodeParameter('issueNumber', i) as string; + const issueNumber = this.getNodeParameter('issueNumber', i) as string; - body.body = this.getNodeParameter('body', i) as string; + body.body = this.getNodeParameter('body', i) as string; - endpoint = `${baseEndpoint}/issues/${issueNumber}/notes`; - } else if (operation === 'edit') { - // ---------------------------------- - // edit - // ---------------------------------- + endpoint = `${baseEndpoint}/issues/${issueNumber}/notes`; + } else if (operation === 'edit') { + // ---------------------------------- + // edit + // ---------------------------------- - requestMethod = 'PUT'; + requestMethod = 'PUT'; - const issueNumber = this.getNodeParameter('issueNumber', i) as string; + const issueNumber = this.getNodeParameter('issueNumber', i) as string; - body = this.getNodeParameter('editFields', i, {}) as IDataObject; + body = this.getNodeParameter('editFields', i, {}) as IDataObject; - if (body.labels !== undefined) { - body.labels = (body.labels as IDataObject[]).map((data) => data['label']).join(','); + if (body.labels !== undefined) { + body.labels = (body.labels as IDataObject[]).map((data) => data['label']).join(','); + } + if (body.assignee_ids !== undefined) { + body.assignee_ids = (body.assignee_ids as IDataObject[]).map((data) => data['assignee']); + } + + endpoint = `${baseEndpoint}/issues/${issueNumber}`; + } else if (operation === 'get') { + // ---------------------------------- + // get + // ---------------------------------- + + requestMethod = 'GET'; + + const issueNumber = this.getNodeParameter('issueNumber', i) as string; + + endpoint = `${baseEndpoint}/issues/${issueNumber}`; + } else if (operation === 'lock') { + // ---------------------------------- + // lock + // ---------------------------------- + + requestMethod = 'PUT'; + + const issueNumber = this.getNodeParameter('issueNumber', i) as string; + + body.discussion_locked = true; + + endpoint = `${baseEndpoint}/issues/${issueNumber}`; } - if (body.assignee_ids !== undefined) { - body.assignee_ids = (body.assignee_ids as IDataObject[]).map((data) => data['assignee']); + } else if (resource === 'release') { + if (operation === 'create') { + // ---------------------------------- + // create + // ---------------------------------- + + requestMethod = 'POST'; + + body = this.getNodeParameter('additionalFields', i, {}) as IDataObject; + + body.tag_name = this.getNodeParameter('releaseTag', i) as string; + + endpoint = `${baseEndpoint}/releases`; } + if (operation === 'delete') { + // ---------------------------------- + // delete + // ---------------------------------- - endpoint = `${baseEndpoint}/issues/${issueNumber}`; - } else if (operation === 'get') { - // ---------------------------------- - // get - // ---------------------------------- + requestMethod = 'DELETE'; - requestMethod = 'GET'; + const id = this.getNodeParameter('projectId', i) as string; - const issueNumber = this.getNodeParameter('issueNumber', i) as string; + const tagName = this.getNodeParameter('tag_name', i) as string; - endpoint = `${baseEndpoint}/issues/${issueNumber}`; - } else if (operation === 'lock') { - // ---------------------------------- - // lock - // ---------------------------------- - - requestMethod = 'PUT'; - - const issueNumber = this.getNodeParameter('issueNumber', i) as string; - - body.discussion_locked = true; - - endpoint = `${baseEndpoint}/issues/${issueNumber}`; - } - } else if (resource === 'release') { - if (operation === 'create') { - // ---------------------------------- - // create - // ---------------------------------- - - requestMethod = 'POST'; - - body = this.getNodeParameter('additionalFields', i, {}) as IDataObject; - - body.tag_name = this.getNodeParameter('releaseTag', i) as string; - - endpoint = `${baseEndpoint}/releases`; - } - if (operation === 'delete') { - // ---------------------------------- - // delete - // ---------------------------------- - - requestMethod = 'DELETE'; - - const id = this.getNodeParameter('projectId', i) as string; - - const tagName = this.getNodeParameter('tag_name', i) as string; - - endpoint = `/projects/${id}/releases/${tagName}`; - } - if (operation === 'get') { - // ---------------------------------- - // get - // ---------------------------------- - - requestMethod = 'GET'; - - const id = this.getNodeParameter('projectId', i) as string; - - const tagName = this.getNodeParameter('tag_name', i) as string; - - endpoint = `/projects/${id}/releases/${tagName}`; - } - if (operation === 'getAll') { - // ---------------------------------- - // getAll - // ---------------------------------- - - requestMethod = 'GET'; - - const id = this.getNodeParameter('projectId', i) as string; - - qs = this.getNodeParameter('additionalFields', i, {}) as IDataObject; - - returnAll = this.getNodeParameter('returnAll', 0) as boolean; - - if (returnAll === false) { - qs.per_page = this.getNodeParameter('limit', 0) as number; + endpoint = `/projects/${id}/releases/${tagName}`; } + if (operation === 'get') { + // ---------------------------------- + // get + // ---------------------------------- - endpoint = `/projects/${id}/releases`; - } - if (operation === 'update') { - // ---------------------------------- - // update - // ---------------------------------- + requestMethod = 'GET'; - requestMethod = 'PUT'; + const id = this.getNodeParameter('projectId', i) as string; - const id = this.getNodeParameter('projectId', i) as string; + const tagName = this.getNodeParameter('tag_name', i) as string; - const tagName = this.getNodeParameter('tag_name', i) as string; - - body = this.getNodeParameter('additionalFields', i, {}) as IDataObject; - if(body.milestones){ - body.milestones = (body.milestones as string).split(','); + endpoint = `/projects/${id}/releases/${tagName}`; } + if (operation === 'getAll') { + // ---------------------------------- + // getAll + // ---------------------------------- - endpoint = `/projects/${id}/releases/${tagName}`; + requestMethod = 'GET'; + + const id = this.getNodeParameter('projectId', i) as string; + + qs = this.getNodeParameter('additionalFields', i, {}) as IDataObject; + + returnAll = this.getNodeParameter('returnAll', 0) as boolean; + + if (returnAll === false) { + qs.per_page = this.getNodeParameter('limit', 0) as number; + } + + endpoint = `/projects/${id}/releases`; + } + if (operation === 'update') { + // ---------------------------------- + // update + // ---------------------------------- + + requestMethod = 'PUT'; + + const id = this.getNodeParameter('projectId', i) as string; + + const tagName = this.getNodeParameter('tag_name', i) as string; + + body = this.getNodeParameter('additionalFields', i, {}) as IDataObject; + if(body.milestones){ + body.milestones = (body.milestones as string).split(','); + } + + endpoint = `/projects/${id}/releases/${tagName}`; + } + } else if (resource === 'repository') { + if (operation === 'get') { + // ---------------------------------- + // get + // ---------------------------------- + + requestMethod = 'GET'; + + endpoint = `${baseEndpoint}`; + } else if (operation === 'getIssues') { + // ---------------------------------- + // getIssues + // ---------------------------------- + + requestMethod = 'GET'; + + qs = this.getNodeParameter('getRepositoryIssuesFilters', i) as IDataObject; + + endpoint = `${baseEndpoint}/issues`; + } + } else if (resource === 'user') { + if (operation === 'getRepositories') { + // ---------------------------------- + // getRepositories + // ---------------------------------- + + requestMethod = 'GET'; + + endpoint = `/users/${owner}/projects`; + } + } else { + throw new NodeOperationError(this.getNode(), `The resource "${resource}" is not known!`); } - } else if (resource === 'repository') { - if (operation === 'get') { - // ---------------------------------- - // get - // ---------------------------------- - requestMethod = 'GET'; - - endpoint = `${baseEndpoint}`; - } else if (operation === 'getIssues') { - // ---------------------------------- - // getIssues - // ---------------------------------- - - requestMethod = 'GET'; - - qs = this.getNodeParameter('getRepositoryIssuesFilters', i) as IDataObject; - - endpoint = `${baseEndpoint}/issues`; + if (returnAll === true) { + responseData = await gitlabApiRequestAllItems.call(this, requestMethod, endpoint, body, qs); + } else { + responseData = await gitlabApiRequest.call(this, requestMethod, endpoint, body, qs); } - } else if (resource === 'user') { - if (operation === 'getRepositories') { - // ---------------------------------- - // getRepositories - // ---------------------------------- - requestMethod = 'GET'; - - endpoint = `/users/${owner}/projects`; + if (overwriteDataOperations.includes(fullOperation)) { + returnData.push(responseData); + } else if (overwriteDataOperationsArray.includes(fullOperation)) { + returnData.push.apply(returnData, responseData); } - } else { - throw new NodeOperationError(this.getNode(), `The resource "${resource}" is not known!`); - } - - if (returnAll === true) { - responseData = await gitlabApiRequestAllItems.call(this, requestMethod, endpoint, body, qs); - } else { - responseData = await gitlabApiRequest.call(this, requestMethod, endpoint, body, qs); - } - - if (overwriteDataOperations.includes(fullOperation)) { - returnData.push(responseData); - } else if (overwriteDataOperationsArray.includes(fullOperation)) { - returnData.push.apply(returnData, responseData); + } catch (error) { + if (this.continueOnFail()) { + if (overwriteDataOperations.includes(fullOperation) || overwriteDataOperationsArray.includes(fullOperation)) { + returnData.push({ error: error.message }); + } else { + items[i].json = { error: error.message }; + } + continue; + } + throw error; } } diff --git a/packages/nodes-base/nodes/Google/Analytics/GoogleAnalytics.node.ts b/packages/nodes-base/nodes/Google/Analytics/GoogleAnalytics.node.ts index 45704490b3..2a5d3e2ec3 100644 --- a/packages/nodes-base/nodes/Google/Analytics/GoogleAnalytics.node.ts +++ b/packages/nodes-base/nodes/Google/Analytics/GoogleAnalytics.node.ts @@ -162,123 +162,131 @@ export class GoogleAnalytics implements INodeType { let endpoint = ''; let responseData; for (let i = 0; i < items.length; i++) { - if (resource === 'report') { - if (operation === 'get') { - //https://developers.google.com/analytics/devguides/reporting/core/v4/rest/v4/reports/batchGet - method = 'POST'; - endpoint = '/v4/reports:batchGet'; - const viewId = this.getNodeParameter('viewId', i) as string; - const returnAll = this.getNodeParameter('returnAll', 0) as boolean; - const additionalFields = this.getNodeParameter( - 'additionalFields', - i, - ) as IDataObject; - const simple = this.getNodeParameter('simple', i) as boolean; + try { + if(resource === 'report') { + if(operation === 'get') { + //https://developers.google.com/analytics/devguides/reporting/core/v4/rest/v4/reports/batchGet + method = 'POST'; + endpoint = '/v4/reports:batchGet'; + const viewId = this.getNodeParameter('viewId', i) as string; + const returnAll = this.getNodeParameter('returnAll', 0) as boolean; + const additionalFields = this.getNodeParameter( + 'additionalFields', + i, + ) as IDataObject; + const simple = this.getNodeParameter('simple', i) as boolean; - const body: IData = { - viewId, - }; + const body: IData = { + viewId, + }; - if (additionalFields.useResourceQuotas) { - qs.useResourceQuotas = additionalFields.useResourceQuotas; - } - if (additionalFields.dateRangesUi) { - const dateValues = (additionalFields.dateRangesUi as IDataObject).dateRanges as IDataObject; - if (dateValues) { - const start = dateValues.startDate as string; - const end = dateValues.endDate as string; - Object.assign( - body, - { - dateRanges: - [ - { - startDate: moment(start).utc().format('YYYY-MM-DD'), - endDate: moment(end).utc().format('YYYY-MM-DD'), - }, - ], - }, - ); + if (additionalFields.useResourceQuotas) { + qs.useResourceQuotas = additionalFields.useResourceQuotas; } - } - - if (additionalFields.metricsUi) { - const metrics = (additionalFields.metricsUi as IDataObject).metricValues as IDataObject[]; - body.metrics = metrics; - } - if (additionalFields.dimensionUi) { - const dimensions = (additionalFields.dimensionUi as IDataObject).dimensionValues as IDataObject[]; - if (dimensions) { - body.dimensions = dimensions; + if (additionalFields.dateRangesUi) { + const dateValues = (additionalFields.dateRangesUi as IDataObject).dateRanges as IDataObject; + if (dateValues) { + const start = dateValues.startDate as string; + const end = dateValues.endDate as string; + Object.assign( + body, + { + dateRanges: + [ + { + startDate: moment(start).utc().format('YYYY-MM-DD'), + endDate: moment(end).utc().format('YYYY-MM-DD'), + }, + ], + }, + ); + } } - } - if (additionalFields.dimensionFiltersUi) { - const dimensionFilters = (additionalFields.dimensionFiltersUi as IDataObject).filterValues as IDataObject[]; - if (dimensionFilters) { - dimensionFilters.forEach(filter => filter.expressions = [filter.expressions]); - body.dimensionFilterClauses = { filters: dimensionFilters }; + + if (additionalFields.metricsUi) { + const metrics = (additionalFields.metricsUi as IDataObject).metricValues as IDataObject[]; + body.metrics = metrics; + } + if (additionalFields.dimensionUi) { + const dimensions = (additionalFields.dimensionUi as IDataObject).dimensionValues as IDataObject[]; + if (dimensions) { + body.dimensions = dimensions; + } + } + if (additionalFields.dimensionFiltersUi) { + const dimensionFilters = (additionalFields.dimensionFiltersUi as IDataObject).filterValues as IDataObject[]; + if (dimensionFilters) { + dimensionFilters.forEach(filter => filter.expressions = [filter.expressions]); + body.dimensionFilterClauses = { filters: dimensionFilters }; + } } - } - if (additionalFields.includeEmptyRows) { - Object.assign(body, { includeEmptyRows: additionalFields.includeEmptyRows }); - } - if (additionalFields.hideTotals) { - Object.assign(body, { hideTotals: additionalFields.hideTotals }); - } - if (additionalFields.hideValueRanges) { - Object.assign(body, { hideTotals: additionalFields.hideTotals }); - } + if (additionalFields.includeEmptyRows) { + Object.assign(body, { includeEmptyRows: additionalFields.includeEmptyRows }); + } + if (additionalFields.hideTotals) { + Object.assign(body, { hideTotals: additionalFields.hideTotals }); + } + if (additionalFields.hideValueRanges) { + Object.assign(body, { hideTotals: additionalFields.hideTotals }); + } - if (returnAll === true) { - responseData = await googleApiRequestAllItems.call(this, 'reports', method, endpoint, { reportRequests: [body] }, qs); - } else { - responseData = await googleApiRequest.call(this, method, endpoint, { reportRequests: [body] }, qs); - responseData = responseData.reports; - } + if (returnAll === true) { + responseData = await googleApiRequestAllItems.call(this, 'reports', method, endpoint, { reportRequests: [body] }, qs); + } else { + responseData = await googleApiRequest.call(this, method, endpoint, { reportRequests: [body] }, qs); + responseData = responseData.reports; + } - if (simple === true) { - responseData = simplify(responseData); - } else if (returnAll === true && responseData.length > 1) { - responseData = merge(responseData); + if (simple === true) { + responseData = simplify(responseData); + } else if (returnAll === true && responseData.length > 1) { + responseData = merge(responseData); + } } } - } - if (resource === 'userActivity') { - if (operation === 'search') { - //https://developers.google.com/analytics/devguides/reporting/core/v4/rest/v4/userActivity/search - method = 'POST'; - endpoint = '/v4/userActivity:search'; - const viewId = this.getNodeParameter('viewId', i); - const userId = this.getNodeParameter('userId', i); - const returnAll = this.getNodeParameter('returnAll', 0) as boolean; - const additionalFields = this.getNodeParameter( - 'additionalFields', - i, - ) as IDataObject; - const body: IDataObject = { - viewId, - user: { - userId, - }, - }; - if (additionalFields.activityTypes) { - Object.assign(body, { activityTypes: additionalFields.activityTypes }); - } + if (resource === 'userActivity') { + if (operation === 'search') { + //https://developers.google.com/analytics/devguides/reporting/core/v4/rest/v4/userActivity/search + method = 'POST'; + endpoint = '/v4/userActivity:search'; + const viewId = this.getNodeParameter('viewId', i); + const userId = this.getNodeParameter('userId', i); + const returnAll = this.getNodeParameter('returnAll', 0) as boolean; + const additionalFields = this.getNodeParameter( + 'additionalFields', + i, + ) as IDataObject; + const body: IDataObject = { + viewId, + user: { + userId, + }, + }; + if (additionalFields.activityTypes) { + Object.assign(body, { activityTypes: additionalFields.activityTypes }); + } - if (returnAll) { - responseData = await googleApiRequestAllItems.call(this, 'sessions', method, endpoint, body); - } else { - body.pageSize = this.getNodeParameter('limit', 0) as number; - responseData = await googleApiRequest.call(this, method, endpoint, body); - responseData = responseData.sessions; + if (returnAll) { + responseData = await googleApiRequestAllItems.call(this, 'sessions', method, endpoint, body); + } else { + body.pageSize = this.getNodeParameter('limit', 0) as number; + responseData = await googleApiRequest.call(this, method, endpoint, body); + responseData = responseData.sessions; + } } } - } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else if (responseData !== undefined) { - returnData.push(responseData as IDataObject); + if (Array.isArray(responseData)) { + returnData.push.apply(returnData, responseData as IDataObject[]); + } else if (responseData !== undefined) { + returnData.push(responseData as IDataObject); + } + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } } return [this.helpers.returnJsonArray(returnData)]; diff --git a/packages/nodes-base/nodes/Google/Books/GoogleBooks.node.ts b/packages/nodes-base/nodes/Google/Books/GoogleBooks.node.ts index c8992cfe10..fc4e87f804 100644 --- a/packages/nodes-base/nodes/Google/Books/GoogleBooks.node.ts +++ b/packages/nodes-base/nodes/Google/Books/GoogleBooks.node.ts @@ -385,115 +385,125 @@ export class GoogleBooks implements INodeType { let responseData; for (let i = 0; i < length; i++) { - if (resource === 'volume') { - if (operation === 'get') { - const volumeId = this.getNodeParameter('volumeId', i) as string; - responseData = await googleApiRequest.call(this, 'GET', `v1/volumes/${volumeId}`, {}); - } else if (operation === 'getAll') { - const searchQuery = this.getNodeParameter('searchQuery', i) as string; - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - if (returnAll) { - responseData = await googleApiRequestAllItems.call(this, 'items', 'GET', `v1/volumes?q=${searchQuery}`, {}); - } else { - qs.maxResults = this.getNodeParameter('limit', i) as number; - responseData = await googleApiRequest.call(this, 'GET', `v1/volumes?q=${searchQuery}`, {}, qs); - responseData = responseData.items || []; - } - } - } + try { - if (resource === 'bookshelf') { - if (operation === 'get') { - const shelfId = this.getNodeParameter('shelfId', i) as string; - const myLibrary = this.getNodeParameter('myLibrary', i) as boolean; - let endpoint; - if (myLibrary === false) { - const userId = this.getNodeParameter('userId', i) as string; - endpoint = `v1/users/${userId}/bookshelves/${shelfId}`; - } else { - endpoint = `v1/mylibrary/bookshelves/${shelfId}`; - } - - responseData = await googleApiRequest.call(this, 'GET', endpoint, {}); - } else if (operation === 'getAll') { - const myLibrary = this.getNodeParameter('myLibrary', i) as boolean; - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - let endpoint; - if (myLibrary === false) { - const userId = this.getNodeParameter('userId', i) as string; - endpoint = `v1/users/${userId}/bookshelves`; - } else { - endpoint = `v1/mylibrary/bookshelves`; - } - if (returnAll) { - responseData = await googleApiRequestAllItems.call(this, 'items', 'GET', endpoint, {}); - } else { - qs.maxResults = this.getNodeParameter('limit', i) as number; - responseData = await googleApiRequest.call(this, 'GET', endpoint, {}, qs); - responseData = responseData.items || []; - } - } - } - - if (resource === 'bookshelfVolume') { - if (operation === 'add') { - const shelfId = this.getNodeParameter('shelfId', i) as string; - const volumeId = this.getNodeParameter('volumeId', i) as string; - const body: IDataObject = { - volumeId, - }; - responseData = await googleApiRequest.call(this, 'POST', `v1/mylibrary/bookshelves/${shelfId}/addVolume`, body); - } - - if (operation === 'clear') { - const shelfId = this.getNodeParameter('shelfId', i) as string; - responseData = await googleApiRequest.call(this, 'POST', `v1/mylibrary/bookshelves/${shelfId}/clearVolumes`); - } - - if (operation === 'getAll') { - const shelfId = this.getNodeParameter('shelfId', i) as string; - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - const myLibrary = this.getNodeParameter('myLibrary', i) as boolean; - let endpoint; - if (myLibrary === false) { - const userId = this.getNodeParameter('userId', i) as string; - endpoint = `v1/users/${userId}/bookshelves/${shelfId}/volumes`; - } else { - endpoint = `v1/mylibrary/bookshelves/${shelfId}/volumes`; - } - if (returnAll) { - responseData = await googleApiRequestAllItems.call(this, 'items', 'GET', endpoint, {}); - } else { - qs.maxResults = this.getNodeParameter('limit', i) as number; - responseData = await googleApiRequest.call(this, 'GET', endpoint, {}, qs); - responseData = responseData.items || []; + if (resource === 'volume') { + if (operation === 'get') { + const volumeId = this.getNodeParameter('volumeId', i) as string; + responseData = await googleApiRequest.call(this, 'GET', `v1/volumes/${volumeId}`, {}); + } else if (operation === 'getAll') { + const searchQuery = this.getNodeParameter('searchQuery', i) as string; + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + if (returnAll) { + responseData = await googleApiRequestAllItems.call(this, 'items', 'GET', `v1/volumes?q=${searchQuery}`, {}); + } else { + qs.maxResults = this.getNodeParameter('limit', i) as number; + responseData = await googleApiRequest.call(this, 'GET', `v1/volumes?q=${searchQuery}`, {}, qs); + responseData = responseData.items || []; + } } } - if (operation === 'move') { - const shelfId = this.getNodeParameter('shelfId', i) as string; - const volumeId = this.getNodeParameter('volumeId', i) as string; - const volumePosition = this.getNodeParameter('volumePosition', i) as number; - const body: IDataObject = { - volumeId, - volumePosition, - }; - responseData = await googleApiRequest.call(this, 'POST', `v1/mylibrary/bookshelves/${shelfId}/moveVolume`, body); + if (resource === 'bookshelf') { + if (operation === 'get') { + const shelfId = this.getNodeParameter('shelfId', i) as string; + const myLibrary = this.getNodeParameter('myLibrary', i) as boolean; + let endpoint; + if (myLibrary === false) { + const userId = this.getNodeParameter('userId', i) as string; + endpoint = `v1/users/${userId}/bookshelves/${shelfId}`; + } else { + endpoint = `v1/mylibrary/bookshelves/${shelfId}`; + } + + responseData = await googleApiRequest.call(this, 'GET', endpoint, {}); + } else if (operation === 'getAll') { + const myLibrary = this.getNodeParameter('myLibrary', i) as boolean; + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + let endpoint; + if (myLibrary === false) { + const userId = this.getNodeParameter('userId', i) as string; + endpoint = `v1/users/${userId}/bookshelves`; + } else { + endpoint = `v1/mylibrary/bookshelves`; + } + if (returnAll) { + responseData = await googleApiRequestAllItems.call(this, 'items', 'GET', endpoint, {}); + } else { + qs.maxResults = this.getNodeParameter('limit', i) as number; + responseData = await googleApiRequest.call(this, 'GET', endpoint, {}, qs); + responseData = responseData.items || []; + } + } } - if (operation === 'remove') { - const shelfId = this.getNodeParameter('shelfId', i) as string; - const volumeId = this.getNodeParameter('volumeId', i) as string; - const body: IDataObject = { - volumeId, - }; - responseData = await googleApiRequest.call(this, 'POST', `v1/mylibrary/bookshelves/${shelfId}/removeVolume`, body); + if (resource === 'bookshelfVolume') { + if (operation === 'add') { + const shelfId = this.getNodeParameter('shelfId', i) as string; + const volumeId = this.getNodeParameter('volumeId', i) as string; + const body: IDataObject = { + volumeId, + }; + responseData = await googleApiRequest.call(this, 'POST', `v1/mylibrary/bookshelves/${shelfId}/addVolume`, body); + } + + if (operation === 'clear') { + const shelfId = this.getNodeParameter('shelfId', i) as string; + responseData = await googleApiRequest.call(this, 'POST', `v1/mylibrary/bookshelves/${shelfId}/clearVolumes`); + } + + if (operation === 'getAll') { + const shelfId = this.getNodeParameter('shelfId', i) as string; + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + const myLibrary = this.getNodeParameter('myLibrary', i) as boolean; + let endpoint; + if (myLibrary === false) { + const userId = this.getNodeParameter('userId', i) as string; + endpoint = `v1/users/${userId}/bookshelves/${shelfId}/volumes`; + } else { + endpoint = `v1/mylibrary/bookshelves/${shelfId}/volumes`; + } + if (returnAll) { + responseData = await googleApiRequestAllItems.call(this, 'items', 'GET', endpoint, {}); + } else { + qs.maxResults = this.getNodeParameter('limit', i) as number; + responseData = await googleApiRequest.call(this, 'GET', endpoint, {}, qs); + responseData = responseData.items || []; + } + } + + if (operation === 'move') { + const shelfId = this.getNodeParameter('shelfId', i) as string; + const volumeId = this.getNodeParameter('volumeId', i) as string; + const volumePosition = this.getNodeParameter('volumePosition', i) as number; + const body: IDataObject = { + volumeId, + volumePosition, + }; + responseData = await googleApiRequest.call(this, 'POST', `v1/mylibrary/bookshelves/${shelfId}/moveVolume`, body); + } + + if (operation === 'remove') { + const shelfId = this.getNodeParameter('shelfId', i) as string; + const volumeId = this.getNodeParameter('volumeId', i) as string; + const body: IDataObject = { + volumeId, + }; + responseData = await googleApiRequest.call(this, 'POST', `v1/mylibrary/bookshelves/${shelfId}/removeVolume`, body); + } } - } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else { - returnData.push(responseData as IDataObject); + if (Array.isArray(responseData)) { + returnData.push.apply(returnData, responseData as IDataObject[]); + } else { + returnData.push(responseData as IDataObject); + } + + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } } return [this.helpers.returnJsonArray(responseData)]; diff --git a/packages/nodes-base/nodes/Google/Calendar/GoogleCalendar.node.ts b/packages/nodes-base/nodes/Google/Calendar/GoogleCalendar.node.ts index 6cf7e674df..88cf313de1 100644 --- a/packages/nodes-base/nodes/Google/Calendar/GoogleCalendar.node.ts +++ b/packages/nodes-base/nodes/Google/Calendar/GoogleCalendar.node.ts @@ -606,6 +606,12 @@ export class GoogleCalendar implements INodeType { ); } } + + if (Array.isArray(responseData)) { + returnData.push.apply(returnData, responseData as IDataObject[]); + } else if (responseData !== undefined) { + returnData.push(responseData as IDataObject); + } } catch (error) { if (this.continueOnFail() !== true) { throw error; @@ -619,12 +625,6 @@ export class GoogleCalendar implements INodeType { continue; } } - - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else if (responseData !== undefined) { - returnData.push(responseData as IDataObject); - } } return [this.helpers.returnJsonArray(returnData)]; } diff --git a/packages/nodes-base/nodes/Google/Contacts/GoogleContacts.node.ts b/packages/nodes-base/nodes/Google/Contacts/GoogleContacts.node.ts index e777e943ef..7c794bd7af 100644 --- a/packages/nodes-base/nodes/Google/Contacts/GoogleContacts.node.ts +++ b/packages/nodes-base/nodes/Google/Contacts/GoogleContacts.node.ts @@ -101,396 +101,404 @@ export class GoogleContacts implements INodeType { 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 === 'contact') { - //https://developers.google.com/calendar/v3/reference/events/insert - if (operation === 'create') { - const familyName = this.getNodeParameter('familyName', i) as string; - const givenName = this.getNodeParameter('givenName', i) as string; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + try { + if (resource === 'contact') { + //https://developers.google.com/calendar/v3/reference/events/insert + if (operation === 'create') { + const familyName = this.getNodeParameter('familyName', i) as string; + const givenName = this.getNodeParameter('givenName', i) as string; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const body: IDataObject = { - names: [ - { - familyName, - givenName, - middleName: '', - }, - ], - }; - - if (additionalFields.middleName) { - //@ts-ignore - body.names[0].middleName = additionalFields.middleName as string; - } - - if (additionalFields.honorificPrefix) { - //@ts-ignore - body.names[0].honorificPrefix = additionalFields.honorificPrefix as string; - } - - if (additionalFields.honorificSuffix) { - //@ts-ignore - body.names[0].honorificSuffix = additionalFields.honorificSuffix as string; - } - - if (additionalFields.companyUi) { - const companyValues = (additionalFields.companyUi as IDataObject).companyValues as IDataObject[]; - body.organizations = companyValues; - } - - if (additionalFields.phoneUi) { - const phoneValues = (additionalFields.phoneUi as IDataObject).phoneValues as IDataObject[]; - body.phoneNumbers = phoneValues; - } - - if (additionalFields.addressesUi) { - const addressesValues = (additionalFields.addressesUi as IDataObject).addressesValues as IDataObject[]; - body.addresses = addressesValues; - } - - if (additionalFields.relationsUi) { - const relationsValues = (additionalFields.relationsUi as IDataObject).relationsValues as IDataObject[]; - body.relations = relationsValues; - } - - if (additionalFields.eventsUi) { - const eventsValues = (additionalFields.eventsUi as IDataObject).eventsValues as IDataObject[]; - for (let i = 0; i < eventsValues.length; i++) { - const [month, day, year] = moment(eventsValues[i].date as string).format('MM/DD/YYYY').split('/'); - eventsValues[i] = { - date: { - day, - month, - year, + const body: IDataObject = { + names: [ + { + familyName, + givenName, + middleName: '', }, - type: eventsValues[i].type, - }; + ], + }; + + if (additionalFields.middleName) { + //@ts-ignore + body.names[0].middleName = additionalFields.middleName as string; } - body.events = eventsValues; - } - if (additionalFields.birthday) { - const [month, day, year] = moment(additionalFields.birthday as string).format('MM/DD/YYYY').split('/'); + if (additionalFields.honorificPrefix) { + //@ts-ignore + body.names[0].honorificPrefix = additionalFields.honorificPrefix as string; + } - body.birthdays = [ - { - date: { - day, - month, - year, + if (additionalFields.honorificSuffix) { + //@ts-ignore + body.names[0].honorificSuffix = additionalFields.honorificSuffix as string; + } + + if (additionalFields.companyUi) { + const companyValues = (additionalFields.companyUi as IDataObject).companyValues as IDataObject[]; + body.organizations = companyValues; + } + + if (additionalFields.phoneUi) { + const phoneValues = (additionalFields.phoneUi as IDataObject).phoneValues as IDataObject[]; + body.phoneNumbers = phoneValues; + } + + if (additionalFields.addressesUi) { + const addressesValues = (additionalFields.addressesUi as IDataObject).addressesValues as IDataObject[]; + body.addresses = addressesValues; + } + + if (additionalFields.relationsUi) { + const relationsValues = (additionalFields.relationsUi as IDataObject).relationsValues as IDataObject[]; + body.relations = relationsValues; + } + + if (additionalFields.eventsUi) { + const eventsValues = (additionalFields.eventsUi as IDataObject).eventsValues as IDataObject[]; + for (let i = 0; i < eventsValues.length; i++) { + const [month, day, year] = moment(eventsValues[i].date as string).format('MM/DD/YYYY').split('/'); + eventsValues[i] = { + date: { + day, + month, + year, + }, + type: eventsValues[i].type, + }; + } + body.events = eventsValues; + } + + if (additionalFields.birthday) { + const [month, day, year] = moment(additionalFields.birthday as string).format('MM/DD/YYYY').split('/'); + + body.birthdays = [ + { + date: { + day, + month, + year, + }, }, - }, - ]; - } + ]; + } - if (additionalFields.emailsUi) { - const emailsValues = (additionalFields.emailsUi as IDataObject).emailsValues as IDataObject[]; - body.emailAddresses = emailsValues; - } + if (additionalFields.emailsUi) { + const emailsValues = (additionalFields.emailsUi as IDataObject).emailsValues as IDataObject[]; + body.emailAddresses = emailsValues; + } - if (additionalFields.biographies) { - body.biographies = [ - { - value: additionalFields.biographies, - contentType: 'TEXT_PLAIN', - }, - ]; - } - - if (additionalFields.customFieldsUi) { - const customFieldsValues = (additionalFields.customFieldsUi as IDataObject).customFieldsValues as IDataObject[]; - body.userDefined = customFieldsValues; - } - - if (additionalFields.group) { - const memberships = (additionalFields.group as string[]).map((groupId: string) => { - return { - contactGroupMembership: { - contactGroupResourceName: groupId, + if (additionalFields.biographies) { + body.biographies = [ + { + value: additionalFields.biographies, + contentType: 'TEXT_PLAIN', }, - }; - }); + ]; + } - body.memberships = memberships; - } + if (additionalFields.customFieldsUi) { + const customFieldsValues = (additionalFields.customFieldsUi as IDataObject).customFieldsValues as IDataObject[]; + body.userDefined = customFieldsValues; + } - responseData = await googleApiRequest.call( - this, - 'POST', - `/people:createContact`, - body, - qs, - ); + if (additionalFields.group) { + const memberships = (additionalFields.group as string[]).map((groupId: string) => { + return { + contactGroupMembership: { + contactGroupResourceName: groupId, + }, + }; + }); - responseData.contactId = responseData.resourceName.split('/')[1]; + body.memberships = memberships; + } - } - //https://developers.google.com/people/api/rest/v1/people/deleteContact - if (operation === 'delete') { - const contactId = this.getNodeParameter('contactId', i) as string; - responseData = await googleApiRequest.call( - this, - 'DELETE', - `/people/${contactId}:deleteContact`, - {}, - ); - responseData = { success: true }; - } - //https://developers.google.com/people/api/rest/v1/people/get - if (operation === 'get') { - const contactId = this.getNodeParameter('contactId', i) as string; - const fields = this.getNodeParameter('fields', i) as string[]; - const rawData = this.getNodeParameter('rawData', i) as boolean; - - if (fields.includes('*')) { - qs.personFields = allFields.join(','); - } else { - qs.personFields = (fields as string[]).join(','); - } - - responseData = await googleApiRequest.call( - this, - 'GET', - `/people/${contactId}`, - {}, - qs, - ); - - if (!rawData) { - responseData = cleanData(responseData)[0]; - } - - responseData.contactId = responseData.resourceName.split('/')[1]; - } - //https://developers.google.com/people/api/rest/v1/people.connections/list - if (operation === 'getAll') { - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - const fields = this.getNodeParameter('fields', i) as string[]; - const options = this.getNodeParameter('options', i) as IDataObject; - const rawData = this.getNodeParameter('rawData', i) as boolean; - - if (options.sortOrder) { - qs.sortOrder = options.sortOrder as number; - } - - if (fields.includes('*')) { - qs.personFields = allFields.join(','); - } else { - qs.personFields = (fields as string[]).join(','); - } - - if (returnAll) { - responseData = await googleApiRequestAllItems.call( - this, - 'connections', - 'GET', - `/people/me/connections`, - {}, - qs, - ); - } else { - qs.pageSize = this.getNodeParameter('limit', i) as number; responseData = await googleApiRequest.call( this, - 'GET', - `/people/me/connections`, - {}, + 'POST', + `/people:createContact`, + body, qs, ); - responseData = responseData.connections; + + responseData.contactId = responseData.resourceName.split('/')[1]; + } - - if (!rawData) { - responseData = cleanData(responseData); + //https://developers.google.com/people/api/rest/v1/people/deleteContact + if (operation === 'delete') { + const contactId = this.getNodeParameter('contactId', i) as string; + responseData = await googleApiRequest.call( + this, + 'DELETE', + `/people/${contactId}:deleteContact`, + {}, + ); + responseData = { success: true }; } + //https://developers.google.com/people/api/rest/v1/people/get + if (operation === 'get') { + const contactId = this.getNodeParameter('contactId', i) as string; + const fields = this.getNodeParameter('fields', i) as string[]; + const rawData = this.getNodeParameter('rawData', i) as boolean; - for (let i = 0; i < responseData.length; i++) { - responseData[i].contactId = responseData[i].resourceName.split('/')[1]; - } - } - //https://developers.google.com/people/api/rest/v1/people/updateContact - if (operation === 'update') { - const updatePersonFields = []; + if (fields.includes('*')) { + qs.personFields = allFields.join(','); + } else { + qs.personFields = (fields as string[]).join(','); + } - const contactId = this.getNodeParameter('contactId', i) as string; - - const fields = this.getNodeParameter('fields', i) as string[]; - - const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; - - let etag; - - if (updateFields.etag) { - - etag = updateFields.etag as string; - - } else { - - const data = await googleApiRequest.call( + responseData = await googleApiRequest.call( this, 'GET', `/people/${contactId}`, {}, - { personFields: 'Names' }, + qs, ); - etag = data.etag; - - } - - if (fields.includes('*')) { - qs.personFields = allFields.join(','); - } else { - qs.personFields = (fields as string[]).join(','); - } - - const body: IDataObject = { - etag, - names: [ - {}, - ], - }; - - if (updateFields.givenName) { - //@ts-ignore - body.names[0].givenName = updateFields.givenName as string; - } - - if (updateFields.familyName) { - //@ts-ignore - body.names[0].familyName = updateFields.familyName as string; - } - - if (updateFields.middleName) { - //@ts-ignore - body.names[0].middleName = updateFields.middleName as string; - } - - if (updateFields.honorificPrefix) { - //@ts-ignore - body.names[0].honorificPrefix = updateFields.honorificPrefix as string; - } - - if (updateFields.honorificSuffix) { - //@ts-ignore - body.names[0].honorificSuffix = updateFields.honorificSuffix as string; - } - - if (updateFields.companyUi) { - const companyValues = (updateFields.companyUi as IDataObject).companyValues as IDataObject[]; - body.organizations = companyValues; - updatePersonFields.push('organizations'); - } - - if (updateFields.phoneUi) { - const phoneValues = (updateFields.phoneUi as IDataObject).phoneValues as IDataObject[]; - body.phoneNumbers = phoneValues; - updatePersonFields.push('phoneNumbers'); - } - - if (updateFields.addressesUi) { - const addressesValues = (updateFields.addressesUi as IDataObject).addressesValues as IDataObject[]; - body.addresses = addressesValues; - updatePersonFields.push('addresses'); - } - - if (updateFields.relationsUi) { - const relationsValues = (updateFields.relationsUi as IDataObject).relationsValues as IDataObject[]; - body.relations = relationsValues; - updatePersonFields.push('relations'); - } - - if (updateFields.eventsUi) { - const eventsValues = (updateFields.eventsUi as IDataObject).eventsValues as IDataObject[]; - for (let i = 0; i < eventsValues.length; i++) { - const [month, day, year] = moment(eventsValues[i].date as string).format('MM/DD/YYYY').split('/'); - eventsValues[i] = { - date: { - day, - month, - year, - }, - type: eventsValues[i].type, - }; + if (!rawData) { + responseData = cleanData(responseData)[0]; } - body.events = eventsValues; - updatePersonFields.push('events'); + + responseData.contactId = responseData.resourceName.split('/')[1]; } + //https://developers.google.com/people/api/rest/v1/people.connections/list + if (operation === 'getAll') { + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + const fields = this.getNodeParameter('fields', i) as string[]; + const options = this.getNodeParameter('options', i) as IDataObject; + const rawData = this.getNodeParameter('rawData', i) as boolean; - if (updateFields.birthday) { - const [month, day, year] = moment(updateFields.birthday as string).format('MM/DD/YYYY').split('/'); + if (options.sortOrder) { + qs.sortOrder = options.sortOrder as number; + } - body.birthdays = [ - { - date: { - day, - month, - year, + if (fields.includes('*')) { + qs.personFields = allFields.join(','); + } else { + qs.personFields = (fields as string[]).join(','); + } + + if (returnAll) { + responseData = await googleApiRequestAllItems.call( + this, + 'connections', + 'GET', + `/people/me/connections`, + {}, + qs, + ); + } else { + qs.pageSize = this.getNodeParameter('limit', i) as number; + responseData = await googleApiRequest.call( + this, + 'GET', + `/people/me/connections`, + {}, + qs, + ); + responseData = responseData.connections; + } + + if (!rawData) { + responseData = cleanData(responseData); + } + + for (let i = 0; i < responseData.length; i++) { + responseData[i].contactId = responseData[i].resourceName.split('/')[1]; + } + } + //https://developers.google.com/people/api/rest/v1/people/updateContact + if (operation === 'update') { + const updatePersonFields = []; + + const contactId = this.getNodeParameter('contactId', i) as string; + + const fields = this.getNodeParameter('fields', i) as string[]; + + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + + let etag; + + if (updateFields.etag) { + + etag = updateFields.etag as string; + + } else { + + const data = await googleApiRequest.call( + this, + 'GET', + `/people/${contactId}`, + {}, + { personFields: 'Names' }, + ); + + etag = data.etag; + + } + + if (fields.includes('*')) { + qs.personFields = allFields.join(','); + } else { + qs.personFields = (fields as string[]).join(','); + } + + const body: IDataObject = { + etag, + names: [ + {}, + ], + }; + + if (updateFields.givenName) { + //@ts-ignore + body.names[0].givenName = updateFields.givenName as string; + } + + if (updateFields.familyName) { + //@ts-ignore + body.names[0].familyName = updateFields.familyName as string; + } + + if (updateFields.middleName) { + //@ts-ignore + body.names[0].middleName = updateFields.middleName as string; + } + + if (updateFields.honorificPrefix) { + //@ts-ignore + body.names[0].honorificPrefix = updateFields.honorificPrefix as string; + } + + if (updateFields.honorificSuffix) { + //@ts-ignore + body.names[0].honorificSuffix = updateFields.honorificSuffix as string; + } + + if (updateFields.companyUi) { + const companyValues = (updateFields.companyUi as IDataObject).companyValues as IDataObject[]; + body.organizations = companyValues; + updatePersonFields.push('organizations'); + } + + if (updateFields.phoneUi) { + const phoneValues = (updateFields.phoneUi as IDataObject).phoneValues as IDataObject[]; + body.phoneNumbers = phoneValues; + updatePersonFields.push('phoneNumbers'); + } + + if (updateFields.addressesUi) { + const addressesValues = (updateFields.addressesUi as IDataObject).addressesValues as IDataObject[]; + body.addresses = addressesValues; + updatePersonFields.push('addresses'); + } + + if (updateFields.relationsUi) { + const relationsValues = (updateFields.relationsUi as IDataObject).relationsValues as IDataObject[]; + body.relations = relationsValues; + updatePersonFields.push('relations'); + } + + if (updateFields.eventsUi) { + const eventsValues = (updateFields.eventsUi as IDataObject).eventsValues as IDataObject[]; + for (let i = 0; i < eventsValues.length; i++) { + const [month, day, year] = moment(eventsValues[i].date as string).format('MM/DD/YYYY').split('/'); + eventsValues[i] = { + date: { + day, + month, + year, + }, + type: eventsValues[i].type, + }; + } + body.events = eventsValues; + updatePersonFields.push('events'); + } + + if (updateFields.birthday) { + const [month, day, year] = moment(updateFields.birthday as string).format('MM/DD/YYYY').split('/'); + + body.birthdays = [ + { + date: { + day, + month, + year, + }, }, - }, - ]; + ]; - updatePersonFields.push('birthdays'); - } + updatePersonFields.push('birthdays'); + } - if (updateFields.emailsUi) { - const emailsValues = (updateFields.emailsUi as IDataObject).emailsValues as IDataObject[]; - body.emailAddresses = emailsValues; - updatePersonFields.push('emailAddresses'); - } + if (updateFields.emailsUi) { + const emailsValues = (updateFields.emailsUi as IDataObject).emailsValues as IDataObject[]; + body.emailAddresses = emailsValues; + updatePersonFields.push('emailAddresses'); + } - if (updateFields.biographies) { - body.biographies = [ - { - value: updateFields.biographies, - contentType: 'TEXT_PLAIN', - }, - ]; - updatePersonFields.push('biographies'); - } - - if (updateFields.customFieldsUi) { - const customFieldsValues = (updateFields.customFieldsUi as IDataObject).customFieldsValues as IDataObject[]; - body.userDefined = customFieldsValues; - updatePersonFields.push('userDefined'); - } - - if (updateFields.group) { - const memberships = (updateFields.group as string[]).map((groupId: string) => { - return { - contactGroupMembership: { - contactGroupResourceName: groupId, + if (updateFields.biographies) { + body.biographies = [ + { + value: updateFields.biographies, + contentType: 'TEXT_PLAIN', }, - }; - }); + ]; + updatePersonFields.push('biographies'); + } - body.memberships = memberships; - updatePersonFields.push('memberships'); + if (updateFields.customFieldsUi) { + const customFieldsValues = (updateFields.customFieldsUi as IDataObject).customFieldsValues as IDataObject[]; + body.userDefined = customFieldsValues; + updatePersonFields.push('userDefined'); + } + + if (updateFields.group) { + const memberships = (updateFields.group as string[]).map((groupId: string) => { + return { + contactGroupMembership: { + contactGroupResourceName: groupId, + }, + }; + }); + + body.memberships = memberships; + updatePersonFields.push('memberships'); + } + + if ((body.names as IDataObject[]).length > 0) { + updatePersonFields.push('names'); + } + + qs.updatePersonFields = updatePersonFields.join(','); + + responseData = await googleApiRequest.call( + this, + 'PATCH', + `/people/${contactId}:updateContact`, + body, + qs, + ); + + responseData.contactId = responseData.resourceName.split('/')[1]; } - - if ((body.names as IDataObject[]).length > 0) { - updatePersonFields.push('names'); - } - - qs.updatePersonFields = updatePersonFields.join(','); - - responseData = await googleApiRequest.call( - this, - 'PATCH', - `/people/${contactId}:updateContact`, - body, - qs, - ); - - responseData.contactId = responseData.resourceName.split('/')[1]; } + if (Array.isArray(responseData)) { + returnData.push.apply(returnData, responseData as IDataObject[]); + } else if (responseData !== undefined) { + returnData.push(responseData as IDataObject); + } + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else if (responseData !== undefined) { - returnData.push(responseData as IDataObject); - } return [this.helpers.returnJsonArray(returnData)]; } } diff --git a/packages/nodes-base/nodes/Google/Drive/GoogleDrive.node.ts b/packages/nodes-base/nodes/Google/Drive/GoogleDrive.node.ts index 9cf0dcb171..54ececba97 100644 --- a/packages/nodes-base/nodes/Google/Drive/GoogleDrive.node.ts +++ b/packages/nodes-base/nodes/Google/Drive/GoogleDrive.node.ts @@ -1996,436 +1996,448 @@ export class GoogleDrive implements INodeType { const operation = this.getNodeParameter('operation', 0) as string; for (let i = 0; i < items.length; i++) { - const options = this.getNodeParameter('options', i, {}) as IDataObject; + try { + const options = this.getNodeParameter('options', i, {}) as IDataObject; - let queryFields = 'id, name'; - if (options && options.fields) { - const fields = options.fields as string[]; - if (fields.includes('*')) { - queryFields = '*'; - } else { - queryFields = fields.join(', '); - } - } - - if (resource === 'drive') { - if (operation === 'create') { - // ---------------------------------- - // create - // ---------------------------------- - - const name = this.getNodeParameter('name', i) as string; - - const body: IDataObject = { - name, - }; - - Object.assign(body, options); - - const response = await googleApiRequest.call(this, 'POST', `/drive/v3/drives`, body, { requestId: uuid() }); - - returnData.push(response as IDataObject); - } - if (operation === 'delete') { - // ---------------------------------- - // delete - // ---------------------------------- - - const driveId = this.getNodeParameter('driveId', i) as string; - - await googleApiRequest.call(this, 'DELETE', `/drive/v3/drives/${driveId}`); - - returnData.push({ success: true }); - } - if (operation === 'get') { - // ---------------------------------- - // get - // ---------------------------------- - - const driveId = this.getNodeParameter('driveId', i) as string; - - const qs: IDataObject = {}; - - Object.assign(qs, options); - - const response = await googleApiRequest.call(this, 'GET', `/drive/v3/drives/${driveId}`, {}, qs); - - returnData.push(response as IDataObject); - } - if (operation === 'list') { - // ---------------------------------- - // list - // ---------------------------------- - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - - const qs: IDataObject = {}; - - let response: IDataObject[] = []; - - Object.assign(qs, options); - - if (returnAll === true) { - response = await googleApiRequestAllItems.call(this, 'drives', 'GET', `/drive/v3/drives`, {}, qs); + let queryFields = 'id, name'; + if (options && options.fields) { + const fields = options.fields as string[]; + if (fields.includes('*')) { + queryFields = '*'; } else { - qs.pageSize = this.getNodeParameter('limit', i) as number; - const data = await googleApiRequest.call(this, 'GET', `/drive/v3/drives`, {}, qs); - response = data.drives as IDataObject[]; + queryFields = fields.join(', '); } - - returnData.push.apply(returnData, response); - } - if (operation === 'update') { - // ---------------------------------- - // update - // ---------------------------------- - - const driveId = this.getNodeParameter('driveId', i) as string; - - const body: IDataObject = {}; - - Object.assign(body, options); - - const response = await googleApiRequest.call(this, 'PATCH', `/drive/v3/drives/${driveId}`, body); - - returnData.push(response as IDataObject); } - } - if (resource === 'file') { - if (operation === 'copy') { - // ---------------------------------- - // copy - // ---------------------------------- + if (resource === 'drive') { + if (operation === 'create') { + // ---------------------------------- + // create + // ---------------------------------- - const fileId = this.getNodeParameter('fileId', i) as string; + const name = this.getNodeParameter('name', i) as string; - const body: IDataObject = { - fields: queryFields, - }; + const body: IDataObject = { + name, + }; - const optionProperties = ['name', 'parents']; - for (const propertyName of optionProperties) { - if (options[propertyName] !== undefined) { - body[propertyName] = options[propertyName]; - } + Object.assign(body, options); + + const response = await googleApiRequest.call(this, 'POST', `/drive/v3/drives`, body, { requestId: uuid() }); + + returnData.push(response as IDataObject); } + if (operation === 'delete') { + // ---------------------------------- + // delete + // ---------------------------------- - const qs = { - supportsAllDrives: true, - }; + const driveId = this.getNodeParameter('driveId', i) as string; - const response = await googleApiRequest.call(this, 'POST', `/drive/v3/files/${fileId}/copy`, body, qs); + await googleApiRequest.call(this, 'DELETE', `/drive/v3/drives/${driveId}`); - returnData.push(response as IDataObject); - - } else if (operation === 'download') { - // ---------------------------------- - // download - // ---------------------------------- - - const fileId = this.getNodeParameter('fileId', i) as string; - const options = this.getNodeParameter('options', i) as IDataObject; - - const requestOptions = { - resolveWithFullResponse: true, - encoding: null, - json: false, - }; - - const response = await googleApiRequest.call(this, 'GET', `/drive/v3/files/${fileId}`, {}, { alt: 'media' }, undefined, requestOptions); - - let mimeType: string | undefined; - let fileName: string | undefined = undefined; - if (response.headers['content-type']) { - mimeType = response.headers['content-type']; + returnData.push({ success: true }); } + if (operation === 'get') { + // ---------------------------------- + // get + // ---------------------------------- - if (options.fileName) { - fileName = options.fileName as string; + const driveId = this.getNodeParameter('driveId', i) as string; + + const qs: IDataObject = {}; + + Object.assign(qs, options); + + const response = await googleApiRequest.call(this, 'GET', `/drive/v3/drives/${driveId}`, {}, qs); + + returnData.push(response as IDataObject); } + if (operation === 'list') { + // ---------------------------------- + // list + // ---------------------------------- + const returnAll = this.getNodeParameter('returnAll', i) as boolean; - const newItem: INodeExecutionData = { - json: items[i].json, - binary: {}, - }; + const qs: IDataObject = {}; - if (items[i].binary !== undefined) { - // Create a shallow copy of the binary data so that the old - // data references which do not get changed still stay behind - // but the incoming data does not get changed. - Object.assign(newItem.binary, items[i].binary); - } + let response: IDataObject[] = []; - items[i] = newItem; + Object.assign(qs, options); - const dataPropertyNameDownload = this.getNodeParameter('binaryPropertyName', i) as string; - - const data = Buffer.from(response.body as string); - - items[i].binary![dataPropertyNameDownload] = await this.helpers.prepareBinaryData(data as unknown as Buffer, fileName, mimeType); - - } else if (operation === 'list') { - // ---------------------------------- - // list - // ---------------------------------- - - let querySpaces = ''; - if (options.spaces) { - const spaces = options.spaces as string[]; - if (spaces.includes('*')) { - querySpaces = 'appDataFolder, drive, photos'; + if (returnAll === true) { + response = await googleApiRequestAllItems.call(this, 'drives', 'GET', `/drive/v3/drives`, {}, qs); } else { - querySpaces = spaces.join(', '); - } - } - - let queryCorpora = ''; - if (options.corpora) { - queryCorpora = options.corpora as string; - } - - let driveId: string | undefined; - driveId = options.driveId as string; - if (driveId === '') { - driveId = undefined; - } - - let queryString = ''; - const useQueryString = this.getNodeParameter('useQueryString', i) as boolean; - if (useQueryString === true) { - // Use the user defined query string - queryString = this.getNodeParameter('queryString', i) as string; - } else { - // Build query string out of parameters set by user - const queryFilters = this.getNodeParameter('queryFilters', i) as IDataObject; - - const queryFilterFields: string[] = []; - if (queryFilters.name) { - (queryFilters.name as IDataObject[]).forEach(nameFilter => { - let operation = nameFilter.operation; - if (operation === 'is') { - operation = '='; - } else if (operation === 'isNot') { - operation = '!='; - } - queryFilterFields.push(`name ${operation} '${nameFilter.value}'`); - }); - - queryString += queryFilterFields.join(' or '); + qs.pageSize = this.getNodeParameter('limit', i) as number; + const data = await googleApiRequest.call(this, 'GET', `/drive/v3/drives`, {}, qs); + response = data.drives as IDataObject[]; } - queryFilterFields.length = 0; - if (queryFilters.mimeType) { - (queryFilters.mimeType as IDataObject[]).forEach(mimeTypeFilter => { - let mimeType = mimeTypeFilter.mimeType; - if (mimeTypeFilter.mimeType === 'custom') { - mimeType = mimeTypeFilter.customMimeType; - } - queryFilterFields.push(`mimeType = '${mimeType}'`); - }); + returnData.push.apply(returnData, response); + } + if (operation === 'update') { + // ---------------------------------- + // update + // ---------------------------------- - if (queryFilterFields.length) { - if (queryString !== '') { - queryString += ' and '; - } + const driveId = this.getNodeParameter('driveId', i) as string; + + const body: IDataObject = {}; + + Object.assign(body, options); + + const response = await googleApiRequest.call(this, 'PATCH', `/drive/v3/drives/${driveId}`, body); + + returnData.push(response as IDataObject); + } + + } + if (resource === 'file') { + if (operation === 'copy') { + // ---------------------------------- + // copy + // ---------------------------------- + + const fileId = this.getNodeParameter('fileId', i) as string; + + const body: IDataObject = { + fields: queryFields, + }; + + const optionProperties = ['name', 'parents']; + for (const propertyName of optionProperties) { + if (options[propertyName] !== undefined) { + body[propertyName] = options[propertyName]; + } + } + + const qs = { + supportsAllDrives: true, + }; + + const response = await googleApiRequest.call(this, 'POST', `/drive/v3/files/${fileId}/copy`, body, qs); + + returnData.push(response as IDataObject); + + } else if (operation === 'download') { + // ---------------------------------- + // download + // ---------------------------------- + + const fileId = this.getNodeParameter('fileId', i) as string; + const options = this.getNodeParameter('options', i) as IDataObject; + + const requestOptions = { + resolveWithFullResponse: true, + encoding: null, + json: false, + }; + + const response = await googleApiRequest.call(this, 'GET', `/drive/v3/files/${fileId}`, {}, { alt: 'media' }, undefined, requestOptions); + + let mimeType: string | undefined; + let fileName: string | undefined = undefined; + if (response.headers['content-type']) { + mimeType = response.headers['content-type']; + } + + if (options.fileName) { + fileName = options.fileName as string; + } + + const newItem: INodeExecutionData = { + json: items[i].json, + binary: {}, + }; + + if (items[i].binary !== undefined) { + // Create a shallow copy of the binary data so that the old + // data references which do not get changed still stay behind + // but the incoming data does not get changed. + Object.assign(newItem.binary, items[i].binary); + } + + items[i] = newItem; + + const dataPropertyNameDownload = this.getNodeParameter('binaryPropertyName', i) as string; + + const data = Buffer.from(response.body as string); + + items[i].binary![dataPropertyNameDownload] = await this.helpers.prepareBinaryData(data as unknown as Buffer, fileName, mimeType); + + } else if (operation === 'list') { + // ---------------------------------- + // list + // ---------------------------------- + + let querySpaces = ''; + if (options.spaces) { + const spaces = options.spaces as string[]; + if (spaces.includes('*')) { + querySpaces = 'appDataFolder, drive, photos'; + } else { + querySpaces = spaces.join(', '); + } + } + + let queryCorpora = ''; + if (options.corpora) { + queryCorpora = options.corpora as string; + } + + let driveId: string | undefined; + driveId = options.driveId as string; + if (driveId === '') { + driveId = undefined; + } + + let queryString = ''; + const useQueryString = this.getNodeParameter('useQueryString', i) as boolean; + if (useQueryString === true) { + // Use the user defined query string + queryString = this.getNodeParameter('queryString', i) as string; + } else { + // Build query string out of parameters set by user + const queryFilters = this.getNodeParameter('queryFilters', i) as IDataObject; + + const queryFilterFields: string[] = []; + if (queryFilters.name) { + (queryFilters.name as IDataObject[]).forEach(nameFilter => { + let operation = nameFilter.operation; + if (operation === 'is') { + operation = '='; + } else if (operation === 'isNot') { + operation = '!='; + } + queryFilterFields.push(`name ${operation} '${nameFilter.value}'`); + }); queryString += queryFilterFields.join(' or '); } + + queryFilterFields.length = 0; + if (queryFilters.mimeType) { + (queryFilters.mimeType as IDataObject[]).forEach(mimeTypeFilter => { + let mimeType = mimeTypeFilter.mimeType; + if (mimeTypeFilter.mimeType === 'custom') { + mimeType = mimeTypeFilter.customMimeType; + } + queryFilterFields.push(`mimeType = '${mimeType}'`); + }); + + if (queryFilterFields.length) { + if (queryString !== '') { + queryString += ' and '; + } + + queryString += queryFilterFields.join(' or '); + } + } } + + const pageSize = this.getNodeParameter('limit', i) as number; + + const qs = { + pageSize, + orderBy: 'modifiedTime', + fields: `nextPageToken, files(${queryFields})`, + spaces: querySpaces, + q: queryString, + includeItemsFromAllDrives: (queryCorpora !== '' || driveId !== ''), + supportsAllDrives: (queryCorpora !== '' || driveId !== ''), + }; + + const response = await googleApiRequest.call(this, 'GET', `/drive/v3/files`, {}, qs); + + const files = response!.files; + + return [this.helpers.returnJsonArray(files as IDataObject[])]; + + } else if (operation === 'upload') { + // ---------------------------------- + // upload + // ---------------------------------- + const resolveData = this.getNodeParameter('resolveData', 0) as boolean; + + let mimeType = 'text/plain'; + let body; + let originalFilename: string | undefined; + if (this.getNodeParameter('binaryData', i) === true) { + // Is binary file to upload + const item = items[i]; + + if (item.binary === undefined) { + throw new NodeOperationError(this.getNode(), 'No binary data exists on item!'); + } + + const propertyNameUpload = this.getNodeParameter('binaryPropertyName', i) as string; + + if (item.binary[propertyNameUpload] === undefined) { + throw new NodeOperationError(this.getNode(), `No binary data property "${propertyNameUpload}" does not exists on item!`); + } + + if (item.binary[propertyNameUpload].mimeType) { + mimeType = item.binary[propertyNameUpload].mimeType; + } + + if (item.binary[propertyNameUpload].fileName) { + originalFilename = item.binary[propertyNameUpload].fileName; + } + + body = Buffer.from(item.binary[propertyNameUpload].data, BINARY_ENCODING); + } else { + // Is text file + body = Buffer.from(this.getNodeParameter('fileContent', i) as string, 'utf8'); + } + + const name = this.getNodeParameter('name', i) as string; + const parents = this.getNodeParameter('parents', i) as string[]; + + let qs: IDataObject = { + fields: queryFields, + uploadType: 'media', + }; + + const requestOptions = { + headers: { + 'Content-Type': mimeType, + 'Content-Length': body.byteLength, + }, + encoding: null, + json: false, + }; + + let response = await googleApiRequest.call(this, 'POST', `/upload/drive/v3/files`, body, qs, undefined, requestOptions); + + body = { + mimeType, + name, + originalFilename, + }; + + const properties = this.getNodeParameter('options.propertiesUi.propertyValues', i, []) as IDataObject[]; + + if (properties.length) { + Object.assign(body, { properties: properties.reduce((obj, value) => Object.assign(obj, { [`${value.key}`]: value.value }), {}) } ); + } + + const appProperties = this.getNodeParameter('options.appPropertiesUi.appPropertyValues', i, []) as IDataObject[]; + + if (properties.length) { + Object.assign(body, { appProperties: appProperties.reduce((obj, value) => Object.assign(obj, { [`${value.key}`]: value.value }), {}) }); + } + + qs = { + addParents: parents.join(','), + // When set to true shared drives can be used. + supportsAllDrives: true, + }; + + response = await googleApiRequest.call(this, 'PATCH', `/drive/v3/files/${JSON.parse(response).id}`, body, qs); + + if (resolveData === true) { + response = await googleApiRequest.call(this, 'GET', `/drive/v3/files/${response.id}`, {}, { fields: '*' }); + } + + returnData.push(response as IDataObject); + } else if (operation === 'update') { + // ---------------------------------- + // file:update + // ---------------------------------- + + const id = this.getNodeParameter('fileId', i) as string; + const updateFields = this.getNodeParameter('updateFields', i, {}) as IDataObject; + + const qs: IDataObject = { + supportsAllDrives: true, + }; + + Object.assign(qs, options); + + qs.fields = queryFields; + + if (updateFields.parentId && updateFields.parentId !== '') { + qs.addParents = updateFields.parentId; + } + + const responseData = await googleApiRequest.call(this, 'PATCH', `/drive/v3/files/${id}`, {}, qs); + returnData.push(responseData as IDataObject); } - const pageSize = this.getNodeParameter('limit', i) as number; + } + if (resource === 'folder') { + if (operation === 'create') { + // ---------------------------------- + // folder:create + // ---------------------------------- - const qs = { - pageSize, - orderBy: 'modifiedTime', - fields: `nextPageToken, files(${queryFields})`, - spaces: querySpaces, - q: queryString, - includeItemsFromAllDrives: (queryCorpora !== '' || driveId !== ''), - supportsAllDrives: (queryCorpora !== '' || driveId !== ''), - }; + const name = this.getNodeParameter('name', i) as string; - const response = await googleApiRequest.call(this, 'GET', `/drive/v3/files`, {}, qs); + const body = { + name, + mimeType: 'application/vnd.google-apps.folder', + parents: options.parents || [], + }; - const files = response!.files; + const qs = { + fields: queryFields, + supportsAllDrives: true, + }; - return [this.helpers.returnJsonArray(files as IDataObject[])]; + const response = await googleApiRequest.call(this, 'POST', '/drive/v3/files', body, qs); - } else if (operation === 'upload') { - // ---------------------------------- - // upload - // ---------------------------------- - const resolveData = this.getNodeParameter('resolveData', 0) as boolean; + returnData.push(response as IDataObject); + } + } + if (['file', 'folder'].includes(resource)) { + if (operation === 'delete') { + // ---------------------------------- + // delete + // ---------------------------------- - let mimeType = 'text/plain'; - let body; - let originalFilename: string | undefined; - if (this.getNodeParameter('binaryData', i) === true) { - // Is binary file to upload - const item = items[i]; + const fileId = this.getNodeParameter('fileId', i) as string; - if (item.binary === undefined) { - throw new NodeOperationError(this.getNode(), 'No binary data exists on item!'); + const response = await googleApiRequest.call(this, 'DELETE', `/drive/v3/files/${fileId}`); + + // If we are still here it did succeed + returnData.push({ + fileId, + success: true, + }); + } + if (operation === 'share') { + + const fileId = this.getNodeParameter('fileId', i) as string; + + const permissions = this.getNodeParameter('permissionsUi', i) as IDataObject; + + const options = this.getNodeParameter('options', i) as IDataObject; + + const body: IDataObject = {}; + + const qs: IDataObject = {}; + + if (permissions.permissionsValues) { + Object.assign(body, permissions.permissionsValues); } - const propertyNameUpload = this.getNodeParameter('binaryPropertyName', i) as string; + Object.assign(qs, options); - if (item.binary[propertyNameUpload] === undefined) { - throw new NodeOperationError(this.getNode(), `No binary data property "${propertyNameUpload}" does not exists on item!`); - } + const response = await googleApiRequest.call(this, 'POST', `/drive/v3/files/${fileId}/permissions`, body, qs); - if (item.binary[propertyNameUpload].mimeType) { - mimeType = item.binary[propertyNameUpload].mimeType; - } - - if (item.binary[propertyNameUpload].fileName) { - originalFilename = item.binary[propertyNameUpload].fileName; - } - - body = Buffer.from(item.binary[propertyNameUpload].data, BINARY_ENCODING); + returnData.push(response as IDataObject); + } + } + } catch (error) { + if (this.continueOnFail()) { + if (resource === 'file' && operation === 'download') { + items[i].json = { error: error.message }; } else { - // Is text file - body = Buffer.from(this.getNodeParameter('fileContent', i) as string, 'utf8'); + returnData.push({ error: error.message }); } - - const name = this.getNodeParameter('name', i) as string; - const parents = this.getNodeParameter('parents', i) as string[]; - - let qs: IDataObject = { - fields: queryFields, - uploadType: 'media', - }; - - const requestOptions = { - headers: { - 'Content-Type': mimeType, - 'Content-Length': body.byteLength, - }, - encoding: null, - json: false, - }; - - let response = await googleApiRequest.call(this, 'POST', `/upload/drive/v3/files`, body, qs, undefined, requestOptions); - - body = { - mimeType, - name, - originalFilename, - }; - - const properties = this.getNodeParameter('options.propertiesUi.propertyValues', i, []) as IDataObject[]; - - if (properties.length) { - Object.assign(body, { properties: properties.reduce((obj, value) => Object.assign(obj, { [`${value.key}`]: value.value }), {}) } ); - } - - const appProperties = this.getNodeParameter('options.appPropertiesUi.appPropertyValues', i, []) as IDataObject[]; - - if (properties.length) { - Object.assign(body, { appProperties: appProperties.reduce((obj, value) => Object.assign(obj, { [`${value.key}`]: value.value }), {}) }); - } - - qs = { - addParents: parents.join(','), - // When set to true shared drives can be used. - supportsAllDrives: true, - }; - - response = await googleApiRequest.call(this, 'PATCH', `/drive/v3/files/${JSON.parse(response).id}`, body, qs); - - if (resolveData === true) { - response = await googleApiRequest.call(this, 'GET', `/drive/v3/files/${response.id}`, {}, { fields: '*' }); - } - - returnData.push(response as IDataObject); - } else if (operation === 'update') { - // ---------------------------------- - // file:update - // ---------------------------------- - - const id = this.getNodeParameter('fileId', i) as string; - const updateFields = this.getNodeParameter('updateFields', i, {}) as IDataObject; - - const qs: IDataObject = { - supportsAllDrives: true, - }; - - Object.assign(qs, options); - - qs.fields = queryFields; - - if (updateFields.parentId && updateFields.parentId !== '') { - qs.addParents = updateFields.parentId; - } - - const responseData = await googleApiRequest.call(this, 'PATCH', `/drive/v3/files/${id}`, {}, qs); - returnData.push(responseData as IDataObject); - } - - } - if (resource === 'folder') { - if (operation === 'create') { - // ---------------------------------- - // folder:create - // ---------------------------------- - - const name = this.getNodeParameter('name', i) as string; - - const body = { - name, - mimeType: 'application/vnd.google-apps.folder', - parents: options.parents || [], - }; - - const qs = { - fields: queryFields, - supportsAllDrives: true, - }; - - const response = await googleApiRequest.call(this, 'POST', '/drive/v3/files', body, qs); - - returnData.push(response as IDataObject); - } - } - if (['file', 'folder'].includes(resource)) { - if (operation === 'delete') { - // ---------------------------------- - // delete - // ---------------------------------- - - const fileId = this.getNodeParameter('fileId', i) as string; - - const response = await googleApiRequest.call(this, 'DELETE', `/drive/v3/files/${fileId}`); - - // If we are still here it did succeed - returnData.push({ - fileId, - success: true, - }); - } - if (operation === 'share') { - - const fileId = this.getNodeParameter('fileId', i) as string; - - const permissions = this.getNodeParameter('permissionsUi', i) as IDataObject; - - const options = this.getNodeParameter('options', i) as IDataObject; - - const body: IDataObject = {}; - - const qs: IDataObject = {}; - - if (permissions.permissionsValues) { - Object.assign(body, permissions.permissionsValues); - } - - Object.assign(qs, options); - - const response = await googleApiRequest.call(this, 'POST', `/drive/v3/files/${fileId}/permissions`, body, qs); - - returnData.push(response as IDataObject); + continue; } + throw error; } } if (resource === 'file' && operation === 'download') { diff --git a/packages/nodes-base/nodes/Google/Firebase/RealtimeDatabase/RealtimeDatabase.node.ts b/packages/nodes-base/nodes/Google/Firebase/RealtimeDatabase/RealtimeDatabase.node.ts index e28c9b8176..dfabec6b5d 100644 --- a/packages/nodes-base/nodes/Google/Firebase/RealtimeDatabase/RealtimeDatabase.node.ts +++ b/packages/nodes-base/nodes/Google/Firebase/RealtimeDatabase/RealtimeDatabase.node.ts @@ -150,49 +150,56 @@ export class RealtimeDatabase implements INodeType { } for (let i = 0; i < length; i++) { - const projectId = this.getNodeParameter('projectId', i) as string; - let method = 'GET', attributes = ''; - const document: IDataObject = {}; - if (operation === 'create') { - method = 'PUT'; - attributes = this.getNodeParameter('attributes', i) as string; - } else if (operation === 'delete') { - method = 'DELETE'; - } else if (operation === 'get') { - method = 'GET'; - } else if (operation === 'push') { - method = 'POST'; - attributes = this.getNodeParameter('attributes', i) as string; - } else if (operation === 'update') { - method = 'PATCH'; - attributes = this.getNodeParameter('attributes', i) as string; - } - - if (attributes) { - const attributeList = attributes.split(',').map(el => el.trim()); - attributeList.map((attribute: string) => { - if (items[i].json.hasOwnProperty(attribute)) { - document[attribute] = items[i].json[attribute]; - } - }); - } - - responseData = await googleApiRequest.call( - this, - projectId, - method, - this.getNodeParameter('path', i) as string, - document, - ); - - if (responseData === null) { - if (operation === 'get') { - throw new NodeApiError(this.getNode(), responseData, { message: `Requested entity was not found.` }); - } else if (method === 'DELETE') { - responseData = { success: true }; + try { + const projectId = this.getNodeParameter('projectId', i) as string; + let method = 'GET', attributes = ''; + const document: IDataObject = {}; + if (operation === 'create') { + method = 'PUT'; + attributes = this.getNodeParameter('attributes', i) as string; + } else if (operation === 'delete') { + method = 'DELETE'; + } else if (operation === 'get') { + method = 'GET'; + } else if (operation === 'push') { + method = 'POST'; + attributes = this.getNodeParameter('attributes', i) as string; + } else if (operation === 'update') { + method = 'PATCH'; + attributes = this.getNodeParameter('attributes', i) as string; } - } + if (attributes) { + const attributeList = attributes.split(',').map(el => el.trim()); + attributeList.map((attribute: string) => { + if (items[i].json.hasOwnProperty(attribute)) { + document[attribute] = items[i].json[attribute]; + } + }); + } + + responseData = await googleApiRequest.call( + this, + projectId, + method, + this.getNodeParameter('path', i) as string, + document, + ); + + if (responseData === null) { + if (operation === 'get') { + throw new NodeApiError(this.getNode(), responseData, { message: `Requested entity was not found.` }); + } else if (method === 'DELETE') { + responseData = { success: true }; + } + } + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; + } if (Array.isArray(responseData)) { returnData.push.apply(returnData, responseData as IDataObject[]); } else if (typeof responseData === 'string' || typeof responseData === 'number') { diff --git a/packages/nodes-base/nodes/Google/Gmail/Gmail.node.ts b/packages/nodes-base/nodes/Google/Gmail/Gmail.node.ts index 2fd4457849..1107630f05 100644 --- a/packages/nodes-base/nodes/Google/Gmail/Gmail.node.ts +++ b/packages/nodes-base/nodes/Google/Gmail/Gmail.node.ts @@ -206,599 +206,612 @@ export class Gmail implements INodeType { let responseData; for (let i = 0; i < items.length; i++) { - if (resource === 'label') { - if (operation === 'create') { - //https://developers.google.com/gmail/api/v1/reference/users/labels/create - const labelName = this.getNodeParameter('name', i) as string; - const labelListVisibility = this.getNodeParameter('labelListVisibility', i) as string; - const messageListVisibility = this.getNodeParameter('messageListVisibility', i) as string; + try { + if (resource === 'label') { + if (operation === 'create') { + //https://developers.google.com/gmail/api/v1/reference/users/labels/create + const labelName = this.getNodeParameter('name', i) as string; + const labelListVisibility = this.getNodeParameter('labelListVisibility', i) as string; + const messageListVisibility = this.getNodeParameter('messageListVisibility', i) as string; - method = 'POST'; - endpoint = '/gmail/v1/users/me/labels'; + method = 'POST'; + endpoint = '/gmail/v1/users/me/labels'; - body = { - labelListVisibility, - messageListVisibility, - name: labelName, - }; - - responseData = await googleApiRequest.call(this, method, endpoint, body, qs); - } - if (operation === 'delete') { - //https://developers.google.com/gmail/api/v1/reference/users/labels/delete - const labelId = this.getNodeParameter('labelId', i) as string[]; - - method = 'DELETE'; - endpoint = `/gmail/v1/users/me/labels/${labelId}`; - responseData = await googleApiRequest.call(this, method, endpoint, body, qs); - responseData = { success: true }; - - } - if (operation === 'get') { - // https://developers.google.com/gmail/api/v1/reference/users/labels/get - const labelId = this.getNodeParameter('labelId', i); - - method = 'GET'; - endpoint = `/gmail/v1/users/me/labels/${labelId}`; - - responseData = await googleApiRequest.call(this, method, endpoint, body, qs); - } - if (operation === 'getAll') { - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - - responseData = await googleApiRequest.call( - this, - 'GET', - `/gmail/v1/users/me/labels`, - {}, - qs, - ); - - responseData = responseData.labels; - - if (!returnAll) { - const limit = this.getNodeParameter('limit', i) as number; - responseData = responseData.splice(0, limit); - } - } - } - if (resource === 'messageLabel') { - if (operation === 'remove') { - //https://developers.google.com/gmail/api/v1/reference/users/messages/modify - const messageID = this.getNodeParameter('messageId', i); - const labelIds = this.getNodeParameter('labelIds', i) as string[]; - - method = 'POST'; - endpoint = `/gmail/v1/users/me/messages/${messageID}/modify`; - body = { - removeLabelIds: labelIds, - }; - responseData = await googleApiRequest.call(this, method, endpoint, body, qs); - } - if (operation === 'add') { - // https://developers.google.com/gmail/api/v1/reference/users/messages/modify - const messageID = this.getNodeParameter('messageId', i); - const labelIds = this.getNodeParameter('labelIds', i) as string[]; - - method = 'POST'; - endpoint = `/gmail/v1/users/me/messages/${messageID}/modify`; - - body = { - addLabelIds: labelIds, - }; - - responseData = await googleApiRequest.call(this, method, endpoint, body, qs); - } - } - if (resource === 'message') { - if (operation === 'send') { - // https://developers.google.com/gmail/api/v1/reference/users/messages/send - - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - - let toStr = ''; - let ccStr = ''; - let bccStr = ''; - let attachmentsList: IDataObject[] = []; - - const toList = this.getNodeParameter('toList', i) as IDataObject[]; - - toList.forEach((email) => { - toStr += `<${email}>, `; - }); - - if (additionalFields.ccList) { - const ccList = additionalFields.ccList as IDataObject[]; - - ccList.forEach((email) => { - ccStr += `<${email}>, `; - }); - } - - if (additionalFields.bccList) { - const bccList = additionalFields.bccList as IDataObject[]; - - bccList.forEach((email) => { - bccStr += `<${email}>, `; - }); - } - - if (additionalFields.attachmentsUi) { - const attachmentsUi = additionalFields.attachmentsUi as IDataObject; - const attachmentsBinary = []; - if (!isEmpty(attachmentsUi)) { - if (attachmentsUi.hasOwnProperty('attachmentsBinary') - && !isEmpty(attachmentsUi.attachmentsBinary) - && items[i].binary) { - for (const { property } of attachmentsUi.attachmentsBinary as IDataObject[]) { - for (const binaryProperty of (property as string).split(',')) { - if (items[i].binary![binaryProperty] !== undefined) { - const binaryData = items[i].binary![binaryProperty]; - attachmentsBinary.push({ - name: binaryData.fileName || 'unknown', - content: binaryData.data, - type: binaryData.mimeType, - }); - } - } - } - } - - qs = { - userId: 'me', - uploadType: 'media', - }; - attachmentsList = attachmentsBinary; - } - } - - const email: IEmail = { - to: toStr, - cc: ccStr, - bcc: bccStr, - subject: this.getNodeParameter('subject', i) as string, - body: this.getNodeParameter('message', i) as string, - attachments: attachmentsList, - }; - - if (this.getNodeParameter('includeHtml', i, false) as boolean === true) { - email.htmlBody = this.getNodeParameter('htmlMessage', i) as string; - } - - endpoint = '/gmail/v1/users/me/messages/send'; - method = 'POST'; - - body = { - raw: await encodeEmail(email), - }; - - responseData = await googleApiRequest.call(this, method, endpoint, body, qs); - } - if (operation === 'reply') { - - const id = this.getNodeParameter('messageId', i) as string; - - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - - let toStr = ''; - let ccStr = ''; - let bccStr = ''; - let attachmentsList: IDataObject[] = []; - - const toList = this.getNodeParameter('toList', i) as IDataObject[]; - - toList.forEach((email) => { - toStr += `<${email}>, `; - }); - - if (additionalFields.ccList) { - const ccList = additionalFields.ccList as IDataObject[]; - - ccList.forEach((email) => { - ccStr += `<${email}>, `; - }); - } - - if (additionalFields.bccList) { - const bccList = additionalFields.bccList as IDataObject[]; - - bccList.forEach((email) => { - bccStr += `<${email}>, `; - }); - } - - if (additionalFields.attachmentsUi) { - const attachmentsUi = additionalFields.attachmentsUi as IDataObject; - const attachmentsBinary = []; - if (!isEmpty(attachmentsUi)) { - if (attachmentsUi.hasOwnProperty('attachmentsBinary') - && !isEmpty(attachmentsUi.attachmentsBinary) - && items[i].binary) { - for (const { property } of attachmentsUi.attachmentsBinary as IDataObject[]) { - for (const binaryProperty of (property as string).split(',')) { - if (items[i].binary![binaryProperty] !== undefined) { - const binaryData = items[i].binary![binaryProperty]; - attachmentsBinary.push({ - name: binaryData.fileName || 'unknown', - content: binaryData.data, - type: binaryData.mimeType, - }); - } - } - } - } - - qs = { - userId: 'me', - uploadType: 'media', - }; - attachmentsList = attachmentsBinary; - } - } - // if no recipient is defined then grab the one who sent the email - if (toStr === '') { - endpoint = `/gmail/v1/users/me/messages/${id}`; - - qs.format = 'metadata'; - - const { payload } = await googleApiRequest.call(this, method, endpoint, body, qs); - - for (const header of payload.headers as IDataObject[]) { - if (header.name === 'From') { - toStr = `<${extractEmail(header.value as string)}>,`; - break; - } - } - } - - const email: IEmail = { - to: toStr, - cc: ccStr, - bcc: bccStr, - subject: this.getNodeParameter('subject', i) as string, - body: this.getNodeParameter('message', i) as string, - attachments: attachmentsList, - }; - - if (this.getNodeParameter('includeHtml', i, false) as boolean === true) { - email.htmlBody = this.getNodeParameter('htmlMessage', i) as string; - } - - endpoint = '/gmail/v1/users/me/messages/send'; - method = 'POST'; - - email.inReplyTo = id; - email.reference = id; - - body = { - raw: await encodeEmail(email), - threadId: this.getNodeParameter('threadId', i) as string, - }; - - responseData = await googleApiRequest.call(this, method, endpoint, body, qs); - } - if (operation === 'get') { - //https://developers.google.com/gmail/api/v1/reference/users/messages/get - method = 'GET'; - - const id = this.getNodeParameter('messageId', i); - - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const format = additionalFields.format || 'resolved'; - - if (format === 'resolved') { - qs.format = 'raw'; - } else { - qs.format = format; - } - - endpoint = `/gmail/v1/users/me/messages/${id}`; - - responseData = await googleApiRequest.call(this, method, endpoint, body, qs); - - let nodeExecutionData: INodeExecutionData; - if (format === 'resolved') { - const dataPropertyNameDownload = additionalFields.dataPropertyAttachmentsPrefixName as string || 'attachment_'; - - nodeExecutionData = await parseRawEmail.call(this, responseData, dataPropertyNameDownload); - } else { - nodeExecutionData = { - json: responseData, + body = { + labelListVisibility, + messageListVisibility, + name: labelName, }; + + responseData = await googleApiRequest.call(this, method, endpoint, body, qs); } + if (operation === 'delete') { + //https://developers.google.com/gmail/api/v1/reference/users/labels/delete + const labelId = this.getNodeParameter('labelId', i) as string[]; - responseData = nodeExecutionData; - } - if (operation === 'getAll') { - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - Object.assign(qs, additionalFields); + method = 'DELETE'; + endpoint = `/gmail/v1/users/me/labels/${labelId}`; + responseData = await googleApiRequest.call(this, method, endpoint, body, qs); + responseData = { success: true }; - if (qs.labelIds) { - // tslint:disable-next-line: triple-equals - if (qs.labelIds == '') { - delete qs.labelIds; - } else { - qs.labelIds = qs.labelIds as string[]; - } } + if (operation === 'get') { + // https://developers.google.com/gmail/api/v1/reference/users/labels/get + const labelId = this.getNodeParameter('labelId', i); + + method = 'GET'; + endpoint = `/gmail/v1/users/me/labels/${labelId}`; + + responseData = await googleApiRequest.call(this, method, endpoint, body, qs); + } + if (operation === 'getAll') { + const returnAll = this.getNodeParameter('returnAll', i) as boolean; - if (returnAll) { - responseData = await googleApiRequestAllItems.call( - this, - 'messages', - 'GET', - `/gmail/v1/users/me/messages`, - {}, - qs, - ); - } else { - qs.maxResults = this.getNodeParameter('limit', i) as number; responseData = await googleApiRequest.call( this, 'GET', - `/gmail/v1/users/me/messages`, + `/gmail/v1/users/me/labels`, {}, qs, ); - responseData = responseData.messages; - } - if (responseData === undefined) { - responseData = []; - } + responseData = responseData.labels; - const format = additionalFields.format || 'resolved'; - - if (format !== 'ids') { - - if (format === 'resolved') { - qs.format = 'raw'; - } else { - qs.format = format; - } - - for (let i = 0; i < responseData.length; i++) { - responseData[i] = await googleApiRequest.call( - this, - 'GET', - `/gmail/v1/users/me/messages/${responseData[i].id}`, - body, - qs, - ); - - if (format === 'resolved') { - const dataPropertyNameDownload = additionalFields.dataPropertyAttachmentsPrefixName as string || 'attachment_'; - - responseData[i] = await parseRawEmail.call(this, responseData[i], dataPropertyNameDownload); - } + if (!returnAll) { + const limit = this.getNodeParameter('limit', i) as number; + responseData = responseData.splice(0, limit); } } + } + if (resource === 'messageLabel') { + if (operation === 'remove') { + //https://developers.google.com/gmail/api/v1/reference/users/messages/modify + const messageID = this.getNodeParameter('messageId', i); + const labelIds = this.getNodeParameter('labelIds', i) as string[]; - if (format !== 'resolved') { - responseData = this.helpers.returnJsonArray(responseData); + method = 'POST'; + endpoint = `/gmail/v1/users/me/messages/${messageID}/modify`; + body = { + removeLabelIds: labelIds, + }; + responseData = await googleApiRequest.call(this, method, endpoint, body, qs); } + if (operation === 'add') { + // https://developers.google.com/gmail/api/v1/reference/users/messages/modify + const messageID = this.getNodeParameter('messageId', i); + const labelIds = this.getNodeParameter('labelIds', i) as string[]; + method = 'POST'; + endpoint = `/gmail/v1/users/me/messages/${messageID}/modify`; + + body = { + addLabelIds: labelIds, + }; + + responseData = await googleApiRequest.call(this, method, endpoint, body, qs); + } } - if (operation === 'delete') { - // https://developers.google.com/gmail/api/v1/reference/users/messages/delete - method = 'DELETE'; - const id = this.getNodeParameter('messageId', i); + if (resource === 'message') { + if (operation === 'send') { + // https://developers.google.com/gmail/api/v1/reference/users/messages/send - endpoint = `/gmail/v1/users/me/messages/${id}`; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - responseData = await googleApiRequest.call(this, method, endpoint, body, qs); + let toStr = ''; + let ccStr = ''; + let bccStr = ''; + let attachmentsList: IDataObject[] = []; - responseData = { success: true }; - } - } - if (resource === 'draft') { - if (operation === 'create') { - // https://developers.google.com/gmail/api/v1/reference/users/drafts/create - - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - - let toStr = ''; - let ccStr = ''; - let bccStr = ''; - let attachmentsList: IDataObject[] = []; - - if (additionalFields.toList) { - const toList = additionalFields.toList as IDataObject[]; + const toList = this.getNodeParameter('toList', i) as IDataObject[]; toList.forEach((email) => { toStr += `<${email}>, `; }); - } - if (additionalFields.ccList) { - const ccList = additionalFields.ccList as IDataObject[]; + if (additionalFields.ccList) { + const ccList = additionalFields.ccList as IDataObject[]; - ccList.forEach((email) => { - ccStr += `<${email}>, `; - }); - } + ccList.forEach((email) => { + ccStr += `<${email}>, `; + }); + } - if (additionalFields.bccList) { - const bccList = additionalFields.bccList as IDataObject[]; + if (additionalFields.bccList) { + const bccList = additionalFields.bccList as IDataObject[]; - bccList.forEach((email) => { - bccStr += `<${email}>, `; - }); - } + bccList.forEach((email) => { + bccStr += `<${email}>, `; + }); + } - if (additionalFields.attachmentsUi) { - const attachmentsUi = additionalFields.attachmentsUi as IDataObject; - const attachmentsBinary = []; - if (!isEmpty(attachmentsUi)) { - if (attachmentsUi.hasOwnProperty('attachmentsBinary') - && !isEmpty(attachmentsUi.attachmentsBinary) - && items[i].binary) { - for (const { property } of attachmentsUi.attachmentsBinary as IDataObject[]) { - for (const binaryProperty of (property as string).split(',')) { - if (items[i].binary![binaryProperty] !== undefined) { - const binaryData = items[i].binary![binaryProperty]; - attachmentsBinary.push({ - name: binaryData.fileName || 'unknown', - content: binaryData.data, - type: binaryData.mimeType, - }); + if (additionalFields.attachmentsUi) { + const attachmentsUi = additionalFields.attachmentsUi as IDataObject; + const attachmentsBinary = []; + if (!isEmpty(attachmentsUi)) { + if (attachmentsUi.hasOwnProperty('attachmentsBinary') + && !isEmpty(attachmentsUi.attachmentsBinary) + && items[i].binary) { + // @ts-ignore + for (const { property } of attachmentsUi.attachmentsBinary as IDataObject[]) { + for (const binaryProperty of (property as string).split(',')) { + if (items[i].binary![binaryProperty] !== undefined) { + const binaryData = items[i].binary![binaryProperty]; + attachmentsBinary.push({ + name: binaryData.fileName || 'unknown', + content: binaryData.data, + type: binaryData.mimeType, + }); + } } } } + + qs = { + userId: 'me', + uploadType: 'media', + }; + attachmentsList = attachmentsBinary; } - - qs = { - userId: 'me', - uploadType: 'media', - }; - attachmentsList = attachmentsBinary; } - } - const email: IEmail = { - to: toStr, - cc: ccStr, - bcc: bccStr, - subject: this.getNodeParameter('subject', i) as string, - body: this.getNodeParameter('message', i) as string, - attachments: attachmentsList, - }; - - if (this.getNodeParameter('includeHtml', i, false) as boolean === true) { - email.htmlBody = this.getNodeParameter('htmlMessage', i) as string; - } - - endpoint = '/gmail/v1/users/me/drafts'; - method = 'POST'; - - body = { - message: { - raw: await encodeEmail(email), - }, - }; - - responseData = await googleApiRequest.call(this, method, endpoint, body, qs); - } - if (operation === 'get') { - // https://developers.google.com/gmail/api/v1/reference/users/drafts/get - method = 'GET'; - const id = this.getNodeParameter('messageId', i); - - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const format = additionalFields.format || 'resolved'; - - if (format === 'resolved') { - qs.format = 'raw'; - } else { - qs.format = format; - } - - endpoint = `/gmail/v1/users/me/drafts/${id}`; - - responseData = await googleApiRequest.call(this, method, endpoint, body, qs); - - const binaryData: IBinaryKeyData = {}; - - let nodeExecutionData: INodeExecutionData; - if (format === 'resolved') { - const dataPropertyNameDownload = additionalFields.dataPropertyAttachmentsPrefixName as string || 'attachment_'; - - nodeExecutionData = await parseRawEmail.call(this, responseData.message, dataPropertyNameDownload); - - // Add the draft-id - nodeExecutionData.json.messageId = nodeExecutionData.json.id; - nodeExecutionData.json.id = responseData.id; - } else { - nodeExecutionData = { - json: responseData, - binary: Object.keys(binaryData).length ? binaryData : undefined, + const email: IEmail = { + to: toStr, + cc: ccStr, + bcc: bccStr, + subject: this.getNodeParameter('subject', i) as string, + body: this.getNodeParameter('message', i) as string, + attachments: attachmentsList, }; + + if (this.getNodeParameter('includeHtml', i, false) as boolean === true) { + email.htmlBody = this.getNodeParameter('htmlMessage', i) as string; + } + + endpoint = '/gmail/v1/users/me/messages/send'; + method = 'POST'; + + body = { + raw: await encodeEmail(email), + }; + + responseData = await googleApiRequest.call(this, method, endpoint, body, qs); } + if (operation === 'reply') { - responseData = nodeExecutionData; - } - if (operation === 'delete') { - // https://developers.google.com/gmail/api/v1/reference/users/drafts/delete - method = 'DELETE'; - const id = this.getNodeParameter('messageId', i); + const id = this.getNodeParameter('messageId', i) as string; - endpoint = `/gmail/v1/users/me/drafts/${id}`; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - responseData = await googleApiRequest.call(this, method, endpoint, body, qs); + let toStr = ''; + let ccStr = ''; + let bccStr = ''; + let attachmentsList: IDataObject[] = []; - responseData = { success: true }; - } - if (operation === 'getAll') { - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - Object.assign(qs, additionalFields); + const toList = this.getNodeParameter('toList', i) as IDataObject[]; - if (returnAll) { - responseData = await googleApiRequestAllItems.call( - this, - 'drafts', - 'GET', - `/gmail/v1/users/me/drafts`, - {}, - qs, - ); - } else { - qs.maxResults = this.getNodeParameter('limit', i) as number; - responseData = await googleApiRequest.call( - this, - 'GET', - `/gmail/v1/users/me/drafts`, - {}, - qs, - ); - responseData = responseData.drafts; + toList.forEach((email) => { + toStr += `<${email}>, `; + }); + + if (additionalFields.ccList) { + const ccList = additionalFields.ccList as IDataObject[]; + + ccList.forEach((email) => { + ccStr += `<${email}>, `; + }); + } + + if (additionalFields.bccList) { + const bccList = additionalFields.bccList as IDataObject[]; + + bccList.forEach((email) => { + bccStr += `<${email}>, `; + }); + } + + if (additionalFields.attachmentsUi) { + const attachmentsUi = additionalFields.attachmentsUi as IDataObject; + const attachmentsBinary = []; + if (!isEmpty(attachmentsUi)) { + if (attachmentsUi.hasOwnProperty('attachmentsBinary') + && !isEmpty(attachmentsUi.attachmentsBinary) + && items[i].binary) { + // @ts-ignore + for (const { property } of attachmentsUi.attachmentsBinary as IDataObject[]) { + for (const binaryProperty of (property as string).split(',')) { + if (items[i].binary![binaryProperty] !== undefined) { + const binaryData = items[i].binary![binaryProperty]; + attachmentsBinary.push({ + name: binaryData.fileName || 'unknown', + content: binaryData.data, + type: binaryData.mimeType, + }); + } + } + } + } + + qs = { + userId: 'me', + uploadType: 'media', + }; + attachmentsList = attachmentsBinary; + } + } + // if no recipient is defined then grab the one who sent the email + if (toStr === '') { + endpoint = `/gmail/v1/users/me/messages/${id}`; + + qs.format = 'metadata'; + + const { payload } = await googleApiRequest.call(this, method, endpoint, body, qs); + + for (const header of payload.headers as IDataObject[]) { + if (header.name === 'From') { + toStr = `<${extractEmail(header.value as string)}>,`; + break; + } + } + } + + const email: IEmail = { + to: toStr, + cc: ccStr, + bcc: bccStr, + subject: this.getNodeParameter('subject', i) as string, + body: this.getNodeParameter('message', i) as string, + attachments: attachmentsList, + }; + + if (this.getNodeParameter('includeHtml', i, false) as boolean === true) { + email.htmlBody = this.getNodeParameter('htmlMessage', i) as string; + } + + endpoint = '/gmail/v1/users/me/messages/send'; + method = 'POST'; + + email.inReplyTo = id; + email.reference = id; + + body = { + raw: await encodeEmail(email), + threadId: this.getNodeParameter('threadId', i) as string, + }; + + responseData = await googleApiRequest.call(this, method, endpoint, body, qs); } + if (operation === 'get') { + //https://developers.google.com/gmail/api/v1/reference/users/messages/get + method = 'GET'; - if (responseData === undefined) { - responseData = []; - } + const id = this.getNodeParameter('messageId', i); - const format = additionalFields.format || 'resolved'; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const format = additionalFields.format || 'resolved'; - if (format !== 'ids') { if (format === 'resolved') { qs.format = 'raw'; } else { qs.format = format; } - for (let i = 0; i < responseData.length; i++) { + endpoint = `/gmail/v1/users/me/messages/${id}`; - responseData[i] = await googleApiRequest.call( - this, - 'GET', - `/gmail/v1/users/me/drafts/${responseData[i].id}`, - body, - qs, - ); + responseData = await googleApiRequest.call(this, method, endpoint, body, qs); - if (format === 'resolved') { - const dataPropertyNameDownload = additionalFields.dataPropertyAttachmentsPrefixName as string || 'attachment_'; - const id = responseData[i].id; - responseData[i] = await parseRawEmail.call(this, responseData[i].message, dataPropertyNameDownload); + let nodeExecutionData: INodeExecutionData; + if (format === 'resolved') { + const dataPropertyNameDownload = additionalFields.dataPropertyAttachmentsPrefixName as string || 'attachment_'; - // Add the draft-id - responseData[i].json.messageId = responseData[i].json.id; - responseData[i].json.id = id; + nodeExecutionData = await parseRawEmail.call(this, responseData, dataPropertyNameDownload); + } else { + nodeExecutionData = { + json: responseData, + }; + } + + responseData = nodeExecutionData; + } + if (operation === 'getAll') { + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + Object.assign(qs, additionalFields); + + if (qs.labelIds) { + // tslint:disable-next-line: triple-equals + if (qs.labelIds == '') { + delete qs.labelIds; + } else { + qs.labelIds = qs.labelIds as string[]; } } - } - if (format !== 'resolved') { - responseData = this.helpers.returnJsonArray(responseData); + if (returnAll) { + responseData = await googleApiRequestAllItems.call( + this, + 'messages', + 'GET', + `/gmail/v1/users/me/messages`, + {}, + qs, + ); + } else { + qs.maxResults = this.getNodeParameter('limit', i) as number; + responseData = await googleApiRequest.call( + this, + 'GET', + `/gmail/v1/users/me/messages`, + {}, + qs, + ); + responseData = responseData.messages; + } + + if (responseData === undefined) { + responseData = []; + } + + const format = additionalFields.format || 'resolved'; + + if (format !== 'ids') { + + if (format === 'resolved') { + qs.format = 'raw'; + } else { + qs.format = format; + } + + for (let i = 0; i < responseData.length; i++) { + responseData[i] = await googleApiRequest.call( + this, + 'GET', + `/gmail/v1/users/me/messages/${responseData[i].id}`, + body, + qs, + ); + + if (format === 'resolved') { + const dataPropertyNameDownload = additionalFields.dataPropertyAttachmentsPrefixName as string || 'attachment_'; + + responseData[i] = await parseRawEmail.call(this, responseData[i], dataPropertyNameDownload); + } + } + } + + if (format !== 'resolved') { + responseData = this.helpers.returnJsonArray(responseData); + } + + } + if (operation === 'delete') { + // https://developers.google.com/gmail/api/v1/reference/users/messages/delete + method = 'DELETE'; + const id = this.getNodeParameter('messageId', i); + + endpoint = `/gmail/v1/users/me/messages/${id}`; + + responseData = await googleApiRequest.call(this, method, endpoint, body, qs); + + responseData = { success: true }; } } - } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else { - returnData.push(responseData as IDataObject); + if (resource === 'draft') { + if (operation === 'create') { + // https://developers.google.com/gmail/api/v1/reference/users/drafts/create + + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + + let toStr = ''; + let ccStr = ''; + let bccStr = ''; + let attachmentsList: IDataObject[] = []; + + if (additionalFields.toList) { + const toList = additionalFields.toList as IDataObject[]; + + toList.forEach((email) => { + toStr += `<${email}>, `; + }); + } + + if (additionalFields.ccList) { + const ccList = additionalFields.ccList as IDataObject[]; + + ccList.forEach((email) => { + ccStr += `<${email}>, `; + }); + } + + if (additionalFields.bccList) { + const bccList = additionalFields.bccList as IDataObject[]; + + bccList.forEach((email) => { + bccStr += `<${email}>, `; + }); + } + + if (additionalFields.attachmentsUi) { + const attachmentsUi = additionalFields.attachmentsUi as IDataObject; + const attachmentsBinary = []; + if (!isEmpty(attachmentsUi)) { + if (!isEmpty(attachmentsUi)) { + if (attachmentsUi.hasOwnProperty('attachmentsBinary') + && !isEmpty(attachmentsUi.attachmentsBinary) + && items[i].binary) { + for (const { property } of attachmentsUi.attachmentsBinary as IDataObject[]) { + for (const binaryProperty of (property as string).split(',')) { + if (items[i].binary![binaryProperty] !== undefined) { + const binaryData = items[i].binary![binaryProperty]; + attachmentsBinary.push({ + name: binaryData.fileName || 'unknown', + content: binaryData.data, + type: binaryData.mimeType, + }); + } + } + } + } + } + + qs = { + userId: 'me', + uploadType: 'media', + }; + + attachmentsList = attachmentsBinary; + } + } + + const email: IEmail = { + to: toStr, + cc: ccStr, + bcc: bccStr, + subject: this.getNodeParameter('subject', i) as string, + body: this.getNodeParameter('message', i) as string, + attachments: attachmentsList, + }; + + if (this.getNodeParameter('includeHtml', i, false) as boolean === true) { + email.htmlBody = this.getNodeParameter('htmlMessage', i) as string; + } + + endpoint = '/gmail/v1/users/me/drafts'; + method = 'POST'; + + body = { + message: { + raw: await encodeEmail(email), + }, + }; + + responseData = await googleApiRequest.call(this, method, endpoint, body, qs); + } + if (operation === 'get') { + // https://developers.google.com/gmail/api/v1/reference/users/drafts/get + method = 'GET'; + const id = this.getNodeParameter('messageId', i); + + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const format = additionalFields.format || 'resolved'; + + if (format === 'resolved') { + qs.format = 'raw'; + } else { + qs.format = format; + } + + endpoint = `/gmail/v1/users/me/drafts/${id}`; + + responseData = await googleApiRequest.call(this, method, endpoint, body, qs); + + const binaryData: IBinaryKeyData = {}; + + let nodeExecutionData: INodeExecutionData; + if (format === 'resolved') { + const dataPropertyNameDownload = additionalFields.dataPropertyAttachmentsPrefixName as string || 'attachment_'; + + nodeExecutionData = await parseRawEmail.call(this, responseData.message, dataPropertyNameDownload); + + // Add the draft-id + nodeExecutionData.json.messageId = nodeExecutionData.json.id; + nodeExecutionData.json.id = responseData.id; + } else { + nodeExecutionData = { + json: responseData, + binary: Object.keys(binaryData).length ? binaryData : undefined, + }; + } + + responseData = nodeExecutionData; + } + if (operation === 'delete') { + // https://developers.google.com/gmail/api/v1/reference/users/drafts/delete + method = 'DELETE'; + const id = this.getNodeParameter('messageId', i); + + endpoint = `/gmail/v1/users/me/drafts/${id}`; + + responseData = await googleApiRequest.call(this, method, endpoint, body, qs); + + responseData = { success: true }; + } + if (operation === 'getAll') { + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + Object.assign(qs, additionalFields); + + if (returnAll) { + responseData = await googleApiRequestAllItems.call( + this, + 'drafts', + 'GET', + `/gmail/v1/users/me/drafts`, + {}, + qs, + ); + } else { + qs.maxResults = this.getNodeParameter('limit', i) as number; + responseData = await googleApiRequest.call( + this, + 'GET', + `/gmail/v1/users/me/drafts`, + {}, + qs, + ); + responseData = responseData.drafts; + } + + if (responseData === undefined) { + responseData = []; + } + + const format = additionalFields.format || 'resolved'; + + if (format !== 'ids') { + if (format === 'resolved') { + qs.format = 'raw'; + } else { + qs.format = format; + } + + for (let i = 0; i < responseData.length; i++) { + + responseData[i] = await googleApiRequest.call( + this, + 'GET', + `/gmail/v1/users/me/drafts/${responseData[i].id}`, + body, + qs, + ); + + if (format === 'resolved') { + const dataPropertyNameDownload = additionalFields.dataPropertyAttachmentsPrefixName as string || 'attachment_'; + const id = responseData[i].id; + responseData[i] = await parseRawEmail.call(this, responseData[i].message, dataPropertyNameDownload); + + // Add the draft-id + responseData[i].json.messageId = responseData[i].json.id; + responseData[i].json.id = id; + } + } + } + + if (format !== 'resolved') { + responseData = this.helpers.returnJsonArray(responseData); + } + } + } + if (Array.isArray(responseData)) { + returnData.push.apply(returnData, responseData as IDataObject[]); + } else { + returnData.push(responseData as IDataObject); + } + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } } if (['draft', 'message'].includes(resource) && ['get', 'getAll'].includes(operation)) { diff --git a/packages/nodes-base/nodes/Google/Sheet/GoogleSheets.node.ts b/packages/nodes-base/nodes/Google/Sheet/GoogleSheets.node.ts index cb793ce0f4..e7d5cf9746 100644 --- a/packages/nodes-base/nodes/Google/Sheet/GoogleSheets.node.ts +++ b/packages/nodes-base/nodes/Google/Sheet/GoogleSheets.node.ts @@ -1034,60 +1034,81 @@ export class GoogleSheets implements INodeType { // ---------------------------------- // append // ---------------------------------- - const keyRow = parseInt(this.getNodeParameter('keyRow', 0) as string, 10); + try { + const keyRow = parseInt(this.getNodeParameter('keyRow', 0) as string, 10); - const items = this.getInputData(); + const items = this.getInputData(); - const setData: IDataObject[] = []; - items.forEach((item) => { - setData.push(item.json); - }); + const setData: IDataObject[] = []; + items.forEach((item) => { + setData.push(item.json); + }); - // Convert data into array format - const data = await sheet.appendSheetData(setData, sheet.encodeRange(range), keyRow, valueInputMode); + // Convert data into array format + const data = await sheet.appendSheetData(setData, sheet.encodeRange(range), keyRow, valueInputMode); - // TODO: Should add this data somewhere - // TODO: Should have something like add metadata which does not get passed through + // TODO: Should add this data somewhere + // TODO: Should have something like add metadata which does not get passed through - return this.prepareOutputData(items); + return this.prepareOutputData(items); + } catch (error) { + if (this.continueOnFail()) { + return this.prepareOutputData([{json:{ error: error.message }}]); + } + throw error; + } } else if (operation === 'clear') { // ---------------------------------- // clear // ---------------------------------- + try { + await sheet.clearData(sheet.encodeRange(range)); - await sheet.clearData(sheet.encodeRange(range)); - - const items = this.getInputData(); - return this.prepareOutputData(items); + const items = this.getInputData(); + return this.prepareOutputData(items); + } catch (error) { + if (this.continueOnFail()) { + return this.prepareOutputData([{json:{ error: error.message }}]); + } + throw error; + } } else if (operation === 'create') { const returnData: IDataObject[] = []; let responseData; for (let i = 0; i < this.getInputData().length; i++) { - const spreadsheetId = this.getNodeParameter('sheetId', i) as string; - const options = this.getNodeParameter('options', i, {}) as IDataObject; - const simple = this.getNodeParameter('simple', 0) as boolean; - const properties = { ...options }; + try { + const spreadsheetId = this.getNodeParameter('sheetId', i) as string; + const options = this.getNodeParameter('options', i, {}) as IDataObject; + const simple = this.getNodeParameter('simple', 0) as boolean; + const properties = { ...options }; - if (options.tabColor) { - const { red, green, blue } = hexToRgb(options.tabColor as string)!; - properties.tabColor = { red: red / 255, green: green / 255, blue: blue / 255 }; + if (options.tabColor) { + const { red, green, blue } = hexToRgb(options.tabColor as string)!; + properties.tabColor = { red: red / 255, green: green / 255, blue: blue / 255 }; + } + + const requests = [{ + addSheet: { + properties, + }, + }]; + + responseData = await googleApiRequest.call(this, 'POST', `/v4/spreadsheets/${spreadsheetId}:batchUpdate`, { requests }); + + if (simple === true) { + Object.assign(responseData, responseData.replies[0].addSheet.properties); + delete responseData.replies; + } + returnData.push(responseData); + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } - - const requests = [{ - addSheet: { - properties, - }, - }]; - - responseData = await googleApiRequest.call(this, 'POST', `/v4/spreadsheets/${spreadsheetId}:batchUpdate`, { requests }); - - if (simple === true) { - Object.assign(responseData, responseData.replies[0].addSheet.properties); - delete responseData.replies; - } - returnData.push(responseData); } return [this.helpers.returnJsonArray(returnData)]; @@ -1096,119 +1117,145 @@ export class GoogleSheets implements INodeType { // ---------------------------------- // delete // ---------------------------------- + try { + const requests: IDataObject[] = []; - const requests: IDataObject[] = []; + const toDelete = this.getNodeParameter('toDelete', 0) as IToDelete; - const toDelete = this.getNodeParameter('toDelete', 0) as IToDelete; + const deletePropertyToDimensions: IDataObject = { + 'columns': 'COLUMNS', + 'rows': 'ROWS', + }; - const deletePropertyToDimensions: IDataObject = { - 'columns': 'COLUMNS', - 'rows': 'ROWS', - }; - - for (const propertyName of Object.keys(deletePropertyToDimensions)) { - if (toDelete[propertyName] !== undefined) { - toDelete[propertyName]!.forEach(range => { - requests.push({ - deleteDimension: { - range: { - sheetId: range.sheetId, - dimension: deletePropertyToDimensions[propertyName] as string, - startIndex: range.startIndex, - endIndex: parseInt(range.startIndex.toString(), 10) + parseInt(range.amount.toString(), 10), + for (const propertyName of Object.keys(deletePropertyToDimensions)) { + if (toDelete[propertyName] !== undefined) { + toDelete[propertyName]!.forEach(range => { + requests.push({ + deleteDimension: { + range: { + sheetId: range.sheetId, + dimension: deletePropertyToDimensions[propertyName] as string, + startIndex: range.startIndex, + endIndex: parseInt(range.startIndex.toString(), 10) + parseInt(range.amount.toString(), 10), + }, }, - }, + }); }); - }); + } } + + const data = await sheet.spreadsheetBatchUpdate(requests); + + const items = this.getInputData(); + return this.prepareOutputData(items); + } catch (error) { + if (this.continueOnFail()) { + return this.prepareOutputData([{json:{ error: error.message }}]); + } + throw error; } - - const data = await sheet.spreadsheetBatchUpdate(requests); - - const items = this.getInputData(); - return this.prepareOutputData(items); } else if (operation === 'lookup') { // ---------------------------------- // lookup // ---------------------------------- + try { + const sheetData = await sheet.getData(sheet.encodeRange(range), valueRenderMode); - const sheetData = await sheet.getData(sheet.encodeRange(range), valueRenderMode); + if (sheetData === undefined) { + return []; + } - if (sheetData === undefined) { - return []; + const dataStartRow = parseInt(this.getNodeParameter('dataStartRow', 0) as string, 10); + const keyRow = parseInt(this.getNodeParameter('keyRow', 0) as string, 10); + + const items = this.getInputData(); + + const lookupValues: ILookupValues[] = []; + for (let i = 0; i < items.length; i++) { + lookupValues.push({ + lookupColumn: this.getNodeParameter('lookupColumn', i) as string, + lookupValue: this.getNodeParameter('lookupValue', i) as string, + }); + } + + let returnData = await sheet.lookupValues(sheetData, keyRow, dataStartRow, lookupValues, options.returnAllMatches as boolean | undefined); + + if (returnData.length === 0 && options.continue && options.returnAllMatches) { + returnData = [{}]; + } else if (returnData.length === 1 && Object.keys(returnData[0]).length === 0 && !options.continue && !options.returnAllMatches) { + returnData = []; + } + + return [this.helpers.returnJsonArray(returnData)]; + } catch (error) { + if (this.continueOnFail()) { + return [this.helpers.returnJsonArray({ error: error.message })]; + } + throw error; } - - const dataStartRow = parseInt(this.getNodeParameter('dataStartRow', 0) as string, 10); - const keyRow = parseInt(this.getNodeParameter('keyRow', 0) as string, 10); - - const items = this.getInputData(); - - const lookupValues: ILookupValues[] = []; - for (let i = 0; i < items.length; i++) { - lookupValues.push({ - lookupColumn: this.getNodeParameter('lookupColumn', i) as string, - lookupValue: this.getNodeParameter('lookupValue', i) as string, - }); - } - - let returnData = await sheet.lookupValues(sheetData, keyRow, dataStartRow, lookupValues, options.returnAllMatches as boolean | undefined); - - if (returnData.length === 0 && options.continue && options.returnAllMatches) { - returnData = [{}]; - } else if (returnData.length === 1 && Object.keys(returnData[0]).length === 0 && !options.continue && !options.returnAllMatches) { - returnData = []; - } - - return [this.helpers.returnJsonArray(returnData)]; } else if (operation === 'read') { // ---------------------------------- // read // ---------------------------------- + try { + const rawData = this.getNodeParameter('rawData', 0) as boolean; - const rawData = this.getNodeParameter('rawData', 0) as boolean; + const sheetData = await sheet.getData(sheet.encodeRange(range), valueRenderMode); - const sheetData = await sheet.getData(sheet.encodeRange(range), valueRenderMode); + let returnData: IDataObject[]; + if (!sheetData) { + returnData = []; + } else if (rawData === true) { + const dataProperty = this.getNodeParameter('dataProperty', 0) as string; + returnData = [ + { + [dataProperty]: sheetData, + }, + ]; + } else { + const dataStartRow = parseInt(this.getNodeParameter('dataStartRow', 0) as string, 10); + const keyRow = parseInt(this.getNodeParameter('keyRow', 0) as string, 10); - let returnData: IDataObject[]; - if (!sheetData) { - returnData = []; - } else if (rawData === true) { - const dataProperty = this.getNodeParameter('dataProperty', 0) as string; - returnData = [ - { - [dataProperty]: sheetData, - }, - ]; - } else { - const dataStartRow = parseInt(this.getNodeParameter('dataStartRow', 0) as string, 10); - const keyRow = parseInt(this.getNodeParameter('keyRow', 0) as string, 10); + returnData = sheet.structureArrayDataByColumn(sheetData, keyRow, dataStartRow); + } - returnData = sheet.structureArrayDataByColumn(sheetData, keyRow, dataStartRow); + if (returnData.length === 0 && options.continue) { + returnData = [{}]; + } + + return [this.helpers.returnJsonArray(returnData)]; + } catch (error) { + if (this.continueOnFail()) { + return [this.helpers.returnJsonArray({ error: error.message })]; + } + throw error; } - if (returnData.length === 0 && options.continue) { - returnData = [{}]; - } - - return [this.helpers.returnJsonArray(returnData)]; - } else if (operation === 'remove') { const returnData: IDataObject[] = []; let responseData; for (let i = 0; i < this.getInputData().length; i++) { - const sheetId = this.getNodeParameter('id', i) as string; - const spreadsheetId = this.getNodeParameter('sheetId', i) as string; + try { + const sheetId = this.getNodeParameter('id', i) as string; + const spreadsheetId = this.getNodeParameter('sheetId', i) as string; - const requests = [{ - deleteSheet: { - sheetId, - }, - }]; + const requests = [{ + deleteSheet: { + sheetId, + }, + }]; - responseData = await googleApiRequest.call(this, 'POST', `/v4/spreadsheets/${spreadsheetId}:batchUpdate`, { requests }); - delete responseData.replies; - returnData.push(responseData); + responseData = await googleApiRequest.call(this, 'POST', `/v4/spreadsheets/${spreadsheetId}:batchUpdate`, { requests }); + delete responseData.replies; + returnData.push(responseData); + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; + } } return [this.helpers.returnJsonArray(returnData)]; @@ -1216,40 +1263,46 @@ export class GoogleSheets implements INodeType { // ---------------------------------- // update // ---------------------------------- + try { + const rawData = this.getNodeParameter('rawData', 0) as boolean; - const rawData = this.getNodeParameter('rawData', 0) as boolean; + const items = this.getInputData(); - const items = this.getInputData(); + if (rawData === true) { + const dataProperty = this.getNodeParameter('dataProperty', 0) as string; - if (rawData === true) { - const dataProperty = this.getNodeParameter('dataProperty', 0) as string; + const updateData: ISheetUpdateData[] = []; + for (let i = 0; i < items.length; i++) { + updateData.push({ + range, + values: items[i].json[dataProperty] as string[][], + }); + } - const updateData: ISheetUpdateData[] = []; - for (let i = 0; i < items.length; i++) { - updateData.push({ - range, - values: items[i].json[dataProperty] as string[][], + const data = await sheet.batchUpdate(updateData, valueInputMode); + } else { + const keyName = this.getNodeParameter('key', 0) as string; + const keyRow = parseInt(this.getNodeParameter('keyRow', 0) as string, 10); + const dataStartRow = parseInt(this.getNodeParameter('dataStartRow', 0) as string, 10); + + const setData: IDataObject[] = []; + items.forEach((item) => { + setData.push(item.json); }); + + const data = await sheet.updateSheetData(setData, keyName, range, keyRow, dataStartRow, valueInputMode, valueRenderMode); } + // TODO: Should add this data somewhere + // TODO: Should have something like add metadata which does not get passed through - const data = await sheet.batchUpdate(updateData, valueInputMode); - } else { - const keyName = this.getNodeParameter('key', 0) as string; - const keyRow = parseInt(this.getNodeParameter('keyRow', 0) as string, 10); - const dataStartRow = parseInt(this.getNodeParameter('dataStartRow', 0) as string, 10); - const setData: IDataObject[] = []; - items.forEach((item) => { - setData.push(item.json); - }); - - const data = await sheet.updateSheetData(setData, keyName, range, keyRow, dataStartRow, valueInputMode, valueRenderMode); + return this.prepareOutputData(items); + } catch (error) { + if (this.continueOnFail()) { + return this.prepareOutputData([{json:{ error: error.message }}]); + } + throw error; } - // TODO: Should add this data somewhere - // TODO: Should have something like add metadata which does not get passed through - - - return this.prepareOutputData(items); } } @@ -1267,39 +1320,46 @@ export class GoogleSheets implements INodeType { // https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/create for (let i = 0; i < this.getInputData().length; i++) { + try { + const title = this.getNodeParameter('title', i) as string; + const sheetsUi = this.getNodeParameter('sheetsUi', i, {}) as IDataObject; - const title = this.getNodeParameter('title', i) as string; - const sheetsUi = this.getNodeParameter('sheetsUi', i, {}) as IDataObject; + const body = { + properties: { + title, + autoRecalc: undefined as undefined | string, + locale: undefined as undefined | string, + }, + sheets: [] as IDataObject[], + }; - const body = { - properties: { - title, - autoRecalc: undefined as undefined | string, - locale: undefined as undefined | string, - }, - sheets: [] as IDataObject[], - }; + const options = this.getNodeParameter('options', i, {}) as IDataObject; - const options = this.getNodeParameter('options', i, {}) as IDataObject; - - if (Object.keys(sheetsUi).length) { - const data = []; - const sheets = sheetsUi.sheetValues as IDataObject[]; - for (const sheet of sheets) { - const properties = sheet.propertiesUi as IDataObject; - if (properties) { - data.push({ properties }); + if (Object.keys(sheetsUi).length) { + const data = []; + const sheets = sheetsUi.sheetValues as IDataObject[]; + for (const sheet of sheets) { + const properties = sheet.propertiesUi as IDataObject; + if (properties) { + data.push({ properties }); + } } + body.sheets = data; } - body.sheets = data; + + body.properties!.autoRecalc = options.autoRecalc ? (options.autoRecalc as string) : undefined; + body.properties!.locale = options.locale ? (options.locale as string) : undefined; + + responseData = await googleApiRequest.call(this, 'POST', `/v4/spreadsheets`, body); + + returnData.push(responseData); + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } - - body.properties!.autoRecalc = options.autoRecalc ? (options.autoRecalc as string) : undefined; - body.properties!.locale = options.locale ? (options.locale as string) : undefined; - - responseData = await googleApiRequest.call(this, 'POST', `/v4/spreadsheets`, body); - - returnData.push(responseData); } } diff --git a/packages/nodes-base/nodes/Google/Slides/GoogleSlides.node.ts b/packages/nodes-base/nodes/Google/Slides/GoogleSlides.node.ts index d2de0bf6f8..15e12367e5 100644 --- a/packages/nodes-base/nodes/Google/Slides/GoogleSlides.node.ts +++ b/packages/nodes-base/nodes/Google/Slides/GoogleSlides.node.ts @@ -416,136 +416,146 @@ export class GoogleSlides implements INodeType { for (let i = 0; i < items.length; i++) { - if (resource === 'page') { + try { - // ********************************************************************* - // page - // ********************************************************************* + if (resource === 'page') { - if (operation === 'get') { + // ********************************************************************* + // page + // ********************************************************************* - // ---------------------------------- - // page: get - // ---------------------------------- + if (operation === 'get') { - const presentationId = this.getNodeParameter('presentationId', i) as string; - const pageObjectId = this.getNodeParameter('pageObjectId', i) as string; - responseData = await googleApiRequest.call(this, 'GET', `/presentations/${presentationId}/pages/${pageObjectId}`); - returnData.push({ json: responseData }); + // ---------------------------------- + // page: get + // ---------------------------------- - } else if (operation === 'getThumbnail') { - - // ---------------------------------- - // page: getThumbnail - // ---------------------------------- - - const presentationId = this.getNodeParameter('presentationId', i) as string; - const pageObjectId = this.getNodeParameter('pageObjectId', i) as string; - responseData = await googleApiRequest.call(this, 'GET', `/presentations/${presentationId}/pages/${pageObjectId}/thumbnail`); - - const download = this.getNodeParameter('download', 0) as boolean; - if (download === true) { - const binaryProperty = this.getNodeParameter('binaryProperty', i) as string; - - const data = await this.helpers.request({ - uri: responseData.contentUrl, - method: 'GET', - json: false, - encoding: null, - }); - - const fileName = pageObjectId + '.png'; - const binaryData = await this.helpers.prepareBinaryData(data, fileName || fileName); - returnData.push({ - json: responseData, - binary: { - [binaryProperty]: binaryData, - }, - }); - } else { + const presentationId = this.getNodeParameter('presentationId', i) as string; + const pageObjectId = this.getNodeParameter('pageObjectId', i) as string; + responseData = await googleApiRequest.call(this, 'GET', `/presentations/${presentationId}/pages/${pageObjectId}`); returnData.push({ json: responseData }); - } - } - } else if (resource === 'presentation') { + } else if (operation === 'getThumbnail') { - // ********************************************************************* - // presentation - // ********************************************************************* + // ---------------------------------- + // page: getThumbnail + // ---------------------------------- - if (operation === 'create') { + const presentationId = this.getNodeParameter('presentationId', i) as string; + const pageObjectId = this.getNodeParameter('pageObjectId', i) as string; + responseData = await googleApiRequest.call(this, 'GET', `/presentations/${presentationId}/pages/${pageObjectId}/thumbnail`); - // ---------------------------------- - // presentation: create - // ---------------------------------- + const download = this.getNodeParameter('download', 0) as boolean; + if (download === true) { + const binaryProperty = this.getNodeParameter('binaryProperty', i) as string; - const body = { - title: this.getNodeParameter('title', i) as string, - }; + const data = await this.helpers.request({ + uri: responseData.contentUrl, + method: 'GET', + json: false, + encoding: null, + }); - responseData = await googleApiRequest.call(this, 'POST', '/presentations', body); - returnData.push({ json: responseData }); - - } else if (operation === 'get') { - - // ---------------------------------- - // presentation: get - // ---------------------------------- - - const presentationId = this.getNodeParameter('presentationId', i) as string; - responseData = await googleApiRequest.call(this, 'GET', `/presentations/${presentationId}`); - returnData.push({ json: responseData }); - - } else if (operation === 'getSlides') { - - // ---------------------------------- - // presentation: getSlides - // ---------------------------------- - const returnAll = this.getNodeParameter('returnAll', 0) as boolean; - const presentationId = this.getNodeParameter('presentationId', i) as string; - responseData = await googleApiRequest.call(this, 'GET', `/presentations/${presentationId}`, {}, { fields: 'slides' }); - responseData = responseData.slides; - if (returnAll === false) { - const limit = this.getNodeParameter('limit', i) as number; - responseData = responseData.slice(0, limit); - } - returnData.push(...this.helpers.returnJsonArray(responseData)); - - } else if (operation === 'replaceText') { - - // ---------------------------------- - // presentation: replaceText - // ---------------------------------- - const presentationId = this.getNodeParameter('presentationId', i) as string; - const texts = this.getNodeParameter('textUi.textValues', i, []) as IDataObject[]; - const options = this.getNodeParameter('options', i) as IDataObject; - const requests = texts.map((text => { - return { - replaceAllText: { - replaceText: text.replaceText, - pageObjectIds: text.pageObjectIds || [], - containsText: { - text: text.text, - matchCase: text.matchCase, + const fileName = pageObjectId + '.png'; + const binaryData = await this.helpers.prepareBinaryData(data, fileName || fileName); + returnData.push({ + json: responseData, + binary: { + [binaryProperty]: binaryData, }, - }, - }; - })); - - const body: IDataObject = { - requests, - }; - - if (options.revisionId) { - body['writeControl'] = { - requiredRevisionId: options.revisionId as string, - }; + }); + } else { + returnData.push({ json: responseData }); + } } - responseData = await googleApiRequest.call(this, 'POST', `/presentations/${presentationId}:batchUpdate`, { requests }); - returnData.push({ json: responseData }); + } else if (resource === 'presentation') { + // ********************************************************************* + // presentation + // ********************************************************************* + + if (operation === 'create') { + + // ---------------------------------- + // presentation: create + // ---------------------------------- + + const body = { + title: this.getNodeParameter('title', i) as string, + }; + + responseData = await googleApiRequest.call(this, 'POST', '/presentations', body); + returnData.push({ json: responseData }); + + } else if (operation === 'get') { + + // ---------------------------------- + // presentation: get + // ---------------------------------- + + const presentationId = this.getNodeParameter('presentationId', i) as string; + responseData = await googleApiRequest.call(this, 'GET', `/presentations/${presentationId}`); + returnData.push({ json: responseData }); + + } else if (operation === 'getSlides') { + + // ---------------------------------- + // presentation: getSlides + // ---------------------------------- + const returnAll = this.getNodeParameter('returnAll', 0) as boolean; + const presentationId = this.getNodeParameter('presentationId', i) as string; + responseData = await googleApiRequest.call(this, 'GET', `/presentations/${presentationId}`, {}, { fields: 'slides' }); + responseData = responseData.slides; + if (returnAll === false) { + const limit = this.getNodeParameter('limit', i) as number; + responseData = responseData.slice(0, limit); + } + returnData.push(...this.helpers.returnJsonArray(responseData)); + + } else if (operation === 'replaceText') { + + // ---------------------------------- + // presentation: replaceText + // ---------------------------------- + const presentationId = this.getNodeParameter('presentationId', i) as string; + const texts = this.getNodeParameter('textUi.textValues', i, []) as IDataObject[]; + const options = this.getNodeParameter('options', i) as IDataObject; + const requests = texts.map((text => { + return { + replaceAllText: { + replaceText: text.replaceText, + pageObjectIds: text.pageObjectIds || [], + containsText: { + text: text.text, + matchCase: text.matchCase, + }, + }, + }; + })); + + const body: IDataObject = { + requests, + }; + + if (options.revisionId) { + body['writeControl'] = { + requiredRevisionId: options.revisionId as string, + }; + } + + responseData = await googleApiRequest.call(this, 'POST', `/presentations/${presentationId}:batchUpdate`, { requests }); + returnData.push({ json: responseData }); + + } } + + } catch (error) { + if (this.continueOnFail()) { + returnData.push({json:{ error: error.message }}); + continue; + } + throw error; } } diff --git a/packages/nodes-base/nodes/Google/Task/GoogleTasks.node.ts b/packages/nodes-base/nodes/Google/Task/GoogleTasks.node.ts index 29c945d9db..f956251911 100644 --- a/packages/nodes-base/nodes/Google/Task/GoogleTasks.node.ts +++ b/packages/nodes-base/nodes/Google/Task/GoogleTasks.node.ts @@ -97,181 +97,189 @@ export class GoogleTasks implements INodeType { const operation = this.getNodeParameter('operation', 0) as string; let body: IDataObject = {}; for (let i = 0; i < length; i++) { - if (resource === 'task') { - if (operation === 'create') { - body = {}; - //https://developers.google.com/tasks/v1/reference/tasks/insert - const taskId = this.getNodeParameter('task', i) as string; - body.title = this.getNodeParameter('title', i) as string; - const additionalFields = this.getNodeParameter( - 'additionalFields', - i, - ) as IDataObject; + try { + if (resource === 'task') { + if (operation === 'create') { + body = {}; + //https://developers.google.com/tasks/v1/reference/tasks/insert + const taskId = this.getNodeParameter('task', i) as string; + body.title = this.getNodeParameter('title', i) as string; + const additionalFields = this.getNodeParameter( + 'additionalFields', + i, + ) as IDataObject; - if (additionalFields.parent) { - qs.parent = additionalFields.parent as string; - } - if (additionalFields.previous) { - qs.previous = additionalFields.previous as string; - } + if (additionalFields.parent) { + qs.parent = additionalFields.parent as string; + } + if (additionalFields.previous) { + qs.previous = additionalFields.previous as string; + } - if (additionalFields.status) { - body.status = additionalFields.status as string; - } + if (additionalFields.status) { + body.status = additionalFields.status as string; + } - if (additionalFields.notes) { - body.notes = additionalFields.notes as string; - } - if (additionalFields.dueDate) { - body.dueDate = additionalFields.dueDate as string; - } + if (additionalFields.notes) { + body.notes = additionalFields.notes as string; + } + if (additionalFields.dueDate) { + body.dueDate = additionalFields.dueDate as string; + } - if (additionalFields.completed) { - body.completed = additionalFields.completed as string; - } + if (additionalFields.completed) { + body.completed = additionalFields.completed as string; + } - if (additionalFields.deleted) { - body.deleted = additionalFields.deleted as boolean; - } + if (additionalFields.deleted) { + body.deleted = additionalFields.deleted as boolean; + } - responseData = await googleApiRequest.call( - this, - 'POST', - `/tasks/v1/lists/${taskId}/tasks`, - body, - qs, - ); - } - if (operation === 'delete') { - //https://developers.google.com/tasks/v1/reference/tasks/delete - const taskListId = this.getNodeParameter('task', i) as string; - const taskId = this.getNodeParameter('taskId', i) as string; - - responseData = await googleApiRequest.call( - this, - 'DELETE', - `/tasks/v1/lists/${taskListId}/tasks/${taskId}`, - {}, - ); - responseData = { success: true }; - } - if (operation === 'get') { - //https://developers.google.com/tasks/v1/reference/tasks/get - const taskListId = this.getNodeParameter('task', i) as string; - const taskId = this.getNodeParameter('taskId', i) as string; - responseData = await googleApiRequest.call( - this, - 'GET', - `/tasks/v1/lists/${taskListId}/tasks/${taskId}`, - {}, - qs, - ); - } - if (operation === 'getAll') { - //https://developers.google.com/tasks/v1/reference/tasks/list - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - const taskListId = this.getNodeParameter('task', i) as string; - const options = this.getNodeParameter( - 'additionalFields', - i, - ) as IDataObject; - if (options.completedMax) { - qs.completedMax = options.completedMax as string; - } - if (options.completedMin) { - qs.completedMin = options.completedMin as string; - } - if (options.dueMin) { - qs.dueMin = options.dueMin as string; - } - if (options.dueMax) { - qs.dueMax = options.dueMax as string; - } - if (options.showCompleted) { - qs.showCompleted = options.showCompleted as boolean; - } - if (options.showDeleted) { - qs.showDeleted = options.showDeleted as boolean; - } - if (options.showHidden) { - qs.showHidden = options.showHidden as boolean; - } - if (options.updatedMin) { - qs.updatedMin = options.updatedMin as string; - } - - if (returnAll) { - responseData = await googleApiRequestAllItems.call( + responseData = await googleApiRequest.call( this, - 'items', - 'GET', - `/tasks/v1/lists/${taskListId}/tasks`, - {}, + 'POST', + `/tasks/v1/lists/${taskId}/tasks`, + body, qs, ); - } else { - qs.maxResults = this.getNodeParameter('limit', i) as number; + } + if (operation === 'delete') { + //https://developers.google.com/tasks/v1/reference/tasks/delete + const taskListId = this.getNodeParameter('task', i) as string; + const taskId = this.getNodeParameter('taskId', i) as string; + + responseData = await googleApiRequest.call( + this, + 'DELETE', + `/tasks/v1/lists/${taskListId}/tasks/${taskId}`, + {}, + ); + responseData = { success: true }; + } + if (operation === 'get') { + //https://developers.google.com/tasks/v1/reference/tasks/get + const taskListId = this.getNodeParameter('task', i) as string; + const taskId = this.getNodeParameter('taskId', i) as string; responseData = await googleApiRequest.call( this, 'GET', - `/tasks/v1/lists/${taskListId}/tasks`, + `/tasks/v1/lists/${taskListId}/tasks/${taskId}`, {}, qs, ); - responseData = responseData.items; + } + if (operation === 'getAll') { + //https://developers.google.com/tasks/v1/reference/tasks/list + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + const taskListId = this.getNodeParameter('task', i) as string; + const options = this.getNodeParameter( + 'additionalFields', + i, + ) as IDataObject; + if (options.completedMax) { + qs.completedMax = options.completedMax as string; + } + if (options.completedMin) { + qs.completedMin = options.completedMin as string; + } + if (options.dueMin) { + qs.dueMin = options.dueMin as string; + } + if (options.dueMax) { + qs.dueMax = options.dueMax as string; + } + if (options.showCompleted) { + qs.showCompleted = options.showCompleted as boolean; + } + if (options.showDeleted) { + qs.showDeleted = options.showDeleted as boolean; + } + if (options.showHidden) { + qs.showHidden = options.showHidden as boolean; + } + if (options.updatedMin) { + qs.updatedMin = options.updatedMin as string; + } + + if (returnAll) { + responseData = await googleApiRequestAllItems.call( + this, + 'items', + 'GET', + `/tasks/v1/lists/${taskListId}/tasks`, + {}, + qs, + ); + } else { + qs.maxResults = this.getNodeParameter('limit', i) as number; + responseData = await googleApiRequest.call( + this, + 'GET', + `/tasks/v1/lists/${taskListId}/tasks`, + {}, + qs, + ); + responseData = responseData.items; + } + } + if (operation === 'update') { + body = {}; + //https://developers.google.com/tasks/v1/reference/tasks/patch + const taskListId = this.getNodeParameter('task', i) as string; + const taskId = this.getNodeParameter('taskId', i) as string; + const updateFields = this.getNodeParameter( + 'updateFields', + i, + ) as IDataObject; + + if (updateFields.previous) { + qs.previous = updateFields.previous as string; + } + + if (updateFields.status) { + body.status = updateFields.status as string; + } + + if (updateFields.notes) { + body.notes = updateFields.notes as string; + } + + if (updateFields.title) { + body.title = updateFields.title as string; + } + + if (updateFields.dueDate) { + body.dueDate = updateFields.dueDate as string; + } + + if (updateFields.completed) { + body.completed = updateFields.completed as string; + } + + if (updateFields.deleted) { + body.deleted = updateFields.deleted as boolean; + } + + responseData = await googleApiRequest.call( + this, + 'PATCH', + `/tasks/v1/lists/${taskListId}/tasks/${taskId}`, + body, + qs, + ); } } - if (operation === 'update') { - body = {}; - //https://developers.google.com/tasks/v1/reference/tasks/patch - const taskListId = this.getNodeParameter('task', i) as string; - const taskId = this.getNodeParameter('taskId', i) as string; - const updateFields = this.getNodeParameter( - 'updateFields', - i, - ) as IDataObject; - - if (updateFields.previous) { - qs.previous = updateFields.previous as string; - } - - if (updateFields.status) { - body.status = updateFields.status as string; - } - - if (updateFields.notes) { - body.notes = updateFields.notes as string; - } - - if (updateFields.title) { - body.title = updateFields.title as string; - } - - if (updateFields.dueDate) { - body.dueDate = updateFields.dueDate as string; - } - - if (updateFields.completed) { - body.completed = updateFields.completed as string; - } - - if (updateFields.deleted) { - body.deleted = updateFields.deleted as boolean; - } - - responseData = await googleApiRequest.call( - this, - 'PATCH', - `/tasks/v1/lists/${taskListId}/tasks/${taskId}`, - body, - qs, - ); + if (Array.isArray(responseData)) { + returnData.push.apply(returnData, responseData as IDataObject[]); + } else if (responseData !== undefined) { + returnData.push(responseData as IDataObject); } - } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else if (responseData !== undefined) { - returnData.push(responseData as IDataObject); + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } } return [this.helpers.returnJsonArray(returnData)]; diff --git a/packages/nodes-base/nodes/Google/YouTube/YouTube.node.ts b/packages/nodes-base/nodes/Google/YouTube/YouTube.node.ts index 016634aaa5..3e8c580c95 100644 --- a/packages/nodes-base/nodes/Google/YouTube/YouTube.node.ts +++ b/packages/nodes-base/nodes/Google/YouTube/YouTube.node.ts @@ -221,82 +221,31 @@ export class YouTube implements INodeType { 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 === 'channel') { - if (operation === 'get') { - //https://developers.google.com/youtube/v3/docs/channels/list - let part = this.getNodeParameter('part', i) as string[]; - const channelId = this.getNodeParameter('channelId', i) as string; + try { + if (resource === 'channel') { + if (operation === 'get') { + //https://developers.google.com/youtube/v3/docs/channels/list + let part = this.getNodeParameter('part', i) as string[]; + const channelId = this.getNodeParameter('channelId', i) as string; - if (part.includes('*')) { - part = [ - 'brandingSettings', - 'contentDetails', - 'contentOwnerDetails', - 'id', - 'localizations', - 'snippet', - 'statistics', - 'status', - 'topicDetails', - ]; - } + if (part.includes('*')) { + part = [ + 'brandingSettings', + 'contentDetails', + 'contentOwnerDetails', + 'id', + 'localizations', + 'snippet', + 'statistics', + 'status', + 'topicDetails', + ]; + } - qs.part = part.join(','); + qs.part = part.join(','); - qs.id = channelId; + qs.id = channelId; - responseData = await googleApiRequest.call( - this, - 'GET', - `/youtube/v3/channels`, - {}, - qs, - ); - - responseData = responseData.items; - } - //https://developers.google.com/youtube/v3/docs/channels/list - if (operation === 'getAll') { - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - let part = this.getNodeParameter('part', i) as string[]; - const options = this.getNodeParameter('options', i) as IDataObject; - const filters = this.getNodeParameter('filters', i) as IDataObject; - - if (part.includes('*')) { - part = [ - 'brandingSettings', - 'contentDetails', - 'contentOwnerDetails', - 'id', - 'localizations', - 'snippet', - 'statistics', - 'status', - 'topicDetails', - ]; - } - - qs.part = part.join(','); - - Object.assign(qs, options, filters); - - qs.mine = true; - - if (qs.categoryId || qs.forUsername || qs.id || qs.managedByMe) { - delete qs.mine; - } - - if (returnAll) { - responseData = await googleApiRequestAllItems.call( - this, - 'items', - 'GET', - `/youtube/v3/channels`, - {}, - qs, - ); - } else { - qs.maxResults = this.getNodeParameter('limit', i) as number; responseData = await googleApiRequest.call( this, 'GET', @@ -304,232 +253,235 @@ export class YouTube implements INodeType { {}, qs, ); + responseData = responseData.items; } - } - //https://developers.google.com/youtube/v3/docs/channels/update - if (operation === 'update') { - const channelId = this.getNodeParameter('channelId', i) as string; - const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + //https://developers.google.com/youtube/v3/docs/channels/list + if (operation === 'getAll') { + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + let part = this.getNodeParameter('part', i) as string[]; + const options = this.getNodeParameter('options', i) as IDataObject; + const filters = this.getNodeParameter('filters', i) as IDataObject; - const body: IDataObject = { - id: channelId, - brandingSettings: { - channel: {}, - image: {}, - }, - }; - - qs.part = 'brandingSettings'; - - if (updateFields.onBehalfOfContentOwner) { - qs.onBehalfOfContentOwner = updateFields.onBehalfOfContentOwner as string; - } - - if (updateFields.brandingSettingsUi) { - const channelSettingsValues = (updateFields.brandingSettingsUi as IDataObject).channelSettingsValues as IDataObject | undefined; - const channelSettings: IDataObject = {}; - if (channelSettingsValues?.channel) { - const channelSettingsOptions = channelSettingsValues.channel as IDataObject; - if (channelSettingsOptions.country) { - channelSettings.country = channelSettingsOptions.country; - } - if (channelSettingsOptions.description) { - channelSettings.description = channelSettingsOptions.description; - } - if (channelSettingsOptions.defaultLanguage) { - channelSettings.defaultLanguage = channelSettingsOptions.defaultLanguage; - } - if (channelSettingsOptions.defaultTab) { - channelSettings.defaultTab = channelSettingsOptions.defaultTab; - } - if (channelSettingsOptions.featuredChannelsTitle) { - channelSettings.featuredChannelsTitle = channelSettingsOptions.featuredChannelsTitle; - } - if (channelSettingsOptions.featuredChannelsUrls) { - channelSettings.featuredChannelsUrls = channelSettingsOptions.featuredChannelsUrls; - } - if (channelSettingsOptions.keywords) { - channelSettings.keywords = channelSettingsOptions.keywords; - } - if (channelSettingsOptions.moderateComments) { - channelSettings.moderateComments = channelSettingsOptions.moderateComments as boolean; - } - if (channelSettingsOptions.profileColor) { - channelSettings.profileColor = channelSettingsOptions.profileColor as string; - } - if (channelSettingsOptions.profileColor) { - channelSettings.profileColor = channelSettingsOptions.profileColor as string; - } - if (channelSettingsOptions.showRelatedChannels) { - channelSettings.showRelatedChannels = channelSettingsOptions.showRelatedChannels as boolean; - } - if (channelSettingsOptions.showBrowseView) { - channelSettings.showBrowseView = channelSettingsOptions.showBrowseView as boolean; - } - if (channelSettingsOptions.trackingAnalyticsAccountId) { - channelSettings.trackingAnalyticsAccountId = channelSettingsOptions.trackingAnalyticsAccountId as string; - } - if (channelSettingsOptions.unsubscribedTrailer) { - channelSettings.unsubscribedTrailer = channelSettingsOptions.unsubscribedTrailer as string; - } + if (part.includes('*')) { + part = [ + 'brandingSettings', + 'contentDetails', + 'contentOwnerDetails', + 'id', + 'localizations', + 'snippet', + 'statistics', + 'status', + 'topicDetails', + ]; } - const imageSettingsValues = (updateFields.brandingSettingsUi as IDataObject).imageSettingsValues as IDataObject | undefined; - const imageSettings: IDataObject = {}; - if (imageSettingsValues?.image) { - const imageSettingsOptions = imageSettings.image as IDataObject; - if (imageSettingsOptions.bannerExternalUrl) { - imageSettings.bannerExternalUrl = imageSettingsOptions.bannerExternalUrl as string; - } - if (imageSettingsOptions.trackingImageUrl) { - imageSettings.trackingImageUrl = imageSettingsOptions.trackingImageUrl as string; - } - if (imageSettingsOptions.watchIconImageUrl) { - imageSettings.watchIconImageUrl = imageSettingsOptions.watchIconImageUrl as string; - } + qs.part = part.join(','); + + Object.assign(qs, options, filters); + + qs.mine = true; + + if (qs.categoryId || qs.forUsername || qs.id || qs.managedByMe) { + delete qs.mine; } - //@ts-ignore - body.brandingSettings.channel = channelSettings; - //@ts-ignore - body.brandingSettings.image = imageSettings; + if (returnAll) { + responseData = await googleApiRequestAllItems.call( + this, + 'items', + 'GET', + `/youtube/v3/channels`, + {}, + qs, + ); + } else { + qs.maxResults = this.getNodeParameter('limit', i) as number; + responseData = await googleApiRequest.call( + this, + 'GET', + `/youtube/v3/channels`, + {}, + qs, + ); + responseData = responseData.items; + } } + //https://developers.google.com/youtube/v3/docs/channels/update + if (operation === 'update') { + const channelId = this.getNodeParameter('channelId', i) as string; + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; - responseData = await googleApiRequest.call( - this, - 'PUT', - '/youtube/v3/channels', - body, - qs, - ); - } - //https://developers.google.com/youtube/v3/docs/channelBanners/insert - if (operation === 'uploadBanner') { - const channelId = this.getNodeParameter('channelId', i) as string; - const binaryProperty = this.getNodeParameter('binaryProperty', i) as string; - - let mimeType; - - // Is binary file to upload - const item = items[i]; - - if (item.binary === undefined) { - throw new NodeOperationError(this.getNode(), 'No binary data exists on item!'); - } - - if (item.binary[binaryProperty] === undefined) { - throw new NodeOperationError(this.getNode(), `No binary data property "${binaryProperty}" does not exists on item!`); - } - - if (item.binary[binaryProperty].mimeType) { - mimeType = item.binary[binaryProperty].mimeType; - } - - const body = Buffer.from(item.binary[binaryProperty].data, BINARY_ENCODING); - - const requestOptions = { - headers: { - 'Content-Type': mimeType, - }, - json: false, - }; - - const response = await googleApiRequest.call(this, 'POST', '/upload/youtube/v3/channelBanners/insert', body, qs, undefined, requestOptions); - - const { url } = JSON.parse(response); - - qs.part = 'brandingSettings'; - - responseData = await googleApiRequest.call( - this, - 'PUT', - `/youtube/v3/channels`, - { + const body: IDataObject = { id: channelId, brandingSettings: { - image: { - bannerExternalUrl: url, + channel: {}, + image: {}, + }, + }; + + qs.part = 'brandingSettings'; + + if (updateFields.onBehalfOfContentOwner) { + qs.onBehalfOfContentOwner = updateFields.onBehalfOfContentOwner as string; + } + + if (updateFields.brandingSettingsUi) { + const channelSettingsValues = (updateFields.brandingSettingsUi as IDataObject).channelSettingsValues as IDataObject | undefined; + const channelSettings: IDataObject = {}; + if (channelSettingsValues?.channel) { + const channelSettingsOptions = channelSettingsValues.channel as IDataObject; + if (channelSettingsOptions.country) { + channelSettings.country = channelSettingsOptions.country; + } + if (channelSettingsOptions.description) { + channelSettings.description = channelSettingsOptions.description; + } + if (channelSettingsOptions.defaultLanguage) { + channelSettings.defaultLanguage = channelSettingsOptions.defaultLanguage; + } + if (channelSettingsOptions.defaultTab) { + channelSettings.defaultTab = channelSettingsOptions.defaultTab; + } + if (channelSettingsOptions.featuredChannelsTitle) { + channelSettings.featuredChannelsTitle = channelSettingsOptions.featuredChannelsTitle; + } + if (channelSettingsOptions.featuredChannelsUrls) { + channelSettings.featuredChannelsUrls = channelSettingsOptions.featuredChannelsUrls; + } + if (channelSettingsOptions.keywords) { + channelSettings.keywords = channelSettingsOptions.keywords; + } + if (channelSettingsOptions.moderateComments) { + channelSettings.moderateComments = channelSettingsOptions.moderateComments as boolean; + } + if (channelSettingsOptions.profileColor) { + channelSettings.profileColor = channelSettingsOptions.profileColor as string; + } + if (channelSettingsOptions.profileColor) { + channelSettings.profileColor = channelSettingsOptions.profileColor as string; + } + if (channelSettingsOptions.showRelatedChannels) { + channelSettings.showRelatedChannels = channelSettingsOptions.showRelatedChannels as boolean; + } + if (channelSettingsOptions.showBrowseView) { + channelSettings.showBrowseView = channelSettingsOptions.showBrowseView as boolean; + } + if (channelSettingsOptions.trackingAnalyticsAccountId) { + channelSettings.trackingAnalyticsAccountId = channelSettingsOptions.trackingAnalyticsAccountId as string; + } + if (channelSettingsOptions.unsubscribedTrailer) { + channelSettings.unsubscribedTrailer = channelSettingsOptions.unsubscribedTrailer as string; + } + } + + const imageSettingsValues = (updateFields.brandingSettingsUi as IDataObject).imageSettingsValues as IDataObject | undefined; + const imageSettings: IDataObject = {}; + if (imageSettingsValues?.image) { + const imageSettingsOptions = imageSettings.image as IDataObject; + if (imageSettingsOptions.bannerExternalUrl) { + imageSettings.bannerExternalUrl = imageSettingsOptions.bannerExternalUrl as string; + } + if (imageSettingsOptions.trackingImageUrl) { + imageSettings.trackingImageUrl = imageSettingsOptions.trackingImageUrl as string; + } + if (imageSettingsOptions.watchIconImageUrl) { + imageSettings.watchIconImageUrl = imageSettingsOptions.watchIconImageUrl as string; + } + } + + //@ts-ignore + body.brandingSettings.channel = channelSettings; + //@ts-ignore + body.brandingSettings.image = imageSettings; + } + + responseData = await googleApiRequest.call( + this, + 'PUT', + '/youtube/v3/channels', + body, + qs, + ); + } + //https://developers.google.com/youtube/v3/docs/channelBanners/insert + if (operation === 'uploadBanner') { + const channelId = this.getNodeParameter('channelId', i) as string; + const binaryProperty = this.getNodeParameter('binaryProperty', i) as string; + + let mimeType; + + // Is binary file to upload + const item = items[i]; + + if (item.binary === undefined) { + throw new NodeOperationError(this.getNode(), 'No binary data exists on item!'); + } + + if (item.binary[binaryProperty] === undefined) { + throw new NodeOperationError(this.getNode(), `No binary data property "${binaryProperty}" does not exists on item!`); + } + + if (item.binary[binaryProperty].mimeType) { + mimeType = item.binary[binaryProperty].mimeType; + } + + const body = Buffer.from(item.binary[binaryProperty].data, BINARY_ENCODING); + + const requestOptions = { + headers: { + 'Content-Type': mimeType, + }, + json: false, + }; + + const response = await googleApiRequest.call(this, 'POST', '/upload/youtube/v3/channelBanners/insert', body, qs, undefined, requestOptions); + + const { url } = JSON.parse(response); + + qs.part = 'brandingSettings'; + + responseData = await googleApiRequest.call( + this, + 'PUT', + `/youtube/v3/channels`, + { + id: channelId, + brandingSettings: { + image: { + bannerExternalUrl: url, + }, }, }, - }, - qs, - ); - } - } - if (resource === 'playlist') { - //https://developers.google.com/youtube/v3/docs/playlists/list - if (operation === 'get') { - let part = this.getNodeParameter('part', i) as string[]; - const playlistId = this.getNodeParameter('playlistId', i) as string; - const options = this.getNodeParameter('options', i) as IDataObject; - - if (part.includes('*')) { - part = [ - 'contentDetails', - 'id', - 'localizations', - 'player', - 'snippet', - 'status', - ]; - } - - qs.part = part.join(','); - - qs.id = playlistId; - - Object.assign(qs, options); - - responseData = await googleApiRequest.call( - this, - 'GET', - `/youtube/v3/playlists`, - {}, - qs, - ); - - responseData = responseData.items; - } - //https://developers.google.com/youtube/v3/docs/playlists/list - if (operation === 'getAll') { - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - let part = this.getNodeParameter('part', i) as string[]; - const options = this.getNodeParameter('options', i) as IDataObject; - const filters = this.getNodeParameter('filters', i) as IDataObject; - - if (part.includes('*')) { - part = [ - 'contentDetails', - 'id', - 'localizations', - 'player', - 'snippet', - 'status', - ]; - } - - qs.part = part.join(','); - - Object.assign(qs, options, filters); - - qs.mine = true; - - if (qs.channelId || qs.id) { - delete qs.mine; - } - - if (returnAll) { - responseData = await googleApiRequestAllItems.call( - this, - 'items', - 'GET', - `/youtube/v3/playlists`, - {}, qs, ); - } else { - qs.maxResults = this.getNodeParameter('limit', i) as number; + } + } + if (resource === 'playlist') { + //https://developers.google.com/youtube/v3/docs/playlists/list + if (operation === 'get') { + let part = this.getNodeParameter('part', i) as string[]; + const playlistId = this.getNodeParameter('playlistId', i) as string; + const options = this.getNodeParameter('options', i) as IDataObject; + + if (part.includes('*')) { + part = [ + 'contentDetails', + 'id', + 'localizations', + 'player', + 'snippet', + 'status', + ]; + } + + qs.part = part.join(','); + + qs.id = playlistId; + + Object.assign(qs, options); + responseData = await googleApiRequest.call( this, 'GET', @@ -537,617 +489,673 @@ export class YouTube implements INodeType { {}, qs, ); + responseData = responseData.items; } - } - //https://developers.google.com/youtube/v3/docs/playlists/insert - if (operation === 'create') { - const title = this.getNodeParameter('title', i) as string; - const options = this.getNodeParameter('options', i) as IDataObject; + //https://developers.google.com/youtube/v3/docs/playlists/list + if (operation === 'getAll') { + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + let part = this.getNodeParameter('part', i) as string[]; + const options = this.getNodeParameter('options', i) as IDataObject; + const filters = this.getNodeParameter('filters', i) as IDataObject; - qs.part = 'snippet'; + if (part.includes('*')) { + part = [ + 'contentDetails', + 'id', + 'localizations', + 'player', + 'snippet', + 'status', + ]; + } - const body: IDataObject = { - snippet: { - title, - }, - }; + qs.part = part.join(','); - if (options.tags) { - //@ts-ignore - body.snippet.tags = (options.tags as string).split(',') as string[]; + Object.assign(qs, options, filters); + + qs.mine = true; + + if (qs.channelId || qs.id) { + delete qs.mine; + } + + if (returnAll) { + responseData = await googleApiRequestAllItems.call( + this, + 'items', + 'GET', + `/youtube/v3/playlists`, + {}, + qs, + ); + } else { + qs.maxResults = this.getNodeParameter('limit', i) as number; + responseData = await googleApiRequest.call( + this, + 'GET', + `/youtube/v3/playlists`, + {}, + qs, + ); + responseData = responseData.items; + } } + //https://developers.google.com/youtube/v3/docs/playlists/insert + if (operation === 'create') { + const title = this.getNodeParameter('title', i) as string; + const options = this.getNodeParameter('options', i) as IDataObject; - if (options.description) { - //@ts-ignore - body.snippet.privacyStatus = options.privacyStatus as string; - } + qs.part = 'snippet'; - if (options.defaultLanguage) { - //@ts-ignore - body.snippet.defaultLanguage = options.defaultLanguage as string; - } - - if (options.onBehalfOfContentOwner) { - qs.onBehalfOfContentOwner = options.onBehalfOfContentOwner as string; - } - - if (options.onBehalfOfContentOwnerChannel) { - qs.onBehalfOfContentOwnerChannel = options.onBehalfOfContentOwnerChannel as string; - } - - responseData = await googleApiRequest.call( - this, - 'POST', - '/youtube/v3/playlists', - body, - qs, - ); - } - //https://developers.google.com/youtube/v3/docs/playlists/update - if (operation === 'update') { - const playlistId = this.getNodeParameter('playlistId', i) as string; - const title = this.getNodeParameter('title', i) as string; - const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; - - qs.part = 'snippet, status'; - - const body: IDataObject = { - id: playlistId, - snippet: { - title, - }, - status: { - }, - }; - - if (updateFields.tags) { - //@ts-ignore - body.snippet.tags = (updateFields.tags as string).split(',') as string[]; - } - - if (updateFields.privacyStatus) { - //@ts-ignore - body.status.privacyStatus = updateFields.privacyStatus as string; - } - - if (updateFields.description) { - //@ts-ignore - body.snippet.description = updateFields.description as string; - } - - if (updateFields.defaultLanguage) { - //@ts-ignore - body.snippet.defaultLanguage = updateFields.defaultLanguage as string; - } - - if (updateFields.onBehalfOfContentOwner) { - qs.onBehalfOfContentOwner = updateFields.onBehalfOfContentOwner as string; - } - - responseData = await googleApiRequest.call( - this, - 'PUT', - '/youtube/v3/playlists', - body, - qs, - ); - } - //https://developers.google.com/youtube/v3/docs/playlists/delete - if (operation === 'delete') { - const playlistId = this.getNodeParameter('playlistId', i) as string; - const options = this.getNodeParameter('options', i) as IDataObject; - - const body: IDataObject = { - id: playlistId, - }; - - if (options.onBehalfOfContentOwner) { - qs.onBehalfOfContentOwner = options.onBehalfOfContentOwner as string; - } - - responseData = await googleApiRequest.call( - this, - 'DELETE', - '/youtube/v3/playlists', - body, - ); - - responseData = { success: true }; - } - } - if (resource === 'playlistItem') { - //https://developers.google.com/youtube/v3/docs/playlistItems/list - if (operation === 'get') { - let part = this.getNodeParameter('part', i) as string[]; - const playlistItemId = this.getNodeParameter('playlistItemId', i) as string; - const options = this.getNodeParameter('options', i) as IDataObject; - - if (part.includes('*')) { - part = [ - 'contentDetails', - 'id', - 'snippet', - 'status', - ]; - } - - qs.part = part.join(','); - - qs.id = playlistItemId; - - Object.assign(qs, options); - - responseData = await googleApiRequest.call( - this, - 'GET', - `/youtube/v3/playlistItems`, - {}, - qs, - ); - - responseData = responseData.items; - } - //https://developers.google.com/youtube/v3/docs/playlistItems/list - if (operation === 'getAll') { - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - let part = this.getNodeParameter('part', i) as string[]; - const options = this.getNodeParameter('options', i) as IDataObject; - const playlistId = this.getNodeParameter('playlistId', i) as string; - //const filters = this.getNodeParameter('filters', i) as IDataObject; - - if (part.includes('*')) { - part = [ - 'contentDetails', - 'id', - 'snippet', - 'status', - ]; - } - - qs.playlistId = playlistId; - - qs.part = part.join(','); - - Object.assign(qs, options); - - if (returnAll) { - responseData = await googleApiRequestAllItems.call( - this, - 'items', - 'GET', - `/youtube/v3/playlistItems`, - {}, - qs, - ); - } else { - qs.maxResults = this.getNodeParameter('limit', i) as number; - responseData = await googleApiRequest.call( - this, - 'GET', - `/youtube/v3/playlistItems`, - {}, - qs, - ); - responseData = responseData.items; - } - } - //https://developers.google.com/youtube/v3/docs/playlistItems/insert - if (operation === 'add') { - const playlistId = this.getNodeParameter('playlistId', i) as string; - const videoId = this.getNodeParameter('videoId', i) as string; - const options = this.getNodeParameter('options', i) as IDataObject; - - qs.part = 'snippet, contentDetails'; - - const body: IDataObject = { - snippet: { - playlistId, - resourceId: { - kind: 'youtube#video', - videoId, + const body: IDataObject = { + snippet: { + title, }, - }, - contentDetails: { - }, + }; - }; + if (options.tags) { + //@ts-ignore + body.snippet.tags = (options.tags as string).split(',') as string[]; + } - if (options.position) { - //@ts-ignore - body.snippet.position = options.position as number; - } + if (options.description) { + //@ts-ignore + body.snippet.privacyStatus = options.privacyStatus as string; + } - if (options.note) { - //@ts-ignore - body.contentDetails.note = options.note as string; - } + if (options.defaultLanguage) { + //@ts-ignore + body.snippet.defaultLanguage = options.defaultLanguage as string; + } - if (options.startAt) { - //@ts-ignore - body.contentDetails.startAt = options.startAt as string; - } + if (options.onBehalfOfContentOwner) { + qs.onBehalfOfContentOwner = options.onBehalfOfContentOwner as string; + } - if (options.endAt) { - //@ts-ignore - body.contentDetails.endAt = options.endAt as string; - } + if (options.onBehalfOfContentOwnerChannel) { + qs.onBehalfOfContentOwnerChannel = options.onBehalfOfContentOwnerChannel as string; + } - if (options.onBehalfOfContentOwner) { - qs.onBehalfOfContentOwner = options.onBehalfOfContentOwner as string; - } - - responseData = await googleApiRequest.call( - this, - 'POST', - '/youtube/v3/playlistItems', - body, - qs, - ); - } - //https://developers.google.com/youtube/v3/docs/playlistItems/delete - if (operation === 'delete') { - const playlistItemId = this.getNodeParameter('playlistItemId', i) as string; - const options = this.getNodeParameter('options', i) as IDataObject; - - const body: IDataObject = { - id: playlistItemId, - }; - - if (options.onBehalfOfContentOwner) { - qs.onBehalfOfContentOwner = options.onBehalfOfContentOwner as string; - } - - responseData = await googleApiRequest.call( - this, - 'DELETE', - '/youtube/v3/playlistItems', - body, - ); - - responseData = { success: true }; - } - } - if (resource === 'video') { - //https://developers.google.com/youtube/v3/docs/search/list - if (operation === 'getAll') { - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - const options = this.getNodeParameter('options', i) as IDataObject; - const filters = this.getNodeParameter('filters', i) as IDataObject; - - qs.part = 'snippet'; - - qs.type = 'video'; - - qs.forMine = true; - - Object.assign(qs, options, filters); - - if (Object.keys(filters).length > 0) { - delete qs.forMine; - } - - if (qs.relatedToVideoId && qs.forDeveloper !== undefined) { - throw new NodeOperationError(this.getNode(), `When using the parameter 'related to video' the parameter 'for developer' cannot be set`); - } - - if (returnAll) { - responseData = await googleApiRequestAllItems.call( + responseData = await googleApiRequest.call( this, - 'items', - 'GET', - `/youtube/v3/search`, - {}, + 'POST', + '/youtube/v3/playlists', + body, qs, ); - } else { - qs.maxResults = this.getNodeParameter('limit', i) as number; + } + //https://developers.google.com/youtube/v3/docs/playlists/update + if (operation === 'update') { + const playlistId = this.getNodeParameter('playlistId', i) as string; + const title = this.getNodeParameter('title', i) as string; + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + + qs.part = 'snippet, status'; + + const body: IDataObject = { + id: playlistId, + snippet: { + title, + }, + status: { + }, + }; + + if (updateFields.tags) { + //@ts-ignore + body.snippet.tags = (updateFields.tags as string).split(',') as string[]; + } + + if (updateFields.privacyStatus) { + //@ts-ignore + body.status.privacyStatus = updateFields.privacyStatus as string; + } + + if (updateFields.description) { + //@ts-ignore + body.snippet.description = updateFields.description as string; + } + + if (updateFields.defaultLanguage) { + //@ts-ignore + body.snippet.defaultLanguage = updateFields.defaultLanguage as string; + } + + if (updateFields.onBehalfOfContentOwner) { + qs.onBehalfOfContentOwner = updateFields.onBehalfOfContentOwner as string; + } + + responseData = await googleApiRequest.call( + this, + 'PUT', + '/youtube/v3/playlists', + body, + qs, + ); + } + //https://developers.google.com/youtube/v3/docs/playlists/delete + if (operation === 'delete') { + const playlistId = this.getNodeParameter('playlistId', i) as string; + const options = this.getNodeParameter('options', i) as IDataObject; + + const body: IDataObject = { + id: playlistId, + }; + + if (options.onBehalfOfContentOwner) { + qs.onBehalfOfContentOwner = options.onBehalfOfContentOwner as string; + } + + responseData = await googleApiRequest.call( + this, + 'DELETE', + '/youtube/v3/playlists', + body, + ); + + responseData = { success: true }; + } + } + if (resource === 'playlistItem') { + //https://developers.google.com/youtube/v3/docs/playlistItems/list + if (operation === 'get') { + let part = this.getNodeParameter('part', i) as string[]; + const playlistItemId = this.getNodeParameter('playlistItemId', i) as string; + const options = this.getNodeParameter('options', i) as IDataObject; + + if (part.includes('*')) { + part = [ + 'contentDetails', + 'id', + 'snippet', + 'status', + ]; + } + + qs.part = part.join(','); + + qs.id = playlistItemId; + + Object.assign(qs, options); + responseData = await googleApiRequest.call( this, 'GET', - `/youtube/v3/search`, + `/youtube/v3/playlistItems`, + {}, + qs, + ); + + responseData = responseData.items; + } + //https://developers.google.com/youtube/v3/docs/playlistItems/list + if (operation === 'getAll') { + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + let part = this.getNodeParameter('part', i) as string[]; + const options = this.getNodeParameter('options', i) as IDataObject; + const playlistId = this.getNodeParameter('playlistId', i) as string; + //const filters = this.getNodeParameter('filters', i) as IDataObject; + + if (part.includes('*')) { + part = [ + 'contentDetails', + 'id', + 'snippet', + 'status', + ]; + } + + qs.playlistId = playlistId; + + qs.part = part.join(','); + + Object.assign(qs, options); + + if (returnAll) { + responseData = await googleApiRequestAllItems.call( + this, + 'items', + 'GET', + `/youtube/v3/playlistItems`, + {}, + qs, + ); + } else { + qs.maxResults = this.getNodeParameter('limit', i) as number; + responseData = await googleApiRequest.call( + this, + 'GET', + `/youtube/v3/playlistItems`, + {}, + qs, + ); + responseData = responseData.items; + } + } + //https://developers.google.com/youtube/v3/docs/playlistItems/insert + if (operation === 'add') { + const playlistId = this.getNodeParameter('playlistId', i) as string; + const videoId = this.getNodeParameter('videoId', i) as string; + const options = this.getNodeParameter('options', i) as IDataObject; + + qs.part = 'snippet, contentDetails'; + + const body: IDataObject = { + snippet: { + playlistId, + resourceId: { + kind: 'youtube#video', + videoId, + }, + }, + contentDetails: { + }, + + }; + + if (options.position) { + //@ts-ignore + body.snippet.position = options.position as number; + } + + if (options.note) { + //@ts-ignore + body.contentDetails.note = options.note as string; + } + + if (options.startAt) { + //@ts-ignore + body.contentDetails.startAt = options.startAt as string; + } + + if (options.endAt) { + //@ts-ignore + body.contentDetails.endAt = options.endAt as string; + } + + if (options.onBehalfOfContentOwner) { + qs.onBehalfOfContentOwner = options.onBehalfOfContentOwner as string; + } + + responseData = await googleApiRequest.call( + this, + 'POST', + '/youtube/v3/playlistItems', + body, + qs, + ); + } + //https://developers.google.com/youtube/v3/docs/playlistItems/delete + if (operation === 'delete') { + const playlistItemId = this.getNodeParameter('playlistItemId', i) as string; + const options = this.getNodeParameter('options', i) as IDataObject; + + const body: IDataObject = { + id: playlistItemId, + }; + + if (options.onBehalfOfContentOwner) { + qs.onBehalfOfContentOwner = options.onBehalfOfContentOwner as string; + } + + responseData = await googleApiRequest.call( + this, + 'DELETE', + '/youtube/v3/playlistItems', + body, + ); + + responseData = { success: true }; + } + } + if (resource === 'video') { + //https://developers.google.com/youtube/v3/docs/search/list + if (operation === 'getAll') { + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + const options = this.getNodeParameter('options', i) as IDataObject; + const filters = this.getNodeParameter('filters', i) as IDataObject; + + qs.part = 'snippet'; + + qs.type = 'video'; + + qs.forMine = true; + + Object.assign(qs, options, filters); + + if (Object.keys(filters).length > 0) { + delete qs.forMine; + } + + if (qs.relatedToVideoId && qs.forDeveloper !== undefined) { + throw new NodeOperationError(this.getNode(), `When using the parameter 'related to video' the parameter 'for developer' cannot be set`); + } + + if (returnAll) { + responseData = await googleApiRequestAllItems.call( + this, + 'items', + 'GET', + `/youtube/v3/search`, + {}, + qs, + ); + } else { + qs.maxResults = this.getNodeParameter('limit', i) as number; + responseData = await googleApiRequest.call( + this, + 'GET', + `/youtube/v3/search`, + {}, + qs, + ); + responseData = responseData.items; + } + } + //https://developers.google.com/youtube/v3/docs/videos/list?hl=en + if (operation === 'get') { + let part = this.getNodeParameter('part', i) as string[]; + const videoId = this.getNodeParameter('videoId', i) as string; + const options = this.getNodeParameter('options', i) as IDataObject; + + if (part.includes('*')) { + part = [ + 'contentDetails', + 'id', + 'liveStreamingDetails', + 'localizations', + 'player', + 'recordingDetails', + 'snippet', + 'statistics', + 'status', + 'topicDetails', + ]; + } + + qs.part = part.join(','); + + qs.id = videoId; + + Object.assign(qs, options); + + responseData = await googleApiRequest.call( + this, + 'GET', + `/youtube/v3/videos`, + {}, + qs, + ); + + responseData = responseData.items; + } + //https://developers.google.com/youtube/v3/guides/uploading_a_video?hl=en + if (operation === 'upload') { + const title = this.getNodeParameter('title', i) as string; + const categoryId = this.getNodeParameter('categoryId', i) as string; + const options = this.getNodeParameter('options', i) as IDataObject; + const binaryProperty = this.getNodeParameter('binaryProperty', i) as string; + + let mimeType; + + // Is binary file to upload + const item = items[i]; + + if (item.binary === undefined) { + throw new NodeOperationError(this.getNode(), 'No binary data exists on item!'); + } + + if (item.binary[binaryProperty] === undefined) { + throw new NodeOperationError(this.getNode(), `No binary data property "${binaryProperty}" does not exists on item!`); + } + + if (item.binary[binaryProperty].mimeType) { + mimeType = item.binary[binaryProperty].mimeType; + } + + const body = Buffer.from(item.binary[binaryProperty].data, BINARY_ENCODING); + + const requestOptions = { + headers: { + 'Content-Type': mimeType, + }, + json: false, + }; + + const response = await googleApiRequest.call(this, 'POST', '/upload/youtube/v3/videos', body, qs, undefined, requestOptions); + + const { id } = JSON.parse(response); + + qs.part = 'snippet, status, recordingDetails'; + + const data = { + id, + snippet: { + title, + categoryId, + }, + status: { + }, + recordingDetails: { + }, + }; + + if (options.description) { + //@ts-ignore + data.snippet.description = options.description as string; + } + + if (options.privacyStatus) { + //@ts-ignore + data.status.privacyStatus = options.privacyStatus as string; + } + + if (options.tags) { + //@ts-ignore + data.snippet.tags = (options.tags as string).split(',') as string[]; + } + + if (options.embeddable) { + //@ts-ignore + data.status.embeddable = options.embeddable as boolean; + } + + if (options.publicStatsViewable) { + //@ts-ignore + data.status.publicStatsViewable = options.publicStatsViewable as boolean; + } + + if (options.publishAt) { + //@ts-ignore + data.status.publishAt = options.publishAt as string; + } + + if (options.recordingDate) { + //@ts-ignore + data.recordingDetails.recordingDate = options.recordingDate as string; + } + + if (options.selfDeclaredMadeForKids) { + //@ts-ignore + data.status.selfDeclaredMadeForKids = options.selfDeclaredMadeForKids as boolean; + } + + if (options.license) { + //@ts-ignore + data.status.license = options.license as string; + } + + if (options.defaultLanguage) { + //@ts-ignore + data.snippet.defaultLanguage = options.defaultLanguage as string; + } + + if (options.notifySubscribers) { + qs.notifySubscribers = options.notifySubscribers; + delete options.notifySubscribers; + } + + responseData = await googleApiRequest.call( + this, + 'PUT', + `/youtube/v3/videos`, + data, + qs, + ); + } + //https://developers.google.com/youtube/v3/docs/playlists/update + if (operation === 'update') { + const id = this.getNodeParameter('videoId', i) as string; + const title = this.getNodeParameter('title', i) as string; + const categoryId = this.getNodeParameter('categoryId', i) as string; + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + + qs.part = 'snippet, status, recordingDetails'; + + const body = { + id, + snippet: { + title, + categoryId, + }, + status: { + }, + recordingDetails: { + }, + }; + + if (updateFields.description) { + //@ts-ignore + body.snippet.description = updateFields.description as string; + } + + if (updateFields.privacyStatus) { + //@ts-ignore + body.status.privacyStatus = updateFields.privacyStatus as string; + } + + if (updateFields.tags) { + //@ts-ignore + body.snippet.tags = (updateFields.tags as string).split(',') as string[]; + } + + if (updateFields.embeddable) { + //@ts-ignore + body.status.embeddable = updateFields.embeddable as boolean; + } + + if (updateFields.publicStatsViewable) { + //@ts-ignore + body.status.publicStatsViewable = updateFields.publicStatsViewable as boolean; + } + + if (updateFields.publishAt) { + //@ts-ignore + body.status.publishAt = updateFields.publishAt as string; + } + + if (updateFields.selfDeclaredMadeForKids) { + //@ts-ignore + body.status.selfDeclaredMadeForKids = updateFields.selfDeclaredMadeForKids as boolean; + } + + if (updateFields.recordingDate) { + //@ts-ignore + body.recordingDetails.recordingDate = updateFields.recordingDate as string; + } + + if (updateFields.license) { + //@ts-ignore + body.status.license = updateFields.license as string; + } + + if (updateFields.defaultLanguage) { + //@ts-ignore + body.snippet.defaultLanguage = updateFields.defaultLanguage as string; + } + + responseData = await googleApiRequest.call( + this, + 'PUT', + '/youtube/v3/videos', + body, + qs, + ); + } + //https://developers.google.com/youtube/v3/docs/videos/delete?hl=en + if (operation === 'delete') { + const videoId = this.getNodeParameter('videoId', i) as string; + const options = this.getNodeParameter('options', i) as IDataObject; + + const body: IDataObject = { + id: videoId, + }; + + if (options.onBehalfOfContentOwner) { + qs.onBehalfOfContentOwner = options.onBehalfOfContentOwner as string; + } + + responseData = await googleApiRequest.call( + this, + 'DELETE', + '/youtube/v3/videos', + body, + ); + + responseData = { success: true }; + } + //https://developers.google.com/youtube/v3/docs/videos/rate?hl=en + if (operation === 'rate') { + const videoId = this.getNodeParameter('videoId', i) as string; + const rating = this.getNodeParameter('rating', i) as string; + + const body: IDataObject = { + id: videoId, + rating, + }; + + responseData = await googleApiRequest.call( + this, + 'POST', + '/youtube/v3/videos/rate', + body, + ); + + responseData = { success: true }; + } + } + if (resource === 'videoCategory') { + //https://developers.google.com/youtube/v3/docs/videoCategories/list + if (operation === 'getAll') { + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + const regionCode = this.getNodeParameter('regionCode', i) as string; + + qs.regionCode = regionCode; + + qs.part = 'snippet'; + + responseData = await googleApiRequest.call( + this, + 'GET', + `/youtube/v3/videoCategories`, {}, qs, ); responseData = responseData.items; + + if (returnAll === false) { + const limit = this.getNodeParameter('limit', i) as number; + responseData = responseData.splice(0, limit); + } } } - //https://developers.google.com/youtube/v3/docs/videos/list?hl=en - if (operation === 'get') { - let part = this.getNodeParameter('part', i) as string[]; - const videoId = this.getNodeParameter('videoId', i) as string; - const options = this.getNodeParameter('options', i) as IDataObject; - - if (part.includes('*')) { - part = [ - 'contentDetails', - 'id', - 'liveStreamingDetails', - 'localizations', - 'player', - 'recordingDetails', - 'snippet', - 'statistics', - 'status', - 'topicDetails', - ]; - } - - qs.part = part.join(','); - - qs.id = videoId; - - Object.assign(qs, options); - - responseData = await googleApiRequest.call( - this, - 'GET', - `/youtube/v3/videos`, - {}, - qs, - ); - - responseData = responseData.items; - } - //https://developers.google.com/youtube/v3/guides/uploading_a_video?hl=en - if (operation === 'upload') { - const title = this.getNodeParameter('title', i) as string; - const categoryId = this.getNodeParameter('categoryId', i) as string; - const options = this.getNodeParameter('options', i) as IDataObject; - const binaryProperty = this.getNodeParameter('binaryProperty', i) as string; - - let mimeType; - - // Is binary file to upload - const item = items[i]; - - if (item.binary === undefined) { - throw new NodeOperationError(this.getNode(), 'No binary data exists on item!'); - } - - if (item.binary[binaryProperty] === undefined) { - throw new NodeOperationError(this.getNode(), `No binary data property "${binaryProperty}" does not exists on item!`); - } - - if (item.binary[binaryProperty].mimeType) { - mimeType = item.binary[binaryProperty].mimeType; - } - - const body = Buffer.from(item.binary[binaryProperty].data, BINARY_ENCODING); - - const requestOptions = { - headers: { - 'Content-Type': mimeType, - }, - json: false, - }; - - const response = await googleApiRequest.call(this, 'POST', '/upload/youtube/v3/videos', body, qs, undefined, requestOptions); - - const { id } = JSON.parse(response); - - qs.part = 'snippet, status, recordingDetails'; - - const data = { - id, - snippet: { - title, - categoryId, - }, - status: { - }, - recordingDetails: { - }, - }; - - if (options.description) { - //@ts-ignore - data.snippet.description = options.description as string; - } - - if (options.privacyStatus) { - //@ts-ignore - data.status.privacyStatus = options.privacyStatus as string; - } - - if (options.tags) { - //@ts-ignore - data.snippet.tags = (options.tags as string).split(',') as string[]; - } - - if (options.embeddable) { - //@ts-ignore - data.status.embeddable = options.embeddable as boolean; - } - - if (options.publicStatsViewable) { - //@ts-ignore - data.status.publicStatsViewable = options.publicStatsViewable as boolean; - } - - if (options.publishAt) { - //@ts-ignore - data.status.publishAt = options.publishAt as string; - } - - if (options.recordingDate) { - //@ts-ignore - data.recordingDetails.recordingDate = options.recordingDate as string; - } - - if (options.selfDeclaredMadeForKids) { - //@ts-ignore - data.status.selfDeclaredMadeForKids = options.selfDeclaredMadeForKids as boolean; - } - - if (options.license) { - //@ts-ignore - data.status.license = options.license as string; - } - - if (options.defaultLanguage) { - //@ts-ignore - data.snippet.defaultLanguage = options.defaultLanguage as string; - } - - if (options.notifySubscribers) { - qs.notifySubscribers = options.notifySubscribers; - delete options.notifySubscribers; - } - - responseData = await googleApiRequest.call( - this, - 'PUT', - `/youtube/v3/videos`, - data, - qs, - ); - } - //https://developers.google.com/youtube/v3/docs/playlists/update - if (operation === 'update') { - const id = this.getNodeParameter('videoId', i) as string; - const title = this.getNodeParameter('title', i) as string; - const categoryId = this.getNodeParameter('categoryId', i) as string; - const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; - - qs.part = 'snippet, status, recordingDetails'; - - const body = { - id, - snippet: { - title, - categoryId, - }, - status: { - }, - recordingDetails: { - }, - }; - - if (updateFields.description) { - //@ts-ignore - body.snippet.description = updateFields.description as string; - } - - if (updateFields.privacyStatus) { - //@ts-ignore - body.status.privacyStatus = updateFields.privacyStatus as string; - } - - if (updateFields.tags) { - //@ts-ignore - body.snippet.tags = (updateFields.tags as string).split(',') as string[]; - } - - if (updateFields.embeddable) { - //@ts-ignore - body.status.embeddable = updateFields.embeddable as boolean; - } - - if (updateFields.publicStatsViewable) { - //@ts-ignore - body.status.publicStatsViewable = updateFields.publicStatsViewable as boolean; - } - - if (updateFields.publishAt) { - //@ts-ignore - body.status.publishAt = updateFields.publishAt as string; - } - - if (updateFields.selfDeclaredMadeForKids) { - //@ts-ignore - body.status.selfDeclaredMadeForKids = updateFields.selfDeclaredMadeForKids as boolean; - } - - if (updateFields.recordingDate) { - //@ts-ignore - body.recordingDetails.recordingDate = updateFields.recordingDate as string; - } - - if (updateFields.license) { - //@ts-ignore - body.status.license = updateFields.license as string; - } - - if (updateFields.defaultLanguage) { - //@ts-ignore - body.snippet.defaultLanguage = updateFields.defaultLanguage as string; - } - - responseData = await googleApiRequest.call( - this, - 'PUT', - '/youtube/v3/videos', - body, - qs, - ); - } - //https://developers.google.com/youtube/v3/docs/videos/delete?hl=en - if (operation === 'delete') { - const videoId = this.getNodeParameter('videoId', i) as string; - const options = this.getNodeParameter('options', i) as IDataObject; - - const body: IDataObject = { - id: videoId, - }; - - if (options.onBehalfOfContentOwner) { - qs.onBehalfOfContentOwner = options.onBehalfOfContentOwner as string; - } - - responseData = await googleApiRequest.call( - this, - 'DELETE', - '/youtube/v3/videos', - body, - ); - - responseData = { success: true }; - } - //https://developers.google.com/youtube/v3/docs/videos/rate?hl=en - if (operation === 'rate') { - const videoId = this.getNodeParameter('videoId', i) as string; - const rating = this.getNodeParameter('rating', i) as string; - - const body: IDataObject = { - id: videoId, - rating, - }; - - responseData = await googleApiRequest.call( - this, - 'POST', - '/youtube/v3/videos/rate', - body, - ); - - responseData = { success: true }; - } - } - if (resource === 'videoCategory') { - //https://developers.google.com/youtube/v3/docs/videoCategories/list - if (operation === 'getAll') { - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - const regionCode = this.getNodeParameter('regionCode', i) as string; - - qs.regionCode = regionCode; - - qs.part = 'snippet'; - - responseData = await googleApiRequest.call( - this, - 'GET', - `/youtube/v3/videoCategories`, - {}, - qs, - ); - responseData = responseData.items; - - if (returnAll === false) { - const limit = this.getNodeParameter('limit', i) as number; - responseData = responseData.splice(0, limit); - } + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; } + throw error; } } if (Array.isArray(responseData)) { diff --git a/packages/nodes-base/nodes/Gotify/Gotify.node.ts b/packages/nodes-base/nodes/Gotify/Gotify.node.ts index 03e3eec7e2..f893e945dd 100644 --- a/packages/nodes-base/nodes/Gotify/Gotify.node.ts +++ b/packages/nodes-base/nodes/Gotify/Gotify.node.ts @@ -194,67 +194,75 @@ export class Gotify implements INodeType { 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 === 'message') { - if (operation === 'create') { + try { + if (resource === 'message') { + if (operation === 'create') { - const message = this.getNodeParameter('message', i) as string; + const message = this.getNodeParameter('message', i) as string; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const body: IDataObject = { - message, - }; + const body: IDataObject = { + message, + }; - Object.assign(body, additionalFields); + Object.assign(body, additionalFields); - responseData = await gotifyApiRequest.call( - this, - 'POST', - `/message`, - body, - ); - } - if (operation === 'delete') { - const messageId = this.getNodeParameter('messageId', i) as string; - - responseData = await gotifyApiRequest.call( - this, - 'DELETE', - `/message/${messageId}`, - ); - responseData = { success: true }; - } - - if (operation === 'getAll') { - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - - if (returnAll) { - responseData = await gotifyApiRequestAllItems.call( - this, - 'messages', - 'GET', - '/message', - {}, - qs, - ); - - } else { - qs.limit = this.getNodeParameter('limit', i) as number; responseData = await gotifyApiRequest.call( this, - 'GET', + 'POST', `/message`, - {}, - qs, + body, ); - responseData = responseData.messages; + } + if (operation === 'delete') { + const messageId = this.getNodeParameter('messageId', i) as string; + + responseData = await gotifyApiRequest.call( + this, + 'DELETE', + `/message/${messageId}`, + ); + responseData = { success: true }; + } + + if (operation === 'getAll') { + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + + if (returnAll) { + responseData = await gotifyApiRequestAllItems.call( + this, + 'messages', + 'GET', + '/message', + {}, + qs, + ); + + } else { + qs.limit = this.getNodeParameter('limit', i) as number; + responseData = await gotifyApiRequest.call( + this, + 'GET', + `/message`, + {}, + qs, + ); + responseData = responseData.messages; + } } } - } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else if (responseData !== undefined) { - returnData.push(responseData as IDataObject); + if (Array.isArray(responseData)) { + returnData.push.apply(returnData, responseData as IDataObject[]); + } else if (responseData !== undefined) { + returnData.push(responseData as IDataObject); + } + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } } return [this.helpers.returnJsonArray(returnData)]; diff --git a/packages/nodes-base/nodes/GraphQL/GraphQL.node.ts b/packages/nodes-base/nodes/GraphQL/GraphQL.node.ts index 25b347f502..346ed4c547 100644 --- a/packages/nodes-base/nodes/GraphQL/GraphQL.node.ts +++ b/packages/nodes-base/nodes/GraphQL/GraphQL.node.ts @@ -236,81 +236,89 @@ export class GraphQL implements INodeType { const returnItems: INodeExecutionData[] = []; for (let itemIndex = 0; itemIndex < items.length; itemIndex++) { - const requestMethod = this.getNodeParameter('requestMethod', itemIndex, 'POST') as string; - const endpoint = this.getNodeParameter('endpoint', itemIndex, '') as string; - const requestFormat = this.getNodeParameter('requestFormat', itemIndex, 'graphql') as string; - const responseFormat = this.getNodeParameter('responseFormat', 0) as string; + try { + const requestMethod = this.getNodeParameter('requestMethod', itemIndex, 'POST') as string; + const endpoint = this.getNodeParameter('endpoint', itemIndex, '') as string; + const requestFormat = this.getNodeParameter('requestFormat', itemIndex, 'graphql') as string; + const responseFormat = this.getNodeParameter('responseFormat', 0) as string; - const { parameter }: { parameter?: Array<{ name: string, value: string }> } = this - .getNodeParameter('headerParametersUi', itemIndex, {}) as IDataObject; - const headerParameters = (parameter || []).reduce((result, item) => ({ - ...result, - [item.name]: item.value, - }), {}); + const { parameter }: { parameter?: Array<{ name: string, value: string }> } = this + .getNodeParameter('headerParametersUi', itemIndex, {}) as IDataObject; + const headerParameters = (parameter || []).reduce((result, item) => ({ + ...result, + [item.name]: item.value, + }), {}); - requestOptions = { - headers: { - 'content-type': `application/${requestFormat}`, - ...headerParameters, - }, - method: requestMethod, - uri: endpoint, - simple: false, - rejectUnauthorized: !this.getNodeParameter('allowUnauthorizedCerts', itemIndex, false) as boolean, - }; - - // Add credentials if any are set - if (httpHeaderAuth !== undefined) { - requestOptions.headers![httpHeaderAuth.name as string] = httpHeaderAuth.value; - } - - const gqlQuery = this.getNodeParameter('query', itemIndex, '') as string; - if (requestMethod === 'GET') { - requestOptions.qs = { - query: gqlQuery, - }; - } else { - if (requestFormat === 'json') { - requestOptions.body = { - query: gqlQuery, - variables: this.getNodeParameter('variables', itemIndex, {}) as object, - operationName: this.getNodeParameter('operationName', itemIndex) as string, - }; - if (typeof requestOptions.body.variables === 'string') { - try { - requestOptions.body.variables = JSON.parse(requestOptions.body.variables || '{}'); - } catch (error) { - throw new NodeOperationError(this.getNode(), 'Using variables failed:\n' + requestOptions.body.variables + '\n\nWith error message:\n' + error); - } - } - if (requestOptions.body.operationName === '') { - requestOptions.body.operationName = null; - } - requestOptions.json = true; - } else { - requestOptions.body = gqlQuery; - } - } - - const response = await this.helpers.request(requestOptions); - if (responseFormat === 'string') { - const dataPropertyName = this.getNodeParameter('dataPropertyName', 0) as string; - - returnItems.push({ - json: { - [dataPropertyName]: response, + requestOptions = { + headers: { + 'content-type': `application/${requestFormat}`, + ...headerParameters, }, - }); - } else { - if (typeof response === 'string') { - try { - returnItems.push({ json: JSON.parse(response) }); - } catch (error) { - throw new NodeOperationError(this.getNode(), 'Response body is not valid JSON. Change "Response Format" to "String"'); - } - } else { - returnItems.push({ json: response }); + method: requestMethod, + uri: endpoint, + simple: false, + rejectUnauthorized: !this.getNodeParameter('allowUnauthorizedCerts', itemIndex, false) as boolean, + }; + + // Add credentials if any are set + if (httpHeaderAuth !== undefined) { + requestOptions.headers![httpHeaderAuth.name as string] = httpHeaderAuth.value; } + + const gqlQuery = this.getNodeParameter('query', itemIndex, '') as string; + if (requestMethod === 'GET') { + requestOptions.qs = { + query: gqlQuery, + }; + } else { + if (requestFormat === 'json') { + requestOptions.body = { + query: gqlQuery, + variables: this.getNodeParameter('variables', itemIndex, {}) as object, + operationName: this.getNodeParameter('operationName', itemIndex) as string, + }; + if (typeof requestOptions.body.variables === 'string') { + try { + requestOptions.body.variables = JSON.parse(requestOptions.body.variables || '{}'); + } catch (error) { + throw new NodeOperationError(this.getNode(), 'Using variables failed:\n' + requestOptions.body.variables + '\n\nWith error message:\n' + error); + } + } + if (requestOptions.body.operationName === '') { + requestOptions.body.operationName = null; + } + requestOptions.json = true; + } else { + requestOptions.body = gqlQuery; + } + } + + const response = await this.helpers.request(requestOptions); + if (responseFormat === 'string') { + const dataPropertyName = this.getNodeParameter('dataPropertyName', 0) as string; + + returnItems.push({ + json: { + [dataPropertyName]: response, + }, + }); + } else { + if (typeof response === 'string') { + try { + returnItems.push({ json: JSON.parse(response) }); + } catch (error) { + throw new NodeOperationError(this.getNode(), 'Response body is not valid JSON. Change "Response Format" to "String"'); + } + } else { + returnItems.push({ json: response }); + } + } + } catch (error) { + if (this.continueOnFail()) { + returnItems.push({ json: { error: error.message } }); + continue; + } + throw error; } } diff --git a/packages/nodes-base/nodes/HackerNews/HackerNews.node.ts b/packages/nodes-base/nodes/HackerNews/HackerNews.node.ts index 95fe4eeec1..d260434585 100644 --- a/packages/nodes-base/nodes/HackerNews/HackerNews.node.ts +++ b/packages/nodes-base/nodes/HackerNews/HackerNews.node.ts @@ -303,80 +303,86 @@ export class HackerNews implements INodeType { let returnAll = false; for (let i = 0; i < items.length; i++) { + try { + let qs: IDataObject = {}; + let endpoint = ''; + let includeComments = false; - let qs: IDataObject = {}; - let endpoint = ''; - let includeComments = false; + if (resource === 'all') { + if (operation === 'getAll') { - if (resource === 'all') { - if (operation === 'getAll') { + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const keyword = additionalFields.keyword as string; + const tags = additionalFields.tags as string[]; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const keyword = additionalFields.keyword as string; - const tags = additionalFields.tags as string[]; + qs = { + query: keyword, + tags: tags ? tags.join() : '', + }; - qs = { - query: keyword, - tags: tags ? tags.join() : '', - }; + returnAll = this.getNodeParameter('returnAll', i) as boolean; - returnAll = this.getNodeParameter('returnAll', i) as boolean; + if (!returnAll) { + qs.hitsPerPage = this.getNodeParameter('limit', i) as number; + } - if (!returnAll) { - qs.hitsPerPage = this.getNodeParameter('limit', i) as number; + endpoint = 'search?'; + + } else { + throw new NodeOperationError(this.getNode(), `The operation '${operation}' is unknown!`); + } + } else if (resource === 'article') { + + if (operation === 'get') { + + endpoint = `items/${this.getNodeParameter('articleId', i)}`; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + includeComments = additionalFields.includeComments as boolean; + + } else { + throw new NodeOperationError(this.getNode(), `The operation '${operation}' is unknown!`); } - endpoint = 'search?'; + } else if (resource === 'user') { + + if (operation === 'get') { + endpoint = `users/${this.getNodeParameter('username', i)}`; + + } else { + throw new NodeOperationError(this.getNode(), `The operation '${operation}' is unknown!`); + } } else { - throw new NodeOperationError(this.getNode(), `The operation '${operation}' is unknown!`); + throw new NodeOperationError(this.getNode(), `The resource '${resource}' is unknown!`); } - } else if (resource === 'article') { - if (operation === 'get') { - - endpoint = `items/${this.getNodeParameter('articleId', i)}`; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - includeComments = additionalFields.includeComments as boolean; + let responseData; + if (returnAll === true) { + responseData = await hackerNewsApiRequestAllItems.call(this, 'GET', endpoint, qs); } else { - throw new NodeOperationError(this.getNode(), `The operation '${operation}' is unknown!`); + responseData = await hackerNewsApiRequest.call(this, 'GET', endpoint, qs); + if (resource === 'all' && operation === 'getAll') { + responseData = responseData.hits; + } } - } else if (resource === 'user') { - - if (operation === 'get') { - endpoint = `users/${this.getNodeParameter('username', i)}`; + if (resource === 'article' && operation === 'get' && !includeComments) { + delete responseData.children; + } + if (Array.isArray(responseData)) { + returnData.push.apply(returnData, responseData as IDataObject[]); } else { - throw new NodeOperationError(this.getNode(), `The operation '${operation}' is unknown!`); + returnData.push(responseData as IDataObject); } - - } else { - throw new NodeOperationError(this.getNode(), `The resource '${resource}' is unknown!`); - } - - - let responseData; - if (returnAll === true) { - responseData = await hackerNewsApiRequestAllItems.call(this, 'GET', endpoint, qs); - } else { - responseData = await hackerNewsApiRequest.call(this, 'GET', endpoint, qs); - if (resource === 'all' && operation === 'getAll') { - responseData = responseData.hits; + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; } + throw error; } - - if (resource === 'article' && operation === 'get' && !includeComments) { - delete responseData.children; - } - - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else { - returnData.push(responseData as IDataObject); - } - } return [this.helpers.returnJsonArray(returnData)]; diff --git a/packages/nodes-base/nodes/Harvest/Harvest.node.ts b/packages/nodes-base/nodes/Harvest/Harvest.node.ts index 8540a83093..7b3ff29974 100644 --- a/packages/nodes-base/nodes/Harvest/Harvest.node.ts +++ b/packages/nodes-base/nodes/Harvest/Harvest.node.ts @@ -245,706 +245,714 @@ export class Harvest implements INodeType { let qs: IDataObject; for (let i = 0; i < items.length; i++) { - body = {}; - qs = {}; + try { + body = {}; + qs = {}; - if (resource === 'timeEntry') { - if (operation === 'get') { - // ---------------------------------- - // get - // ---------------------------------- + if (resource === 'timeEntry') { + if (operation === 'get') { + // ---------------------------------- + // get + // ---------------------------------- - requestMethod = 'GET'; - const id = this.getNodeParameter('id', i) as string; + requestMethod = 'GET'; + const id = this.getNodeParameter('id', i) as string; - endpoint = `time_entries/${id}`; + endpoint = `time_entries/${id}`; - const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint); - returnData.push(responseData); + const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint); + returnData.push(responseData); - } else if (operation === 'getAll') { - // ---------------------------------- - // getAll - // ---------------------------------- - const responseData: IDataObject[] = await getAllResource.call(this, 'time_entries', i); - returnData.push.apply(returnData, responseData); + } else if (operation === 'getAll') { + // ---------------------------------- + // getAll + // ---------------------------------- + const responseData: IDataObject[] = await getAllResource.call(this, 'time_entries', i); + returnData.push.apply(returnData, responseData); - } else if (operation === 'createByStartEnd') { - // ---------------------------------- - // createByStartEnd - // ---------------------------------- + } else if (operation === 'createByStartEnd') { + // ---------------------------------- + // createByStartEnd + // ---------------------------------- - requestMethod = 'POST'; - endpoint = 'time_entries'; + requestMethod = 'POST'; + endpoint = 'time_entries'; - body.project_id = this.getNodeParameter('projectId', i) as string; - body.task_id = this.getNodeParameter('taskId', i) as string; - body.spent_date = this.getNodeParameter('spentDate', i) as string; + body.project_id = this.getNodeParameter('projectId', i) as string; + body.task_id = this.getNodeParameter('taskId', i) as string; + body.spent_date = this.getNodeParameter('spentDate', i) as string; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - Object.assign(body, additionalFields); + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + Object.assign(body, additionalFields); - const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint, body); - returnData.push(responseData); + const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint, body); + returnData.push(responseData); - } else if (operation === 'createByDuration') { - // ---------------------------------- - // createByDuration - // ---------------------------------- + } else if (operation === 'createByDuration') { + // ---------------------------------- + // createByDuration + // ---------------------------------- - requestMethod = 'POST'; - endpoint = 'time_entries'; + requestMethod = 'POST'; + endpoint = 'time_entries'; - body.project_id = this.getNodeParameter('projectId', i) as string; - body.task_id = this.getNodeParameter('taskId', i) as string; - body.spent_date = this.getNodeParameter('spentDate', i) as string; + body.project_id = this.getNodeParameter('projectId', i) as string; + body.task_id = this.getNodeParameter('taskId', i) as string; + body.spent_date = this.getNodeParameter('spentDate', i) as string; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - Object.assign(body, additionalFields); + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + Object.assign(body, additionalFields); - const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint, body); - returnData.push(responseData); + const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint, body); + returnData.push(responseData); - } else if (operation === 'delete') { - // ---------------------------------- - // delete - // ---------------------------------- + } else if (operation === 'delete') { + // ---------------------------------- + // delete + // ---------------------------------- - requestMethod = 'DELETE'; - const id = this.getNodeParameter('id', i) as string; - endpoint = `time_entries/${id}`; + requestMethod = 'DELETE'; + const id = this.getNodeParameter('id', i) as string; + endpoint = `time_entries/${id}`; - const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint); - returnData.push(responseData); - } else if (operation === 'deleteExternal') { - // ---------------------------------- - // deleteExternal - // ---------------------------------- + const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint); + returnData.push(responseData); + } else if (operation === 'deleteExternal') { + // ---------------------------------- + // deleteExternal + // ---------------------------------- - requestMethod = 'DELETE'; - const id = this.getNodeParameter('id', i) as string; - endpoint = `time_entries/${id}/external_reference`; + requestMethod = 'DELETE'; + const id = this.getNodeParameter('id', i) as string; + endpoint = `time_entries/${id}/external_reference`; - const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint); - returnData.push(responseData); + const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint); + returnData.push(responseData); - } else if (operation === 'restartTime') { - // ---------------------------------- - // restartTime - // ---------------------------------- + } else if (operation === 'restartTime') { + // ---------------------------------- + // restartTime + // ---------------------------------- - requestMethod = 'PATCH'; - const id = this.getNodeParameter('id', i) as string; - endpoint = `time_entries/${id}/restart`; + requestMethod = 'PATCH'; + const id = this.getNodeParameter('id', i) as string; + endpoint = `time_entries/${id}/restart`; - const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint); - returnData.push(responseData); + const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint); + returnData.push(responseData); - } else if (operation === 'stopTime') { - // ---------------------------------- - // stopTime - // ---------------------------------- + } else if (operation === 'stopTime') { + // ---------------------------------- + // stopTime + // ---------------------------------- - requestMethod = 'PATCH'; - const id = this.getNodeParameter('id', i) as string; - endpoint = `time_entries/${id}/stop`; + requestMethod = 'PATCH'; + const id = this.getNodeParameter('id', i) as string; + endpoint = `time_entries/${id}/stop`; - const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint); - returnData.push(responseData); + const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint); + returnData.push(responseData); - } else if (operation === 'update') { - // ---------------------------------- - // update - // ---------------------------------- + } else if (operation === 'update') { + // ---------------------------------- + // update + // ---------------------------------- - requestMethod = 'PATCH'; - const id = this.getNodeParameter('id', i) as string; - endpoint = `time_entries/${id}`; + requestMethod = 'PATCH'; + const id = this.getNodeParameter('id', i) as string; + endpoint = `time_entries/${id}`; - const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; - Object.assign(body, updateFields); - const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint, body); - returnData.push(responseData); + Object.assign(body, updateFields); + const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint, body); + returnData.push(responseData); - } else { - throw new NodeOperationError(this.getNode(), `The operation "${operation}" is not known!`); - } + } else { + throw new NodeOperationError(this.getNode(), `The operation "${operation}" is not known!`); + } - } else if (resource === 'client') { - if (operation === 'get') { - // ---------------------------------- - // get - // ---------------------------------- + } else if (resource === 'client') { + if (operation === 'get') { + // ---------------------------------- + // get + // ---------------------------------- - requestMethod = 'GET'; - const id = this.getNodeParameter('id', i) as string; + requestMethod = 'GET'; + const id = this.getNodeParameter('id', i) as string; - endpoint = `clients/${id}`; + endpoint = `clients/${id}`; - const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint); - returnData.push(responseData); + const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint); + returnData.push(responseData); - } else if (operation === 'getAll') { - // ---------------------------------- - // getAll - // ---------------------------------- + } else if (operation === 'getAll') { + // ---------------------------------- + // getAll + // ---------------------------------- - const responseData: IDataObject[] = await getAllResource.call(this, 'clients', i); - returnData.push.apply(returnData, responseData); + const responseData: IDataObject[] = await getAllResource.call(this, 'clients', i); + returnData.push.apply(returnData, responseData); - } else if (operation === 'create') { - // ---------------------------------- - // create - // ---------------------------------- + } else if (operation === 'create') { + // ---------------------------------- + // create + // ---------------------------------- - requestMethod = 'POST'; - endpoint = 'clients'; + requestMethod = 'POST'; + endpoint = 'clients'; - body.name = this.getNodeParameter('name', i) as string; + body.name = this.getNodeParameter('name', i) as string; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - Object.assign(body, additionalFields); + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + Object.assign(body, additionalFields); - const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint, body); - returnData.push(responseData); + const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint, body); + returnData.push(responseData); - } else if (operation === 'update') { - // ---------------------------------- - // update - // ---------------------------------- + } else if (operation === 'update') { + // ---------------------------------- + // update + // ---------------------------------- - requestMethod = 'PATCH'; - const id = this.getNodeParameter('id', i) as string; - endpoint = `clients/${id}`; + requestMethod = 'PATCH'; + const id = this.getNodeParameter('id', i) as string; + endpoint = `clients/${id}`; - const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; - Object.assign(qs, updateFields); + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + Object.assign(qs, updateFields); - const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint, body); - returnData.push(responseData); + const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint, body); + returnData.push(responseData); - } else if (operation === 'delete') { - // ---------------------------------- - // delete - // ---------------------------------- + } else if (operation === 'delete') { + // ---------------------------------- + // delete + // ---------------------------------- - requestMethod = 'DELETE'; - const id = this.getNodeParameter('id', i) as string; - endpoint = `clients/${id}`; + requestMethod = 'DELETE'; + const id = this.getNodeParameter('id', i) as string; + endpoint = `clients/${id}`; - const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint); - returnData.push(responseData); + const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint); + returnData.push(responseData); + } else { + throw new NodeOperationError(this.getNode(), `The resource "${resource}" is not known!`); + } + } else if (resource === 'project') { + if (operation === 'get') { + // ---------------------------------- + // get + // ---------------------------------- + + requestMethod = 'GET'; + const id = this.getNodeParameter('id', i) as string; + + endpoint = `projects/${id}`; + + const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint); + returnData.push(responseData); + + } else if (operation === 'getAll') { + // ---------------------------------- + // getAll + // ---------------------------------- + + const responseData: IDataObject[] = await getAllResource.call(this, 'projects', i); + returnData.push.apply(returnData, responseData); + + } else if (operation === 'create') { + // ---------------------------------- + // create + // ---------------------------------- + + requestMethod = 'POST'; + endpoint = 'projects'; + + body.client_id = this.getNodeParameter('clientId', i) as string; + body.name = this.getNodeParameter('name', i) as string; + body.is_billable = this.getNodeParameter('isBillable', i) as string; + body.bill_by = this.getNodeParameter('billBy', i) as string; + body.budget_by = this.getNodeParameter('budgetBy', i) as string; + + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + Object.assign(body, additionalFields); + + const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint, body); + returnData.push(responseData); + + } else if (operation === 'update') { + // ---------------------------------- + // update + // ---------------------------------- + + requestMethod = 'PATCH'; + const id = this.getNodeParameter('id', i) as string; + endpoint = `projects/${id}`; + + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + + Object.assign(body, updateFields); + const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint, body); + returnData.push(responseData); + + } else if (operation === 'delete') { + // ---------------------------------- + // delete + // ---------------------------------- + + requestMethod = 'DELETE'; + const id = this.getNodeParameter('id', i) as string; + endpoint = `projects/${id}`; + + const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint); + returnData.push(responseData); + } else { + throw new NodeOperationError(this.getNode(), `The resource "${resource}" is not known!`); + } + } else if (resource === 'user') { + if (operation === 'get') { + // ---------------------------------- + // get + // ---------------------------------- + + requestMethod = 'GET'; + const id = this.getNodeParameter('id', i) as string; + + endpoint = `users/${id}`; + + const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint); + returnData.push(responseData); + + } else if (operation === 'getAll') { + // ---------------------------------- + // getAll + // ---------------------------------- + + const responseData: IDataObject[] = await getAllResource.call(this, 'users', i); + returnData.push.apply(returnData, responseData); + + } else if (operation === 'me') { + // ---------------------------------- + // me + // ---------------------------------- + + requestMethod = 'GET'; + + endpoint = `users/me`; + + const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint); + returnData.push(responseData); + + } else if (operation === 'create') { + // ---------------------------------- + // create + // ---------------------------------- + + requestMethod = 'POST'; + endpoint = 'users'; + + body.first_name = this.getNodeParameter('firstName', i) as string; + body.last_name = this.getNodeParameter('lastName', i) as string; + body.email = this.getNodeParameter('email', i) as string; + + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + Object.assign(body, additionalFields); + + const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint, body); + returnData.push(responseData); + + } else if (operation === 'update') { + // ---------------------------------- + // update + // ---------------------------------- + + requestMethod = 'PATCH'; + const id = this.getNodeParameter('id', i) as string; + endpoint = `users/${id}`; + + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + Object.assign(qs, updateFields); + + const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint, body); + returnData.push(responseData); + + } else if (operation === 'delete') { + // ---------------------------------- + // delete + // ---------------------------------- + + requestMethod = 'DELETE'; + const id = this.getNodeParameter('id', i) as string; + endpoint = `users/${id}`; + + const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint); + returnData.push(responseData); + } else { + throw new NodeOperationError(this.getNode(), `The resource "${resource}" is not known!`); + } + } else if (resource === 'contact') { + if (operation === 'get') { + // ---------------------------------- + // get + // ---------------------------------- + + requestMethod = 'GET'; + const id = this.getNodeParameter('id', i) as string; + + endpoint = `contacts/${id}`; + + const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint); + returnData.push(responseData); + + } else if (operation === 'getAll') { + // ---------------------------------- + // getAll + // ---------------------------------- + + const responseData: IDataObject[] = await getAllResource.call(this, 'contacts', i); + returnData.push.apply(returnData, responseData); + + } else if (operation === 'create') { + // ---------------------------------- + // create + // ---------------------------------- + + requestMethod = 'POST'; + endpoint = 'contacts'; + + body.client_id = this.getNodeParameter('clientId', i) as string; + body.first_name = this.getNodeParameter('firstName', i) as string; + + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + Object.assign(body, additionalFields); + + const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint, body); + returnData.push(responseData); + + } else if (operation === 'update') { + // ---------------------------------- + // update + // ---------------------------------- + + requestMethod = 'PATCH'; + const id = this.getNodeParameter('id', i) as string; + endpoint = `contacts/${id}`; + + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + Object.assign(qs, updateFields); + + const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint, body); + returnData.push(responseData); + + } else if (operation === 'delete') { + // ---------------------------------- + // delete + // ---------------------------------- + + requestMethod = 'DELETE'; + const id = this.getNodeParameter('id', i) as string; + endpoint = `contacts/${id}`; + + const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint); + returnData.push(responseData); + } else { + throw new NodeOperationError(this.getNode(), `The resource "${resource}" is not known!`); + } + } else if (resource === 'company') { + if (operation === 'get') { + // ---------------------------------- + // get + // ---------------------------------- + + requestMethod = 'GET'; + endpoint = `company`; + + const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint); + returnData.push(responseData); + + } else { + throw new NodeOperationError(this.getNode(), `The resource "${resource}" is not known!`); + } + } else if (resource === 'task') { + if (operation === 'get') { + // ---------------------------------- + // get + // ---------------------------------- + + requestMethod = 'GET'; + const id = this.getNodeParameter('id', i) as string; + + endpoint = `tasks/${id}`; + + const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint); + returnData.push(responseData); + + } else if (operation === 'getAll') { + // ---------------------------------- + // getAll + // ---------------------------------- + + const responseData: IDataObject[] = await getAllResource.call(this, 'tasks', i); + returnData.push.apply(returnData, responseData); + + } else if (operation === 'create') { + // ---------------------------------- + // create + // ---------------------------------- + + requestMethod = 'POST'; + endpoint = 'tasks'; + + body.name = this.getNodeParameter('name', i) as string; + + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + Object.assign(body, additionalFields); + + const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint, body); + returnData.push(responseData); + + } else if (operation === 'update') { + // ---------------------------------- + // update + // ---------------------------------- + + requestMethod = 'PATCH'; + const id = this.getNodeParameter('id', i) as string; + endpoint = `tasks/${id}`; + + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + Object.assign(qs, updateFields); + + const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint, body); + returnData.push(responseData); + + } else if (operation === 'delete') { + // ---------------------------------- + // delete + // ---------------------------------- + + requestMethod = 'DELETE'; + const id = this.getNodeParameter('id', i) as string; + endpoint = `tasks/${id}`; + + const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint); + returnData.push(responseData); + } else { + throw new NodeOperationError(this.getNode(), `The resource "${resource}" is not known!`); + } + } else if (resource === 'invoice') { + if (operation === 'get') { + // ---------------------------------- + // get + // ---------------------------------- + + requestMethod = 'GET'; + const id = this.getNodeParameter('id', i) as string; + + endpoint = `invoices/${id}`; + + const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint); + returnData.push(responseData); + + } else if (operation === 'getAll') { + // ---------------------------------- + // getAll + // ---------------------------------- + + const responseData: IDataObject[] = await getAllResource.call(this, 'invoices', i); + returnData.push.apply(returnData, responseData); + + } else if (operation === 'create') { + // ---------------------------------- + // create + // ---------------------------------- + + requestMethod = 'POST'; + endpoint = 'invoices'; + + body.client_id = this.getNodeParameter('clientId', i) as string; + + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + Object.assign(body, additionalFields); + + const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint, body); + returnData.push(responseData); + + } else if (operation === 'update') { + // ---------------------------------- + // update + // ---------------------------------- + + requestMethod = 'PATCH'; + const id = this.getNodeParameter('id', i) as string; + endpoint = `invoices/${id}`; + + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + Object.assign(qs, updateFields); + + const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint, body); + returnData.push(responseData); + + } else if (operation === 'delete') { + // ---------------------------------- + // delete + // ---------------------------------- + + requestMethod = 'DELETE'; + const id = this.getNodeParameter('id', i) as string; + endpoint = `invoices/${id}`; + + const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint); + returnData.push(responseData); + } else { + throw new NodeOperationError(this.getNode(), `The resource "${resource}" is not known!`); + } + } else if (resource === 'expense') { + if (operation === 'get') { + // ---------------------------------- + // get + // ---------------------------------- + + requestMethod = 'GET'; + const id = this.getNodeParameter('id', i) as string; + + endpoint = `expenses/${id}`; + + const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint); + returnData.push(responseData); + + } else if (operation === 'getAll') { + // ---------------------------------- + // getAll + // ---------------------------------- + + const responseData: IDataObject[] = await getAllResource.call(this, 'expenses', i); + returnData.push.apply(returnData, responseData); + + } else if (operation === 'create') { + // ---------------------------------- + // create + // ---------------------------------- + + requestMethod = 'POST'; + endpoint = 'expenses'; + + body.project_id = this.getNodeParameter('projectId', i) as string; + body.expense_category_id = this.getNodeParameter('expenseCategoryId', i) as string; + body.spent_date = this.getNodeParameter('spentDate', i) as string; + + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + Object.assign(body, additionalFields); + + const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint, body); + returnData.push(responseData); + + } else if (operation === 'update') { + // ---------------------------------- + // update + // ---------------------------------- + + requestMethod = 'PATCH'; + const id = this.getNodeParameter('id', i) as string; + endpoint = `expenses/${id}`; + + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + Object.assign(qs, updateFields); + + const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint, body); + returnData.push(responseData); + + } else if (operation === 'delete') { + // ---------------------------------- + // delete + // ---------------------------------- + + requestMethod = 'DELETE'; + const id = this.getNodeParameter('id', i) as string; + endpoint = `expenses/${id}`; + + const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint); + returnData.push(responseData); + } else { + throw new NodeOperationError(this.getNode(), `The resource "${resource}" is not known!`); + } + } else if (resource === 'estimate') { + if (operation === 'get') { + // ---------------------------------- + // get + // ---------------------------------- + + requestMethod = 'GET'; + const id = this.getNodeParameter('id', i) as string; + + endpoint = `estimates/${id}`; + + const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint); + returnData.push(responseData); + + } else if (operation === 'getAll') { + // ---------------------------------- + // getAll + // ---------------------------------- + + const responseData: IDataObject[] = await getAllResource.call(this, 'estimates', i); + returnData.push.apply(returnData, responseData); + + } else if (operation === 'create') { + // ---------------------------------- + // create + // ---------------------------------- + + requestMethod = 'POST'; + endpoint = 'estimates'; + + body.client_id = this.getNodeParameter('clientId', i) as string; + + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + Object.assign(body, additionalFields); + + const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint, body); + returnData.push(responseData); + + } else if (operation === 'update') { + // ---------------------------------- + // update + // ---------------------------------- + + requestMethod = 'PATCH'; + const id = this.getNodeParameter('id', i) as string; + endpoint = `estimates/${id}`; + + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + Object.assign(qs, updateFields); + + const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint, body); + returnData.push(responseData); + + } else if (operation === 'delete') { + // ---------------------------------- + // delete + // ---------------------------------- + + requestMethod = 'DELETE'; + const id = this.getNodeParameter('id', i) as string; + endpoint = `estimates/${id}`; + + const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint); + returnData.push(responseData); + } else { + throw new NodeOperationError(this.getNode(), `The resource "${resource}" is not known!`); + } } else { throw new NodeOperationError(this.getNode(), `The resource "${resource}" is not known!`); } - } else if (resource === 'project') { - if (operation === 'get') { - // ---------------------------------- - // get - // ---------------------------------- - - requestMethod = 'GET'; - const id = this.getNodeParameter('id', i) as string; - - endpoint = `projects/${id}`; - - const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint); - returnData.push(responseData); - - } else if (operation === 'getAll') { - // ---------------------------------- - // getAll - // ---------------------------------- - - const responseData: IDataObject[] = await getAllResource.call(this, 'projects', i); - returnData.push.apply(returnData, responseData); - - } else if (operation === 'create') { - // ---------------------------------- - // create - // ---------------------------------- - - requestMethod = 'POST'; - endpoint = 'projects'; - - body.client_id = this.getNodeParameter('clientId', i) as string; - body.name = this.getNodeParameter('name', i) as string; - body.is_billable = this.getNodeParameter('isBillable', i) as string; - body.bill_by = this.getNodeParameter('billBy', i) as string; - body.budget_by = this.getNodeParameter('budgetBy', i) as string; - - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - Object.assign(body, additionalFields); - - const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint, body); - returnData.push(responseData); - - } else if (operation === 'update') { - // ---------------------------------- - // update - // ---------------------------------- - - requestMethod = 'PATCH'; - const id = this.getNodeParameter('id', i) as string; - endpoint = `projects/${id}`; - - const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; - - Object.assign(body, updateFields); - const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint, body); - returnData.push(responseData); - - } else if (operation === 'delete') { - // ---------------------------------- - // delete - // ---------------------------------- - - requestMethod = 'DELETE'; - const id = this.getNodeParameter('id', i) as string; - endpoint = `projects/${id}`; - - const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint); - returnData.push(responseData); - } else { - throw new NodeOperationError(this.getNode(), `The resource "${resource}" is not known!`); + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; } - } else if (resource === 'user') { - if (operation === 'get') { - // ---------------------------------- - // get - // ---------------------------------- - - requestMethod = 'GET'; - const id = this.getNodeParameter('id', i) as string; - - endpoint = `users/${id}`; - - const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint); - returnData.push(responseData); - - } else if (operation === 'getAll') { - // ---------------------------------- - // getAll - // ---------------------------------- - - const responseData: IDataObject[] = await getAllResource.call(this, 'users', i); - returnData.push.apply(returnData, responseData); - - } else if (operation === 'me') { - // ---------------------------------- - // me - // ---------------------------------- - - requestMethod = 'GET'; - - endpoint = `users/me`; - - const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint); - returnData.push(responseData); - - } else if (operation === 'create') { - // ---------------------------------- - // create - // ---------------------------------- - - requestMethod = 'POST'; - endpoint = 'users'; - - body.first_name = this.getNodeParameter('firstName', i) as string; - body.last_name = this.getNodeParameter('lastName', i) as string; - body.email = this.getNodeParameter('email', i) as string; - - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - Object.assign(body, additionalFields); - - const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint, body); - returnData.push(responseData); - - } else if (operation === 'update') { - // ---------------------------------- - // update - // ---------------------------------- - - requestMethod = 'PATCH'; - const id = this.getNodeParameter('id', i) as string; - endpoint = `users/${id}`; - - const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; - Object.assign(qs, updateFields); - - const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint, body); - returnData.push(responseData); - - } else if (operation === 'delete') { - // ---------------------------------- - // delete - // ---------------------------------- - - requestMethod = 'DELETE'; - const id = this.getNodeParameter('id', i) as string; - endpoint = `users/${id}`; - - const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint); - returnData.push(responseData); - } else { - throw new NodeOperationError(this.getNode(), `The resource "${resource}" is not known!`); - } - } else if (resource === 'contact') { - if (operation === 'get') { - // ---------------------------------- - // get - // ---------------------------------- - - requestMethod = 'GET'; - const id = this.getNodeParameter('id', i) as string; - - endpoint = `contacts/${id}`; - - const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint); - returnData.push(responseData); - - } else if (operation === 'getAll') { - // ---------------------------------- - // getAll - // ---------------------------------- - - const responseData: IDataObject[] = await getAllResource.call(this, 'contacts', i); - returnData.push.apply(returnData, responseData); - - } else if (operation === 'create') { - // ---------------------------------- - // create - // ---------------------------------- - - requestMethod = 'POST'; - endpoint = 'contacts'; - - body.client_id = this.getNodeParameter('clientId', i) as string; - body.first_name = this.getNodeParameter('firstName', i) as string; - - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - Object.assign(body, additionalFields); - - const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint, body); - returnData.push(responseData); - - } else if (operation === 'update') { - // ---------------------------------- - // update - // ---------------------------------- - - requestMethod = 'PATCH'; - const id = this.getNodeParameter('id', i) as string; - endpoint = `contacts/${id}`; - - const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; - Object.assign(qs, updateFields); - - const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint, body); - returnData.push(responseData); - - } else if (operation === 'delete') { - // ---------------------------------- - // delete - // ---------------------------------- - - requestMethod = 'DELETE'; - const id = this.getNodeParameter('id', i) as string; - endpoint = `contacts/${id}`; - - const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint); - returnData.push(responseData); - } else { - throw new NodeOperationError(this.getNode(), `The resource "${resource}" is not known!`); - } - } else if (resource === 'company') { - if (operation === 'get') { - // ---------------------------------- - // get - // ---------------------------------- - - requestMethod = 'GET'; - endpoint = `company`; - - const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint); - returnData.push(responseData); - - } else { - throw new NodeOperationError(this.getNode(), `The resource "${resource}" is not known!`); - } - } else if (resource === 'task') { - if (operation === 'get') { - // ---------------------------------- - // get - // ---------------------------------- - - requestMethod = 'GET'; - const id = this.getNodeParameter('id', i) as string; - - endpoint = `tasks/${id}`; - - const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint); - returnData.push(responseData); - - } else if (operation === 'getAll') { - // ---------------------------------- - // getAll - // ---------------------------------- - - const responseData: IDataObject[] = await getAllResource.call(this, 'tasks', i); - returnData.push.apply(returnData, responseData); - - } else if (operation === 'create') { - // ---------------------------------- - // create - // ---------------------------------- - - requestMethod = 'POST'; - endpoint = 'tasks'; - - body.name = this.getNodeParameter('name', i) as string; - - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - Object.assign(body, additionalFields); - - const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint, body); - returnData.push(responseData); - - } else if (operation === 'update') { - // ---------------------------------- - // update - // ---------------------------------- - - requestMethod = 'PATCH'; - const id = this.getNodeParameter('id', i) as string; - endpoint = `tasks/${id}`; - - const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; - Object.assign(qs, updateFields); - - const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint, body); - returnData.push(responseData); - - } else if (operation === 'delete') { - // ---------------------------------- - // delete - // ---------------------------------- - - requestMethod = 'DELETE'; - const id = this.getNodeParameter('id', i) as string; - endpoint = `tasks/${id}`; - - const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint); - returnData.push(responseData); - } else { - throw new NodeOperationError(this.getNode(), `The resource "${resource}" is not known!`); - } - } else if (resource === 'invoice') { - if (operation === 'get') { - // ---------------------------------- - // get - // ---------------------------------- - - requestMethod = 'GET'; - const id = this.getNodeParameter('id', i) as string; - - endpoint = `invoices/${id}`; - - const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint); - returnData.push(responseData); - - } else if (operation === 'getAll') { - // ---------------------------------- - // getAll - // ---------------------------------- - - const responseData: IDataObject[] = await getAllResource.call(this, 'invoices', i); - returnData.push.apply(returnData, responseData); - - } else if (operation === 'create') { - // ---------------------------------- - // create - // ---------------------------------- - - requestMethod = 'POST'; - endpoint = 'invoices'; - - body.client_id = this.getNodeParameter('clientId', i) as string; - - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - Object.assign(body, additionalFields); - - const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint, body); - returnData.push(responseData); - - } else if (operation === 'update') { - // ---------------------------------- - // update - // ---------------------------------- - - requestMethod = 'PATCH'; - const id = this.getNodeParameter('id', i) as string; - endpoint = `invoices/${id}`; - - const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; - Object.assign(qs, updateFields); - - const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint, body); - returnData.push(responseData); - - } else if (operation === 'delete') { - // ---------------------------------- - // delete - // ---------------------------------- - - requestMethod = 'DELETE'; - const id = this.getNodeParameter('id', i) as string; - endpoint = `invoices/${id}`; - - const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint); - returnData.push(responseData); - } else { - throw new NodeOperationError(this.getNode(), `The resource "${resource}" is not known!`); - } - } else if (resource === 'expense') { - if (operation === 'get') { - // ---------------------------------- - // get - // ---------------------------------- - - requestMethod = 'GET'; - const id = this.getNodeParameter('id', i) as string; - - endpoint = `expenses/${id}`; - - const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint); - returnData.push(responseData); - - } else if (operation === 'getAll') { - // ---------------------------------- - // getAll - // ---------------------------------- - - const responseData: IDataObject[] = await getAllResource.call(this, 'expenses', i); - returnData.push.apply(returnData, responseData); - - } else if (operation === 'create') { - // ---------------------------------- - // create - // ---------------------------------- - - requestMethod = 'POST'; - endpoint = 'expenses'; - - body.project_id = this.getNodeParameter('projectId', i) as string; - body.expense_category_id = this.getNodeParameter('expenseCategoryId', i) as string; - body.spent_date = this.getNodeParameter('spentDate', i) as string; - - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - Object.assign(body, additionalFields); - - const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint, body); - returnData.push(responseData); - - } else if (operation === 'update') { - // ---------------------------------- - // update - // ---------------------------------- - - requestMethod = 'PATCH'; - const id = this.getNodeParameter('id', i) as string; - endpoint = `expenses/${id}`; - - const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; - Object.assign(qs, updateFields); - - const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint, body); - returnData.push(responseData); - - } else if (operation === 'delete') { - // ---------------------------------- - // delete - // ---------------------------------- - - requestMethod = 'DELETE'; - const id = this.getNodeParameter('id', i) as string; - endpoint = `expenses/${id}`; - - const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint); - returnData.push(responseData); - } else { - throw new NodeOperationError(this.getNode(), `The resource "${resource}" is not known!`); - } - } else if (resource === 'estimate') { - if (operation === 'get') { - // ---------------------------------- - // get - // ---------------------------------- - - requestMethod = 'GET'; - const id = this.getNodeParameter('id', i) as string; - - endpoint = `estimates/${id}`; - - const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint); - returnData.push(responseData); - - } else if (operation === 'getAll') { - // ---------------------------------- - // getAll - // ---------------------------------- - - const responseData: IDataObject[] = await getAllResource.call(this, 'estimates', i); - returnData.push.apply(returnData, responseData); - - } else if (operation === 'create') { - // ---------------------------------- - // create - // ---------------------------------- - - requestMethod = 'POST'; - endpoint = 'estimates'; - - body.client_id = this.getNodeParameter('clientId', i) as string; - - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - Object.assign(body, additionalFields); - - const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint, body); - returnData.push(responseData); - - } else if (operation === 'update') { - // ---------------------------------- - // update - // ---------------------------------- - - requestMethod = 'PATCH'; - const id = this.getNodeParameter('id', i) as string; - endpoint = `estimates/${id}`; - - const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; - Object.assign(qs, updateFields); - - const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint, body); - returnData.push(responseData); - - } else if (operation === 'delete') { - // ---------------------------------- - // delete - // ---------------------------------- - - requestMethod = 'DELETE'; - const id = this.getNodeParameter('id', i) as string; - endpoint = `estimates/${id}`; - - const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint); - returnData.push(responseData); - } else { - throw new NodeOperationError(this.getNode(), `The resource "${resource}" is not known!`); - } - } else { - throw new NodeOperationError(this.getNode(), `The resource "${resource}" is not known!`); + throw error; } } diff --git a/packages/nodes-base/nodes/HelpScout/HelpScout.node.ts b/packages/nodes-base/nodes/HelpScout/HelpScout.node.ts index b2756f1a68..b2269470c1 100644 --- a/packages/nodes-base/nodes/HelpScout/HelpScout.node.ts +++ b/packages/nodes-base/nodes/HelpScout/HelpScout.node.ts @@ -172,262 +172,270 @@ export class HelpScout implements INodeType { 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 === 'conversation') { - //https://developer.helpscout.com/mailbox-api/endpoints/conversations/create - if (operation === 'create') { - const mailboxId = this.getNodeParameter('mailboxId', i) as number; - const status = this.getNodeParameter('status', i) as string; - const subject = this.getNodeParameter('subject', i) as string; - const type = this.getNodeParameter('type', i) as string; - const resolveData = this.getNodeParameter('resolveData', i) as boolean; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const threads = (this.getNodeParameter('threadsUi', i) as IDataObject).threadsValues as IDataObject[]; - const body: IConversation = { - mailboxId, - status, - subject, - type, - }; - Object.assign(body, additionalFields); - if (additionalFields.customerId) { - body.customer = { - id: additionalFields.customerId, + try { + if (resource === 'conversation') { + //https://developer.helpscout.com/mailbox-api/endpoints/conversations/create + if (operation === 'create') { + const mailboxId = this.getNodeParameter('mailboxId', i) as number; + const status = this.getNodeParameter('status', i) as string; + const subject = this.getNodeParameter('subject', i) as string; + const type = this.getNodeParameter('type', i) as string; + const resolveData = this.getNodeParameter('resolveData', i) as boolean; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const threads = (this.getNodeParameter('threadsUi', i) as IDataObject).threadsValues as IDataObject[]; + const body: IConversation = { + mailboxId, + status, + subject, + type, }; - //@ts-ignore - delete body.customerId; - } - if (additionalFields.customerEmail) { - body.customer = { - email: additionalFields.customerEmail, - }; - //@ts-ignore - delete body.customerEmail; - } - if (body.customer === undefined) { - throw new NodeOperationError(this.getNode(), 'Either customer email or customer ID must be set'); - } - if (threads) { - for (let i = 0; i < threads.length; i++) { - if (threads[i].type === '' || threads[i].text === '') { - throw new NodeOperationError(this.getNode(), 'Chat Threads cannot be empty'); - } - if (threads[i].type !== 'note') { - threads[i].customer = body.customer; - } - } - body.threads = threads; - } - responseData = await helpscoutApiRequest.call(this, 'POST', '/v2/conversations', body, qs, undefined, { resolveWithFullResponse: true }); - const id = responseData.headers['resource-id']; - const uri = responseData.headers.location; - if (resolveData) { - responseData = await helpscoutApiRequest.call(this, 'GET', '', {}, {}, uri); - } else { - responseData = { - id, - uri, - }; - } - } - //https://developer.helpscout.com/mailbox-api/endpoints/conversations/delete - if (operation === 'delete') { - const conversationId = this.getNodeParameter('conversationId', i) as string; - responseData = await helpscoutApiRequest.call(this, 'DELETE', `/v2/conversations/${conversationId}`); - responseData = { success: true }; - } - //https://developer.helpscout.com/mailbox-api/endpoints/conversations/get - if (operation === 'get') { - const conversationId = this.getNodeParameter('conversationId', i) as string; - responseData = await helpscoutApiRequest.call(this, 'GET', `/v2/conversations/${conversationId}`); - } - //https://developer.helpscout.com/mailbox-api/endpoints/conversations/list - if (operation === 'getAll') { - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - const options = this.getNodeParameter('options', i) as IDataObject; - Object.assign(qs, options); - if (returnAll) { - responseData = await helpscoutApiRequestAllItems.call(this, '_embedded.conversations', 'GET', '/v2/conversations', {}, qs); - } else { - qs.limit = this.getNodeParameter('limit', i) as number; - responseData = await helpscoutApiRequestAllItems.call(this, '_embedded.conversations', 'GET', '/v2/conversations', {}, qs); - responseData = responseData.splice(0, qs.limit); - } - } - } - if (resource === 'customer') { - //https://developer.helpscout.com/mailbox-api/endpoints/customers/create - if (operation === 'create') { - const resolveData = this.getNodeParameter('resolveData', i) as boolean; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const chats = (this.getNodeParameter('chatsUi', i) as IDataObject).chatsValues as IDataObject[]; - const address = (this.getNodeParameter('addressUi', i) as IDataObject).addressValue as IDataObject; - const emails = (this.getNodeParameter('emailsUi', i) as IDataObject).emailsValues as IDataObject[]; - const phones = (this.getNodeParameter('phonesUi', i) as IDataObject).phonesValues as IDataObject[]; - const socialProfiles = (this.getNodeParameter('socialProfilesUi', i) as IDataObject).socialProfilesValues as IDataObject[]; - const websites = (this.getNodeParameter('websitesUi', i) as IDataObject).websitesValues as IDataObject[]; - let body: ICustomer = {}; - body = Object.assign({}, additionalFields); - if (body.age) { - body.age = body.age.toString(); - } - if (chats) { - body.chats = chats; - } - if (address) { - body.address = address; - body.address.lines = [address.line1, address.line2]; - } - if (emails) { - body.emails = emails; - } - if (phones) { - body.phones = phones; - } - if (socialProfiles) { - body.socialProfiles = socialProfiles; - } - if (websites) { - body.websites = websites; - } - if (Object.keys(body).length === 0) { - throw new NodeOperationError(this.getNode(), 'You have to set at least one field'); - } - responseData = await helpscoutApiRequest.call(this, 'POST', '/v2/customers', body, qs, undefined, { resolveWithFullResponse: true }); - const id = responseData.headers['resource-id']; - const uri = responseData.headers.location; - if (resolveData) { - responseData = await helpscoutApiRequest.call(this, 'GET', '', {}, {}, uri); - } else { - responseData = { - id, - uri, - }; - } - } - //https://developer.helpscout.com/mailbox-api/endpoints/customer_properties/list - if (operation === 'properties') { - responseData = await helpscoutApiRequestAllItems.call(this, '_embedded.customer-properties', 'GET', '/v2/customer-properties', {}, qs); - } - //https://developer.helpscout.com/mailbox-api/endpoints/customers/get - if (operation === 'get') { - const customerId = this.getNodeParameter('customerId', i) as string; - responseData = await helpscoutApiRequest.call(this, 'GET', `/v2/customers/${customerId}`); - } - //https://developer.helpscout.com/mailbox-api/endpoints/customers/list - if (operation === 'getAll') { - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - const options = this.getNodeParameter('options', i) as IDataObject; - Object.assign(qs, options); - if (returnAll) { - responseData = await helpscoutApiRequestAllItems.call(this, '_embedded.customers', 'GET', '/v2/customers', {}, qs); - } else { - qs.limit = this.getNodeParameter('limit', i) as number; - responseData = await helpscoutApiRequestAllItems.call(this, '_embedded.customers', 'GET', '/v2/customers', {}, qs); - responseData = responseData.splice(0, qs.limit); - } - } - //https://developer.helpscout.com/mailbox-api/endpoints/customers/overwrite/ - if (operation === 'update') { - const customerId = this.getNodeParameter('customerId', i) as string; - const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; - let body: ICustomer = {}; - body = Object.assign({}, updateFields); - if (body.age) { - body.age = body.age.toString(); - } - if (Object.keys(body).length === 0) { - throw new NodeOperationError(this.getNode(), 'You have to set at least one field'); - } - responseData = await helpscoutApiRequest.call(this, 'PUT', `/v2/customers/${customerId}`, body, qs, undefined, { resolveWithFullResponse: true }); - responseData = { success: true }; - } - } - if (resource === 'mailbox') { - //https://developer.helpscout.com/mailbox-api/endpoints/mailboxes/get - if (operation === 'get') { - const mailboxId = this.getNodeParameter('mailboxId', i) as string; - responseData = await helpscoutApiRequest.call(this, 'GET', `/v2/mailboxes/${mailboxId}`, {}, qs); - } - //https://developer.helpscout.com/mailbox-api/endpoints/mailboxes/list - if (operation === 'getAll') { - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - if (returnAll) { - responseData = await helpscoutApiRequestAllItems.call(this, '_embedded.mailboxes', 'GET', '/v2/mailboxes', {}, qs); - } else { - qs.limit = this.getNodeParameter('limit', i) as number; - responseData = await helpscoutApiRequestAllItems.call(this, '_embedded.mailboxes', 'GET', '/v2/mailboxes', {}, qs); - responseData = responseData.splice(0, qs.limit); - } - } - } - if (resource === 'thread') { - //https://developer.helpscout.com/mailbox-api/endpoints/conversations/threads/chat - if (operation === 'create') { - const conversationId = this.getNodeParameter('conversationId', i) as string; - const type = this.getNodeParameter('type', i) as string; - const text = this.getNodeParameter('text', i) as string; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const attachments = this.getNodeParameter('attachmentsUi', i) as IDataObject; - const body: IThread = { - text, - attachments: [], - }; - Object.assign(body, additionalFields); - if (additionalFields.customerId) { - body.customer = { - id: additionalFields.customerId, - }; - //@ts-ignore - delete body.customerId; - } - if (additionalFields.customerEmail) { - body.customer = { - email: additionalFields.customerEmail, - }; - //@ts-ignore - delete body.customerEmail; - } - if (body.customer === undefined) { - throw new NodeOperationError(this.getNode(), 'Either customer email or customer ID must be set'); - } - if (attachments) { - if (attachments.attachmentsValues - && (attachments.attachmentsValues as IDataObject[]).length !== 0) { - body.attachments?.push.apply(body.attachments, attachments.attachmentsValues as IAttachment[]); - } - if (attachments.attachmentsBinary - && (attachments.attachmentsBinary as IDataObject[]).length !== 0 - && items[i].binary) { - const mapFunction = (value: IDataObject): IAttachment => { - const binaryProperty = (items[i].binary as IBinaryKeyData)[value.property as string]; - if (binaryProperty) { - return { - fileName: binaryProperty.fileName || 'unknown', - data: binaryProperty.data, - mimeType: binaryProperty.mimeType, - }; - } else { - throw new NodeOperationError(this.getNode(), `Binary property ${value.property} does not exist on input`); - } + Object.assign(body, additionalFields); + if (additionalFields.customerId) { + body.customer = { + id: additionalFields.customerId, + }; + //@ts-ignore + delete body.customerId; + } + if (additionalFields.customerEmail) { + body.customer = { + email: additionalFields.customerEmail, + }; + //@ts-ignore + delete body.customerEmail; + } + if (body.customer === undefined) { + throw new NodeOperationError(this.getNode(), 'Either customer email or customer ID must be set'); + } + if (threads) { + for (let i = 0; i < threads.length; i++) { + if (threads[i].type === '' || threads[i].text === '') { + throw new NodeOperationError(this.getNode(), 'Chat Threads cannot be empty'); + } + if (threads[i].type !== 'note') { + threads[i].customer = body.customer; + } + } + body.threads = threads; + } + responseData = await helpscoutApiRequest.call(this, 'POST', '/v2/conversations', body, qs, undefined, { resolveWithFullResponse: true }); + const id = responseData.headers['resource-id']; + const uri = responseData.headers.location; + if (resolveData) { + responseData = await helpscoutApiRequest.call(this, 'GET', '', {}, {}, uri); + } else { + responseData = { + id, + uri, }; - body.attachments?.push.apply(body.attachments, (attachments.attachmentsBinary as IDataObject[]).map(mapFunction) as IAttachment[]); } } - responseData = await helpscoutApiRequest.call(this, 'POST', `/v2/conversations/${conversationId}/chats`, body); - responseData = { success: true }; - } - //https://developer.helpscout.com/mailbox-api/endpoints/conversations/threads/list - if (operation === 'getAll') { - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - const conversationId = this.getNodeParameter('conversationId', i) as string; - if (returnAll) { - responseData = await helpscoutApiRequestAllItems.call(this, '_embedded.threads', 'GET', `/v2/conversations/${conversationId}/threads`); - } else { - qs.limit = this.getNodeParameter('limit', i) as number; - responseData = await helpscoutApiRequestAllItems.call(this, '_embedded.threads', 'GET', `/v2/conversations/${conversationId}/threads`, {}, qs); - responseData = responseData.splice(0, qs.limit); + //https://developer.helpscout.com/mailbox-api/endpoints/conversations/delete + if (operation === 'delete') { + const conversationId = this.getNodeParameter('conversationId', i) as string; + responseData = await helpscoutApiRequest.call(this, 'DELETE', `/v2/conversations/${conversationId}`); + responseData = { success: true }; + } + //https://developer.helpscout.com/mailbox-api/endpoints/conversations/get + if (operation === 'get') { + const conversationId = this.getNodeParameter('conversationId', i) as string; + responseData = await helpscoutApiRequest.call(this, 'GET', `/v2/conversations/${conversationId}`); + } + //https://developer.helpscout.com/mailbox-api/endpoints/conversations/list + if (operation === 'getAll') { + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + const options = this.getNodeParameter('options', i) as IDataObject; + Object.assign(qs, options); + if (returnAll) { + responseData = await helpscoutApiRequestAllItems.call(this, '_embedded.conversations', 'GET', '/v2/conversations', {}, qs); + } else { + qs.limit = this.getNodeParameter('limit', i) as number; + responseData = await helpscoutApiRequestAllItems.call(this, '_embedded.conversations', 'GET', '/v2/conversations', {}, qs); + responseData = responseData.splice(0, qs.limit); + } } } + if (resource === 'customer') { + //https://developer.helpscout.com/mailbox-api/endpoints/customers/create + if (operation === 'create') { + const resolveData = this.getNodeParameter('resolveData', i) as boolean; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const chats = (this.getNodeParameter('chatsUi', i) as IDataObject).chatsValues as IDataObject[]; + const address = (this.getNodeParameter('addressUi', i) as IDataObject).addressValue as IDataObject; + const emails = (this.getNodeParameter('emailsUi', i) as IDataObject).emailsValues as IDataObject[]; + const phones = (this.getNodeParameter('phonesUi', i) as IDataObject).phonesValues as IDataObject[]; + const socialProfiles = (this.getNodeParameter('socialProfilesUi', i) as IDataObject).socialProfilesValues as IDataObject[]; + const websites = (this.getNodeParameter('websitesUi', i) as IDataObject).websitesValues as IDataObject[]; + let body: ICustomer = {}; + body = Object.assign({}, additionalFields); + if (body.age) { + body.age = body.age.toString(); + } + if (chats) { + body.chats = chats; + } + if (address) { + body.address = address; + body.address.lines = [address.line1, address.line2]; + } + if (emails) { + body.emails = emails; + } + if (phones) { + body.phones = phones; + } + if (socialProfiles) { + body.socialProfiles = socialProfiles; + } + if (websites) { + body.websites = websites; + } + if (Object.keys(body).length === 0) { + throw new NodeOperationError(this.getNode(), 'You have to set at least one field'); + } + responseData = await helpscoutApiRequest.call(this, 'POST', '/v2/customers', body, qs, undefined, { resolveWithFullResponse: true }); + const id = responseData.headers['resource-id']; + const uri = responseData.headers.location; + if (resolveData) { + responseData = await helpscoutApiRequest.call(this, 'GET', '', {}, {}, uri); + } else { + responseData = { + id, + uri, + }; + } + } + //https://developer.helpscout.com/mailbox-api/endpoints/customer_properties/list + if (operation === 'properties') { + responseData = await helpscoutApiRequestAllItems.call(this, '_embedded.customer-properties', 'GET', '/v2/customer-properties', {}, qs); + } + //https://developer.helpscout.com/mailbox-api/endpoints/customers/get + if (operation === 'get') { + const customerId = this.getNodeParameter('customerId', i) as string; + responseData = await helpscoutApiRequest.call(this, 'GET', `/v2/customers/${customerId}`); + } + //https://developer.helpscout.com/mailbox-api/endpoints/customers/list + if (operation === 'getAll') { + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + const options = this.getNodeParameter('options', i) as IDataObject; + Object.assign(qs, options); + if (returnAll) { + responseData = await helpscoutApiRequestAllItems.call(this, '_embedded.customers', 'GET', '/v2/customers', {}, qs); + } else { + qs.limit = this.getNodeParameter('limit', i) as number; + responseData = await helpscoutApiRequestAllItems.call(this, '_embedded.customers', 'GET', '/v2/customers', {}, qs); + responseData = responseData.splice(0, qs.limit); + } + } + //https://developer.helpscout.com/mailbox-api/endpoints/customers/overwrite/ + if (operation === 'update') { + const customerId = this.getNodeParameter('customerId', i) as string; + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + let body: ICustomer = {}; + body = Object.assign({}, updateFields); + if (body.age) { + body.age = body.age.toString(); + } + if (Object.keys(body).length === 0) { + throw new NodeOperationError(this.getNode(), 'You have to set at least one field'); + } + responseData = await helpscoutApiRequest.call(this, 'PUT', `/v2/customers/${customerId}`, body, qs, undefined, { resolveWithFullResponse: true }); + responseData = { success: true }; + } + } + if (resource === 'mailbox') { + //https://developer.helpscout.com/mailbox-api/endpoints/mailboxes/get + if (operation === 'get') { + const mailboxId = this.getNodeParameter('mailboxId', i) as string; + responseData = await helpscoutApiRequest.call(this, 'GET', `/v2/mailboxes/${mailboxId}`, {}, qs); + } + //https://developer.helpscout.com/mailbox-api/endpoints/mailboxes/list + if (operation === 'getAll') { + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + if (returnAll) { + responseData = await helpscoutApiRequestAllItems.call(this, '_embedded.mailboxes', 'GET', '/v2/mailboxes', {}, qs); + } else { + qs.limit = this.getNodeParameter('limit', i) as number; + responseData = await helpscoutApiRequestAllItems.call(this, '_embedded.mailboxes', 'GET', '/v2/mailboxes', {}, qs); + responseData = responseData.splice(0, qs.limit); + } + } + } + if (resource === 'thread') { + //https://developer.helpscout.com/mailbox-api/endpoints/conversations/threads/chat + if (operation === 'create') { + const conversationId = this.getNodeParameter('conversationId', i) as string; + const type = this.getNodeParameter('type', i) as string; + const text = this.getNodeParameter('text', i) as string; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const attachments = this.getNodeParameter('attachmentsUi', i) as IDataObject; + const body: IThread = { + text, + attachments: [], + }; + Object.assign(body, additionalFields); + if (additionalFields.customerId) { + body.customer = { + id: additionalFields.customerId, + }; + //@ts-ignore + delete body.customerId; + } + if (additionalFields.customerEmail) { + body.customer = { + email: additionalFields.customerEmail, + }; + //@ts-ignore + delete body.customerEmail; + } + if (body.customer === undefined) { + throw new NodeOperationError(this.getNode(), 'Either customer email or customer ID must be set'); + } + if (attachments) { + if (attachments.attachmentsValues + && (attachments.attachmentsValues as IDataObject[]).length !== 0) { + body.attachments?.push.apply(body.attachments, attachments.attachmentsValues as IAttachment[]); + } + if (attachments.attachmentsBinary + && (attachments.attachmentsBinary as IDataObject[]).length !== 0 + && items[i].binary) { + const mapFunction = (value: IDataObject): IAttachment => { + const binaryProperty = (items[i].binary as IBinaryKeyData)[value.property as string]; + if (binaryProperty) { + return { + fileName: binaryProperty.fileName || 'unknown', + data: binaryProperty.data, + mimeType: binaryProperty.mimeType, + }; + } else { + throw new NodeOperationError(this.getNode(), `Binary property ${value.property} does not exist on input`); + } + }; + body.attachments?.push.apply(body.attachments, (attachments.attachmentsBinary as IDataObject[]).map(mapFunction) as IAttachment[]); + } + } + responseData = await helpscoutApiRequest.call(this, 'POST', `/v2/conversations/${conversationId}/chats`, body); + responseData = { success: true }; + } + //https://developer.helpscout.com/mailbox-api/endpoints/conversations/threads/list + if (operation === 'getAll') { + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + const conversationId = this.getNodeParameter('conversationId', i) as string; + if (returnAll) { + responseData = await helpscoutApiRequestAllItems.call(this, '_embedded.threads', 'GET', `/v2/conversations/${conversationId}/threads`); + } else { + qs.limit = this.getNodeParameter('limit', i) as number; + responseData = await helpscoutApiRequestAllItems.call(this, '_embedded.threads', 'GET', `/v2/conversations/${conversationId}/threads`, {}, qs); + responseData = responseData.splice(0, qs.limit); + } + } + } + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } if (Array.isArray(responseData)) { returnData.push.apply(returnData, responseData as IDataObject[]); diff --git a/packages/nodes-base/nodes/HtmlExtract/HtmlExtract.node.ts b/packages/nodes-base/nodes/HtmlExtract/HtmlExtract.node.ts index 0e5eb5e04c..1285a141f0 100644 --- a/packages/nodes-base/nodes/HtmlExtract/HtmlExtract.node.ts +++ b/packages/nodes-base/nodes/HtmlExtract/HtmlExtract.node.ts @@ -219,59 +219,67 @@ export class HtmlExtract implements INodeType { let item: INodeExecutionData; for (let itemIndex = 0; itemIndex < items.length; itemIndex++) { - const dataPropertyName = this.getNodeParameter('dataPropertyName', itemIndex) as string; - const extractionValues = this.getNodeParameter('extractionValues', itemIndex) as IDataObject; - const options = this.getNodeParameter('options', itemIndex, {}) as IDataObject; - const sourceData = this.getNodeParameter('sourceData', itemIndex) as string; + try { + const dataPropertyName = this.getNodeParameter('dataPropertyName', itemIndex) as string; + const extractionValues = this.getNodeParameter('extractionValues', itemIndex) as IDataObject; + const options = this.getNodeParameter('options', itemIndex, {}) as IDataObject; + const sourceData = this.getNodeParameter('sourceData', itemIndex) as string; - item = items[itemIndex]; + item = items[itemIndex]; - let htmlArray: string[] | string = []; - if (sourceData === 'json') { - if (item.json[dataPropertyName] === undefined) { - throw new NodeOperationError(this.getNode(), `No property named "${dataPropertyName}" exists!`); - } - htmlArray = item.json[dataPropertyName] as string; - } else { - if (item.binary === undefined) { - throw new NodeOperationError(this.getNode(), `No item does not contain binary data!`); - } - if (item.binary[dataPropertyName] === undefined) { - throw new NodeOperationError(this.getNode(), `No property named "${dataPropertyName}" exists!`); - } - htmlArray = Buffer.from(item.binary[dataPropertyName].data, 'base64').toString('utf8'); - } - - // Convert it always to array that it works with a string or an array of strings - if (!Array.isArray(htmlArray)) { - htmlArray = [htmlArray]; - } - - for (const html of htmlArray as string[]) { - const $ = cheerio.load(html); - - const newItem: INodeExecutionData = { - json: {}, - }; - - // Itterate over all the defined values which should be extracted - let htmlElement; - for (const valueData of extractionValues.values as IValueData[]) { - htmlElement = $(valueData.cssSelector); - - if (valueData.returnArray === true) { - // An array should be returned so itterate over one - // value at a time - newItem.json[valueData.key as string] = []; - htmlElement.each((i, el) => { - (newItem.json[valueData.key as string] as Array).push(getValue($(el), valueData, options)); - }); - } else { - // One single value should be returned - newItem.json[valueData.key as string] = getValue(htmlElement, valueData, options); + let htmlArray: string[] | string = []; + if (sourceData === 'json') { + if (item.json[dataPropertyName] === undefined) { + throw new NodeOperationError(this.getNode(), `No property named "${dataPropertyName}" exists!`); } + htmlArray = item.json[dataPropertyName] as string; + } else { + if (item.binary === undefined) { + throw new NodeOperationError(this.getNode(), `No item does not contain binary data!`); + } + if (item.binary[dataPropertyName] === undefined) { + throw new NodeOperationError(this.getNode(), `No property named "${dataPropertyName}" exists!`); + } + htmlArray = Buffer.from(item.binary[dataPropertyName].data, 'base64').toString('utf8'); } - returnData.push(newItem); + + // Convert it always to array that it works with a string or an array of strings + if (!Array.isArray(htmlArray)) { + htmlArray = [htmlArray]; + } + + for (const html of htmlArray as string[]) { + const $ = cheerio.load(html); + + const newItem: INodeExecutionData = { + json: {}, + }; + + // Itterate over all the defined values which should be extracted + let htmlElement; + for (const valueData of extractionValues.values as IValueData[]) { + htmlElement = $(valueData.cssSelector); + + if (valueData.returnArray === true) { + // An array should be returned so itterate over one + // value at a time + newItem.json[valueData.key as string] = []; + htmlElement.each((i, el) => { + (newItem.json[valueData.key as string] as Array).push(getValue($(el), valueData, options)); + }); + } else { + // One single value should be returned + newItem.json[valueData.key as string] = getValue(htmlElement, valueData, options); + } + } + returnData.push(newItem); + } + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ json: { error: error.message } }); + continue; + } + throw error; } } diff --git a/packages/nodes-base/nodes/Hubspot/Hubspot.node.ts b/packages/nodes-base/nodes/Hubspot/Hubspot.node.ts index 3c9d57e98c..c6659f53e0 100644 --- a/packages/nodes-base/nodes/Hubspot/Hubspot.node.ts +++ b/packages/nodes-base/nodes/Hubspot/Hubspot.node.ts @@ -874,1538 +874,1554 @@ export class Hubspot implements INodeType { //https://legacydocs.hubspot.com/docs/methods/lists/contact-lists-overview if (resource === 'contactList') { - //https://legacydocs.hubspot.com/docs/methods/lists/add_contact_to_list - if (operation === 'add') { - const listId = this.getNodeParameter('listId', 0) as string; - const by = this.getNodeParameter('by', 0) as string; - const body: { [key: string]: [] } = { emails: [], vids: [] }; - for (let i = 0; i < length; i++) { - if (by === 'id') { + try { + //https://legacydocs.hubspot.com/docs/methods/lists/add_contact_to_list + if (operation === 'add') { + const listId = this.getNodeParameter('listId', 0) as string; + const by = this.getNodeParameter('by', 0) as string; + const body: { [key: string]: [] } = { emails: [], vids: [] }; + for (let i = 0; i < length; i++) { + if (by === 'id') { + const id = this.getNodeParameter('id', i) as string; + body.vids.push(parseInt(id, 10) as never); + } else { + const email = this.getNodeParameter('email', i) as string; + body.emails.push(email as never); + } + } + responseData = await hubspotApiRequest.call(this, 'POST', `/contacts/v1/lists/${listId}/add`, body); + returnData.push(responseData); + } + //https://legacydocs.hubspot.com/docs/methods/lists/remove_contact_from_list + if (operation === 'remove') { + const listId = this.getNodeParameter('listId', 0) as string; + const body: { [key: string]: [] } = { vids: [] }; + for (let i = 0; i < length; i++) { const id = this.getNodeParameter('id', i) as string; body.vids.push(parseInt(id, 10) as never); - } else { - const email = this.getNodeParameter('email', i) as string; - body.emails.push(email as never); } + responseData = await hubspotApiRequest.call(this, 'POST', `/contacts/v1/lists/${listId}/remove`, body); + returnData.push(responseData); } - responseData = await hubspotApiRequest.call(this, 'POST', `/contacts/v1/lists/${listId}/add`, body); - returnData.push(responseData); - } - //https://legacydocs.hubspot.com/docs/methods/lists/remove_contact_from_list - if (operation === 'remove') { - const listId = this.getNodeParameter('listId', 0) as string; - const body: { [key: string]: [] } = { vids: [] }; - for (let i = 0; i < length; i++) { - const id = this.getNodeParameter('id', i) as string; - body.vids.push(parseInt(id, 10) as never); + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + } else { + throw error; } - responseData = await hubspotApiRequest.call(this, 'POST', `/contacts/v1/lists/${listId}/remove`, body); - returnData.push(responseData); } } else { for (let i = 0; i < length; i++) { + try { //https://developers.hubspot.com/docs/methods/contacts/create_or_update - if (resource === 'contact') { - //https://developers.hubspot.com/docs/methods/companies/create_company - if (operation === 'upsert') { - const email = this.getNodeParameter('email', i) as string; - const resolveData = this.getNodeParameter('resolveData', i) as boolean; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const body: IDataObject[] = []; - if (additionalFields.annualRevenue) { - body.push({ - property: 'annualrevenue', - value: (additionalFields.annualRevenue as number).toString(), - }); - } - if (additionalFields.city) { - body.push({ - property: 'city', - value: additionalFields.city, - }); - } - if (additionalFields.clickedFacebookAd) { - body.push({ - property: 'hs_facebook_ad_clicked', - value: additionalFields.clickedFacebookAd, - }); - } - if (additionalFields.closeDate) { - body.push({ - property: 'closedate', - value: new Date(additionalFields.closeDate as string).getTime(), - }); - } - if (additionalFields.companyName) { - body.push({ - property: 'company', - value: additionalFields.companyName, - }); - } - if (additionalFields.companySize) { - body.push({ - property: 'company_size', - value: additionalFields.companySize, - }); - } - if (additionalFields.description) { - body.push({ - property: 'description', - value: additionalFields.description, - }); - } - if (additionalFields.contactOwner) { - body.push({ - property: 'hubspot_owner_id', - value: additionalFields.contactOwner, - }); - } - if (additionalFields.country) { - body.push({ - property: 'country', - value: additionalFields.country, - }); - } - if (additionalFields.dateOfBirth) { - body.push({ - property: 'date_of_birth', - value: additionalFields.dateOfBirth, - }); - } - if (additionalFields.degree) { - body.push({ - property: 'degree', - value: additionalFields.degree, - }); - } - if (additionalFields.facebookClickId) { - body.push({ - property: 'hs_facebook_click_id', - value: additionalFields.facebookClickId, - }); - } - if (additionalFields.faxNumber) { - body.push({ - property: 'fax', - value: additionalFields.faxNumber, - }); - } - if (additionalFields.fieldOfStudy) { - body.push({ - property: 'field_of_study', - value: additionalFields.fieldOfStudy, - }); - } - if (additionalFields.firstName) { - body.push({ - property: 'firstname', - value: additionalFields.firstName, - }); - } - if (additionalFields.gender) { - body.push({ - property: 'gender', - value: additionalFields.gender, - }); - } - if (additionalFields.googleAdClickId) { - body.push({ - property: 'hs_google_click_id', - value: additionalFields.googleAdClickId, - }); - } - if (additionalFields.graduationDate) { - body.push({ - property: 'graduation_date', - value: additionalFields.graduationDate, - }); - } - if (additionalFields.industry) { - body.push({ - property: 'industry', - value: additionalFields.industry, - }); - } - if (additionalFields.jobFunction) { - body.push({ - property: 'job_function', - value: additionalFields.jobFunction, - }); - } - if (additionalFields.jobTitle) { - body.push({ - property: 'jobtitle', - value: additionalFields.jobTitle, - }); - } - if (additionalFields.lastName) { - body.push({ - property: 'lastname', - value: additionalFields.lastName, - }); - } - if (additionalFields.leadStatus) { - body.push({ - property: 'hs_lead_status', - value: additionalFields.leadStatus, - }); - } - if (additionalFields.processingContactData) { - body.push({ - property: 'hs_legal_basis', - value: additionalFields.processingContactData, - }); - } - if (additionalFields.lifeCycleStage) { - body.push({ - property: 'lifecyclestage', - value: additionalFields.lifeCycleStage, - }); - } - if (additionalFields.maritalStatus) { - body.push({ - property: 'marital_status', - value: additionalFields.maritalStatus, - }); - } - if (additionalFields.membershipNote) { - body.push({ - property: 'hs_content_membership_notes', - value: additionalFields.membershipNote, - }); - } - if (additionalFields.message) { - body.push({ - property: 'message', - value: additionalFields.message, - }); - } - if (additionalFields.mobilePhoneNumber) { - body.push({ - property: 'mobilephone', - value: additionalFields.mobilePhoneNumber, - }); - } - if (additionalFields.numberOfEmployees) { - body.push({ - property: 'numemployees', - value: additionalFields.numberOfEmployees, - }); - } - if (additionalFields.originalSource) { - body.push({ - property: 'hs_analytics_source', - value: additionalFields.originalSource, - }); - } - if (additionalFields.phoneNumber) { - body.push({ - property: 'phone', - value: additionalFields.phoneNumber, - }); - } - if (additionalFields.postalCode) { - body.push({ - property: 'zip', - value: additionalFields.postalCode, - }); - } - if (additionalFields.prefferedLanguage) { - body.push({ - property: 'hs_language', - value: additionalFields.prefferedLanguage, - }); - } - if (additionalFields.relationshipStatus) { - body.push({ - property: 'relationship_status', - value: additionalFields.relationshipStatus, - }); - } - if (additionalFields.salutation) { - body.push({ - property: 'salutation', - value: additionalFields.salutation, - }); - } - if (additionalFields.school) { - body.push({ - property: 'school', - value: additionalFields.school, - }); - } - if (additionalFields.seniority) { - body.push({ - property: 'seniority', - value: additionalFields.seniority, - }); - } - if (additionalFields.startDate) { - body.push({ - property: 'start_date', - value: additionalFields.startDate, - }); - } - if (additionalFields.stateRegion) { - body.push({ - property: 'state', - value: additionalFields.stateRegion, - }); - } - if (additionalFields.status) { - body.push({ - property: 'hs_content_membership_status', - value: additionalFields.status, - }); - } - if (additionalFields.streetAddress) { - body.push({ - property: 'address', - value: additionalFields.streetAddress, - }); - } - if (additionalFields.twitterUsername) { - body.push({ - property: 'twitterhandle', - value: additionalFields.twitterUsername, - }); - } - if (additionalFields.websiteUrl) { - body.push({ - property: 'website', - value: additionalFields.websiteUrl, - }); - } - if (additionalFields.workEmail) { - body.push({ - property: 'work_email', - value: additionalFields.workEmail, - }); - } + if (resource === 'contact') { + //https://developers.hubspot.com/docs/methods/companies/create_company + if (operation === 'upsert') { + const email = this.getNodeParameter('email', i) as string; + const resolveData = this.getNodeParameter('resolveData', i) as boolean; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const body: IDataObject[] = []; + if (additionalFields.annualRevenue) { + body.push({ + property: 'annualrevenue', + value: (additionalFields.annualRevenue as number).toString(), + }); + } + if (additionalFields.city) { + body.push({ + property: 'city', + value: additionalFields.city, + }); + } + if (additionalFields.clickedFacebookAd) { + body.push({ + property: 'hs_facebook_ad_clicked', + value: additionalFields.clickedFacebookAd, + }); + } + if (additionalFields.closeDate) { + body.push({ + property: 'closedate', + value: new Date(additionalFields.closeDate as string).getTime(), + }); + } + if (additionalFields.companyName) { + body.push({ + property: 'company', + value: additionalFields.companyName, + }); + } + if (additionalFields.companySize) { + body.push({ + property: 'company_size', + value: additionalFields.companySize, + }); + } + if (additionalFields.description) { + body.push({ + property: 'description', + value: additionalFields.description, + }); + } + if (additionalFields.contactOwner) { + body.push({ + property: 'hubspot_owner_id', + value: additionalFields.contactOwner, + }); + } + if (additionalFields.country) { + body.push({ + property: 'country', + value: additionalFields.country, + }); + } + if (additionalFields.dateOfBirth) { + body.push({ + property: 'date_of_birth', + value: additionalFields.dateOfBirth, + }); + } + if (additionalFields.degree) { + body.push({ + property: 'degree', + value: additionalFields.degree, + }); + } + if (additionalFields.facebookClickId) { + body.push({ + property: 'hs_facebook_click_id', + value: additionalFields.facebookClickId, + }); + } + if (additionalFields.faxNumber) { + body.push({ + property: 'fax', + value: additionalFields.faxNumber, + }); + } + if (additionalFields.fieldOfStudy) { + body.push({ + property: 'field_of_study', + value: additionalFields.fieldOfStudy, + }); + } + if (additionalFields.firstName) { + body.push({ + property: 'firstname', + value: additionalFields.firstName, + }); + } + if (additionalFields.gender) { + body.push({ + property: 'gender', + value: additionalFields.gender, + }); + } + if (additionalFields.googleAdClickId) { + body.push({ + property: 'hs_google_click_id', + value: additionalFields.googleAdClickId, + }); + } + if (additionalFields.graduationDate) { + body.push({ + property: 'graduation_date', + value: additionalFields.graduationDate, + }); + } + if (additionalFields.industry) { + body.push({ + property: 'industry', + value: additionalFields.industry, + }); + } + if (additionalFields.jobFunction) { + body.push({ + property: 'job_function', + value: additionalFields.jobFunction, + }); + } + if (additionalFields.jobTitle) { + body.push({ + property: 'jobtitle', + value: additionalFields.jobTitle, + }); + } + if (additionalFields.lastName) { + body.push({ + property: 'lastname', + value: additionalFields.lastName, + }); + } + if (additionalFields.leadStatus) { + body.push({ + property: 'hs_lead_status', + value: additionalFields.leadStatus, + }); + } + if (additionalFields.processingContactData) { + body.push({ + property: 'hs_legal_basis', + value: additionalFields.processingContactData, + }); + } + if (additionalFields.lifeCycleStage) { + body.push({ + property: 'lifecyclestage', + value: additionalFields.lifeCycleStage, + }); + } + if (additionalFields.maritalStatus) { + body.push({ + property: 'marital_status', + value: additionalFields.maritalStatus, + }); + } + if (additionalFields.membershipNote) { + body.push({ + property: 'hs_content_membership_notes', + value: additionalFields.membershipNote, + }); + } + if (additionalFields.message) { + body.push({ + property: 'message', + value: additionalFields.message, + }); + } + if (additionalFields.mobilePhoneNumber) { + body.push({ + property: 'mobilephone', + value: additionalFields.mobilePhoneNumber, + }); + } + if (additionalFields.numberOfEmployees) { + body.push({ + property: 'numemployees', + value: additionalFields.numberOfEmployees, + }); + } + if (additionalFields.originalSource) { + body.push({ + property: 'hs_analytics_source', + value: additionalFields.originalSource, + }); + } + if (additionalFields.phoneNumber) { + body.push({ + property: 'phone', + value: additionalFields.phoneNumber, + }); + } + if (additionalFields.postalCode) { + body.push({ + property: 'zip', + value: additionalFields.postalCode, + }); + } + if (additionalFields.prefferedLanguage) { + body.push({ + property: 'hs_language', + value: additionalFields.prefferedLanguage, + }); + } + if (additionalFields.relationshipStatus) { + body.push({ + property: 'relationship_status', + value: additionalFields.relationshipStatus, + }); + } + if (additionalFields.salutation) { + body.push({ + property: 'salutation', + value: additionalFields.salutation, + }); + } + if (additionalFields.school) { + body.push({ + property: 'school', + value: additionalFields.school, + }); + } + if (additionalFields.seniority) { + body.push({ + property: 'seniority', + value: additionalFields.seniority, + }); + } + if (additionalFields.startDate) { + body.push({ + property: 'start_date', + value: additionalFields.startDate, + }); + } + if (additionalFields.stateRegion) { + body.push({ + property: 'state', + value: additionalFields.stateRegion, + }); + } + if (additionalFields.status) { + body.push({ + property: 'hs_content_membership_status', + value: additionalFields.status, + }); + } + if (additionalFields.streetAddress) { + body.push({ + property: 'address', + value: additionalFields.streetAddress, + }); + } + if (additionalFields.twitterUsername) { + body.push({ + property: 'twitterhandle', + value: additionalFields.twitterUsername, + }); + } + if (additionalFields.websiteUrl) { + body.push({ + property: 'website', + value: additionalFields.websiteUrl, + }); + } + if (additionalFields.workEmail) { + body.push({ + property: 'work_email', + value: additionalFields.workEmail, + }); + } - if (additionalFields.customPropertiesUi) { - const customProperties = (additionalFields.customPropertiesUi as IDataObject).customPropertiesValues as IDataObject[]; + if (additionalFields.customPropertiesUi) { + const customProperties = (additionalFields.customPropertiesUi as IDataObject).customPropertiesValues as IDataObject[]; - if (customProperties) { - for (const customProperty of customProperties) { - body.push({ - property: customProperty.property, - value: customProperty.value, - }); + if (customProperties) { + for (const customProperty of customProperties) { + body.push({ + property: customProperty.property, + value: customProperty.value, + }); + } } } + + const endpoint = `/contacts/v1/contact/createOrUpdate/email/${email}`; + responseData = await hubspotApiRequest.call(this, 'POST', endpoint, { properties: body }); + + if (additionalFields.associatedCompanyId) { + const companyAssociations: IDataObject[] = []; + companyAssociations.push({ + fromObjectId: responseData.vid, + toObjectId: additionalFields.associatedCompanyId, + category: 'HUBSPOT_DEFINED', + definitionId: 1, + }); + await hubspotApiRequest.call(this, 'PUT', '/crm-associations/v1/associations/create-batch', companyAssociations); + } + + if (resolveData) { + const isNew = responseData.isNew; + const qs: IDataObject = {}; + if (additionalFields.properties) { + qs.property = additionalFields.properties as string[]; + } + responseData = await hubspotApiRequest.call(this, 'GET', `/contacts/v1/contact/vid/${responseData.vid}/profile`, {}, qs); + responseData.isNew = isNew; + } } - - const endpoint = `/contacts/v1/contact/createOrUpdate/email/${email}`; - responseData = await hubspotApiRequest.call(this, 'POST', endpoint, { properties: body }); - - if (additionalFields.associatedCompanyId) { - const companyAssociations: IDataObject[] = []; - companyAssociations.push({ - fromObjectId: responseData.vid, - toObjectId: additionalFields.associatedCompanyId, - category: 'HUBSPOT_DEFINED', - definitionId: 1, - }); - await hubspotApiRequest.call(this, 'PUT', '/crm-associations/v1/associations/create-batch', companyAssociations); - } - - if (resolveData) { - const isNew = responseData.isNew; - const qs: IDataObject = {}; + //https://developers.hubspot.com/docs/methods/contacts/get_contact + if (operation === 'get') { + const contactId = this.getNodeParameter('contactId', i) as string; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + if (additionalFields.formSubmissionMode) { + qs.formSubmissionMode = additionalFields.formSubmissionMode as string; + } + if (additionalFields.listMerberships) { + qs.showListMemberships = additionalFields.listMerberships as boolean; + } if (additionalFields.properties) { qs.property = additionalFields.properties as string[]; } - responseData = await hubspotApiRequest.call(this, 'GET', `/contacts/v1/contact/vid/${responseData.vid}/profile`, {}, qs); - responseData.isNew = isNew; - } - } - //https://developers.hubspot.com/docs/methods/contacts/get_contact - if (operation === 'get') { - const contactId = this.getNodeParameter('contactId', i) as string; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - if (additionalFields.formSubmissionMode) { - qs.formSubmissionMode = additionalFields.formSubmissionMode as string; - } - if (additionalFields.listMerberships) { - qs.showListMemberships = additionalFields.listMerberships as boolean; - } - if (additionalFields.properties) { - qs.property = additionalFields.properties as string[]; - } - if (additionalFields.propertyMode) { - qs.propertyMode = snakeCase(additionalFields.propertyMode as string); - } - const endpoint = `/contacts/v1/contact/vid/${contactId}/profile`; - responseData = await hubspotApiRequest.call(this, 'GET', endpoint, {}, qs); - } - //https://developers.hubspot.com/docs/methods/contacts/get_contacts - if (operation === 'getAll') { - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const returnAll = this.getNodeParameter('returnAll', 0) as boolean; - if (additionalFields.formSubmissionMode) { - qs.formSubmissionMode = additionalFields.formSubmissionMode as string; - } - if (additionalFields.listMerberships) { - qs.showListMemberships = additionalFields.listMerberships as boolean; - } - if (additionalFields.properties) { - qs.property = additionalFields.properties as string[]; - } - if (additionalFields.propertyMode) { - qs.propertyMode = snakeCase(additionalFields.propertyMode as string); - } - const endpoint = '/contacts/v1/lists/all/contacts/all'; - if (returnAll) { - responseData = await hubspotApiRequestAllItems.call(this, 'contacts', 'GET', endpoint, {}, qs); - } else { - qs.count = this.getNodeParameter('limit', 0) as number; + if (additionalFields.propertyMode) { + qs.propertyMode = snakeCase(additionalFields.propertyMode as string); + } + const endpoint = `/contacts/v1/contact/vid/${contactId}/profile`; responseData = await hubspotApiRequest.call(this, 'GET', endpoint, {}, qs); - responseData = responseData.contacts; } - } - //https://developers.hubspot.com/docs/methods/contacts/get_recently_created_contacts - if (operation === 'getRecentlyCreatedUpdated') { - let endpoint; - const returnAll = this.getNodeParameter('returnAll', 0) as boolean; - const filters = this.getNodeParameter('filters', i) as IDataObject; - if (filters.formSubmissionMode) { - qs.formSubmissionMode = filters.formSubmissionMode as string; - } - if (filters.listMerberships) { - qs.showListMemberships = filters.listMerberships as boolean; - } - if (filters.properties) { - qs.property = filters.properties as string[]; - } - if (filters.propertyMode) { - qs.propertyMode = snakeCase(filters.propertyMode as string); + //https://developers.hubspot.com/docs/methods/contacts/get_contacts + if (operation === 'getAll') { + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const returnAll = this.getNodeParameter('returnAll', 0) as boolean; + if (additionalFields.formSubmissionMode) { + qs.formSubmissionMode = additionalFields.formSubmissionMode as string; + } + if (additionalFields.listMerberships) { + qs.showListMemberships = additionalFields.listMerberships as boolean; + } + if (additionalFields.properties) { + qs.property = additionalFields.properties as string[]; + } + if (additionalFields.propertyMode) { + qs.propertyMode = snakeCase(additionalFields.propertyMode as string); + } + const endpoint = '/contacts/v1/lists/all/contacts/all'; + if (returnAll) { + responseData = await hubspotApiRequestAllItems.call(this, 'contacts', 'GET', endpoint, {}, qs); + } else { + qs.count = this.getNodeParameter('limit', 0) as number; + responseData = await hubspotApiRequest.call(this, 'GET', endpoint, {}, qs); + responseData = responseData.contacts; + } } + //https://developers.hubspot.com/docs/methods/contacts/get_recently_created_contacts + if (operation === 'getRecentlyCreatedUpdated') { + let endpoint; + const returnAll = this.getNodeParameter('returnAll', 0) as boolean; + const filters = this.getNodeParameter('filters', i) as IDataObject; + if (filters.formSubmissionMode) { + qs.formSubmissionMode = filters.formSubmissionMode as string; + } + if (filters.listMerberships) { + qs.showListMemberships = filters.listMerberships as boolean; + } + if (filters.properties) { + qs.property = filters.properties as string[]; + } + if (filters.propertyMode) { + qs.propertyMode = snakeCase(filters.propertyMode as string); + } - endpoint = '/contacts/v1/lists/recently_updated/contacts/recent'; + endpoint = '/contacts/v1/lists/recently_updated/contacts/recent'; - if (returnAll) { - responseData = await hubspotApiRequestAllItems.call(this, 'contacts', 'GET', endpoint, {}, qs); - } else { - qs.count = this.getNodeParameter('limit', 0) as number; - responseData = await hubspotApiRequest.call(this, 'GET', endpoint, {}, qs); - responseData = responseData.contacts; + if (returnAll) { + responseData = await hubspotApiRequestAllItems.call(this, 'contacts', 'GET', endpoint, {}, qs); + } else { + qs.count = this.getNodeParameter('limit', 0) as number; + responseData = await hubspotApiRequest.call(this, 'GET', endpoint, {}, qs); + responseData = responseData.contacts; + } } - } - //https://developers.hubspot.com/docs/methods/contacts/delete_contact - if (operation === 'delete') { - const contactId = this.getNodeParameter('contactId', i) as string; - const endpoint = `/contacts/v1/contact/vid/${contactId}`; - responseData = await hubspotApiRequest.call(this, 'DELETE', endpoint); - } - //https://developers.hubspot.com/docs/api/crm/search - if (operation === 'search') { - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const returnAll = this.getNodeParameter('returnAll', 0) as boolean; - const filtersGroupsUi = this.getNodeParameter('filterGroupsUi', i) as IDataObject; - const sortBy = additionalFields.sortBy || 'createdate'; - const direction = additionalFields.direction || 'DESCENDING'; + //https://developers.hubspot.com/docs/methods/contacts/delete_contact + if (operation === 'delete') { + const contactId = this.getNodeParameter('contactId', i) as string; + const endpoint = `/contacts/v1/contact/vid/${contactId}`; + responseData = await hubspotApiRequest.call(this, 'DELETE', endpoint); + } + //https://developers.hubspot.com/docs/api/crm/search + if (operation === 'search') { + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const returnAll = this.getNodeParameter('returnAll', 0) as boolean; + const filtersGroupsUi = this.getNodeParameter('filterGroupsUi', i) as IDataObject; + const sortBy = additionalFields.sortBy || 'createdate'; + const direction = additionalFields.direction || 'DESCENDING'; - const body: IDataObject = { - sorts: [ - { - propertyName: sortBy, - direction, - }, - ], - }; + const body: IDataObject = { + sorts: [ + { + propertyName: sortBy, + direction, + }, + ], + }; - if (filtersGroupsUi) { - const filterGroupValues = (filtersGroupsUi as IDataObject).filterGroupsValues as IDataObject[]; - if (filterGroupValues) { - body.filterGroups = []; - for (const filterGroupValue of filterGroupValues) { - if (filterGroupValue.filtersUi) { - const filterValues = (filterGroupValue.filtersUi as IDataObject).filterValues as IDataObject[]; - if (filterValues) { - //@ts-ignore - body.filterGroups.push({ filters: filterValues }); + if (filtersGroupsUi) { + const filterGroupValues = (filtersGroupsUi as IDataObject).filterGroupsValues as IDataObject[]; + if (filterGroupValues) { + body.filterGroups = []; + for (const filterGroupValue of filterGroupValues) { + if (filterGroupValue.filtersUi) { + const filterValues = (filterGroupValue.filtersUi as IDataObject).filterValues as IDataObject[]; + if (filterValues) { + //@ts-ignore + body.filterGroups.push({ filters: filterValues }); + } } } } } - } - Object.assign(body, additionalFields); + Object.assign(body, additionalFields); - const endpoint = '/crm/v3/objects/contacts/search'; + const endpoint = '/crm/v3/objects/contacts/search'; - if (returnAll) { + if (returnAll) { - responseData = await hubspotApiRequestAllItems.call(this, 'results', 'POST', endpoint, body, qs); + responseData = await hubspotApiRequestAllItems.call(this, 'results', 'POST', endpoint, body, qs); - } else { - qs.count = this.getNodeParameter('limit', 0) as number; - responseData = await hubspotApiRequest.call(this, 'POST', endpoint, body, qs); - responseData = responseData.results; - } - } - } - //https://developers.hubspot.com/docs/methods/companies/companies-overview - if (resource === 'company') { - //https://developers.hubspot.com/docs/methods/companies/create_company - if (operation === 'create') { - const name = this.getNodeParameter('name', i) as string; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const body: IDataObject[] = []; - body.push({ - name: 'name', - value: name, - }); - if (additionalFields.aboutUs) { - body.push({ - name: 'about_us', - value: additionalFields.aboutUs, - }); - } - if (additionalFields.annualRevenue) { - body.push({ - name: 'annualrevenue', - value: (additionalFields.annualRevenue as number).toString(), - }); - } - if (additionalFields.city) { - body.push({ - name: 'city', - value: additionalFields.city, - }); - } - if (additionalFields.closeDate) { - body.push({ - name: 'closedate', - value: new Date(additionalFields.closeDate as string).getTime(), - }); - } - if (additionalFields.companyDomainName) { - body.push({ - name: 'domain', - value: additionalFields.companyDomainName, - }); - } - if (additionalFields.companyOwner) { - body.push({ - name: 'hubspot_owner_id', - value: additionalFields.companyOwner, - }); - } - if (additionalFields.countryRegion) { - body.push({ - name: 'country', - value: additionalFields.countryRegion, - }); - } - if (additionalFields.description) { - body.push({ - name: 'description', - value: additionalFields.description, - }); - } - if (additionalFields.facebookFans) { - body.push({ - name: 'facebookfans', - value: additionalFields.facebookFans, - }); - } - if (additionalFields.googlePlusPage) { - body.push({ - name: 'googleplus_page', - value: additionalFields.googlePlusPage, - }); - } - if (additionalFields.industry) { - body.push({ - name: 'industry', - value: additionalFields.industry, - }); - } - if (additionalFields.isPublic) { - body.push({ - name: 'is_public', - value: additionalFields.isPublic, - }); - } - if (additionalFields.leadStatus) { - body.push({ - name: 'hs_lead_status', - value: additionalFields.leadStatus, - }); - } - if (additionalFields.lifecycleStatus) { - body.push({ - name: 'lifecyclestage', - value: additionalFields.lifecycleStatus, - }); - } - if (additionalFields.linkedinBio) { - body.push({ - name: 'linkedinbio', - value: additionalFields.linkedinBio, - }); - } - if (additionalFields.linkedInCompanyPage) { - body.push({ - name: 'linkedin_company_page', - value: additionalFields.linkedInCompanyPage, - }); - } - if (additionalFields.numberOfEmployees) { - body.push({ - name: 'numberofemployees', - value: additionalFields.numberOfEmployees, - }); - } - if (additionalFields.originalSourceType) { - body.push({ - name: 'hs_analytics_source', - value: additionalFields.originalSourceType, - }); - } - if (additionalFields.phoneNumber) { - body.push({ - name: 'phone', - value: additionalFields.phoneNumber, - }); - } - if (additionalFields.postalCode) { - body.push({ - name: 'zip', - value: additionalFields.postalCode, - }); - } - if (additionalFields.stateRegion) { - body.push({ - name: 'state', - value: additionalFields.stateRegion, - }); - } - if (additionalFields.streetAddress) { - body.push({ - name: 'address', - value: additionalFields.streetAddress, - }); - } - if (additionalFields.streetAddress2) { - body.push({ - name: 'address2', - value: additionalFields.streetAddress2, - }); - } - if (additionalFields.targetAccount) { - body.push({ - name: 'hs_target_account', - value: additionalFields.targetAccount, - }); - } - if (additionalFields.timezone) { - body.push({ - name: 'timezone', - value: additionalFields.timezone, - }); - } - if (additionalFields.totalMoneyRaised) { - body.push({ - name: 'total_money_raised', - value: additionalFields.totalMoneyRaised, - }); - } - if (additionalFields.twitterBio) { - body.push({ - name: 'twitterbio', - value: additionalFields.twitterBio, - }); - } - if (additionalFields.twitterFollowers) { - body.push({ - name: 'twitterfollowers', - value: additionalFields.twitterFollowers, - }); - } - if (additionalFields.twitterHandle) { - body.push({ - name: 'twitterhandle', - value: additionalFields.twitterHandle, - }); - } - if (additionalFields.type) { - body.push({ - name: 'type', - value: additionalFields.type, - }); - } - if (additionalFields.websiteUrl) { - body.push({ - name: 'website', - value: additionalFields.websiteUrl, - }); - } - if (additionalFields.webTechnologies) { - body.push({ - name: 'web_technologies', - value: additionalFields.webTechnologies, - }); - } - if (additionalFields.yearFounded) { - body.push({ - name: 'founded_year', - value: additionalFields.yearFounded, - }); - } - if (additionalFields.customPropertiesUi) { - const customProperties = (additionalFields.customPropertiesUi as IDataObject).customPropertiesValues as IDataObject[]; - - if (customProperties) { - for (const customProperty of customProperties) { - body.push({ - name: customProperty.property, - value: customProperty.value, - }); - } + } else { + qs.count = this.getNodeParameter('limit', 0) as number; + responseData = await hubspotApiRequest.call(this, 'POST', endpoint, body, qs); + responseData = responseData.results; } } - const endpoint = '/companies/v2/companies'; - responseData = await hubspotApiRequest.call(this, 'POST', endpoint, { properties: body }); } - //https://developers.hubspot.com/docs/methods/companies/update_company - if (operation === 'update') { - const companyId = this.getNodeParameter('companyId', i) as string; - const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; - const body: IDataObject[] = []; - if (updateFields.name) { + //https://developers.hubspot.com/docs/methods/companies/companies-overview + if (resource === 'company') { + //https://developers.hubspot.com/docs/methods/companies/create_company + if (operation === 'create') { + const name = this.getNodeParameter('name', i) as string; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const body: IDataObject[] = []; body.push({ name: 'name', - value: updateFields.name, + value: name, }); - } - if (updateFields.aboutUs) { - body.push({ - name: 'about_us', - value: updateFields.aboutUs, - }); - } - if (updateFields.annualRevenue) { - body.push({ - name: 'annualrevenue', - value: (updateFields.annualRevenue as number).toString(), - }); - } - if (updateFields.city) { - body.push({ - name: 'city', - value: updateFields.city, - }); - } - if (updateFields.closeDate) { - body.push({ - name: 'closedate', - value: new Date(updateFields.closeDate as string).getTime(), - }); - } - if (updateFields.companyDomainName) { - body.push({ - name: 'domain', - value: updateFields.companyDomainName, - }); - } - if (updateFields.companyOwner) { - body.push({ - name: 'hubspot_owner_id', - value: updateFields.companyOwner, - }); - } - if (updateFields.countryRegion) { - body.push({ - name: 'country', - value: updateFields.countryRegion, - }); - } - if (updateFields.description) { - body.push({ - name: 'description', - value: updateFields.description, - }); - } - if (updateFields.facebookFans) { - body.push({ - name: 'facebookfans', - value: updateFields.facebookFans, - }); - } - if (updateFields.googlePlusPage) { - body.push({ - name: 'googleplus_page', - value: updateFields.googlePlusPage, - }); - } - if (updateFields.industry) { - body.push({ - name: 'industry', - value: updateFields.industry, - }); - } - if (updateFields.isPublic) { - body.push({ - name: 'is_public', - value: updateFields.isPublic, - }); - } - if (updateFields.leadStatus) { - body.push({ - name: 'hs_lead_status', - value: updateFields.leadStatus, - }); - } - if (updateFields.lifecycleStatus) { - body.push({ - name: 'lifecyclestage', - value: updateFields.lifecycleStatus, - }); - } - if (updateFields.linkedinBio) { - body.push({ - name: 'linkedinbio', - value: updateFields.linkedinBio, - }); - } - if (updateFields.linkedInCompanyPage) { - body.push({ - name: 'linkedin_company_page', - value: updateFields.linkedInCompanyPage, - }); - } - if (updateFields.numberOfEmployees) { - body.push({ - name: 'numberofemployees', - value: updateFields.numberOfEmployees, - }); - } - if (updateFields.originalSourceType) { - body.push({ - name: 'hs_analytics_source', - value: updateFields.originalSourceType, - }); - } - if (updateFields.phoneNumber) { - body.push({ - name: 'phone', - value: updateFields.phoneNumber, - }); - } - if (updateFields.postalCode) { - body.push({ - name: 'zip', - value: updateFields.postalCode, - }); - } - if (updateFields.stateRegion) { - body.push({ - name: 'state', - value: updateFields.stateRegion, - }); - } - if (updateFields.streetAddress) { - body.push({ - name: 'address', - value: updateFields.streetAddress, - }); - } - if (updateFields.streetAddress2) { - body.push({ - name: 'address2', - value: updateFields.streetAddress2, - }); - } - if (updateFields.targetAccount) { - body.push({ - name: 'hs_target_account', - value: updateFields.targetAccount, - }); - } - if (updateFields.timezone) { - body.push({ - name: 'timezone', - value: updateFields.timezone, - }); - } - if (updateFields.totalMoneyRaised) { - body.push({ - name: 'total_money_raised', - value: updateFields.totalMoneyRaised, - }); - } - if (updateFields.twitterBio) { - body.push({ - name: 'twitterbio', - value: updateFields.twitterBio, - }); - } - if (updateFields.twitterFollowers) { - body.push({ - name: 'twitterfollowers', - value: updateFields.twitterFollowers, - }); - } - if (updateFields.twitterHandle) { - body.push({ - name: 'twitterhandle', - value: updateFields.twitterHandle, - }); - } - if (updateFields.type) { - body.push({ - name: 'type', - value: updateFields.type, - }); - } - if (updateFields.websiteUrl) { - body.push({ - name: 'website', - value: updateFields.websiteUrl, - }); - } - if (updateFields.webTechnologies) { - body.push({ - name: 'web_technologies', - value: updateFields.webTechnologies, - }); - } - if (updateFields.yearFounded) { - body.push({ - name: 'founded_year', - value: updateFields.yearFounded, - }); - } - if (updateFields.customPropertiesUi) { - const customProperties = (updateFields.customPropertiesUi as IDataObject).customPropertiesValues as IDataObject[]; + if (additionalFields.aboutUs) { + body.push({ + name: 'about_us', + value: additionalFields.aboutUs, + }); + } + if (additionalFields.annualRevenue) { + body.push({ + name: 'annualrevenue', + value: (additionalFields.annualRevenue as number).toString(), + }); + } + if (additionalFields.city) { + body.push({ + name: 'city', + value: additionalFields.city, + }); + } + if (additionalFields.closeDate) { + body.push({ + name: 'closedate', + value: new Date(additionalFields.closeDate as string).getTime(), + }); + } + if (additionalFields.companyDomainName) { + body.push({ + name: 'domain', + value: additionalFields.companyDomainName, + }); + } + if (additionalFields.companyOwner) { + body.push({ + name: 'hubspot_owner_id', + value: additionalFields.companyOwner, + }); + } + if (additionalFields.countryRegion) { + body.push({ + name: 'country', + value: additionalFields.countryRegion, + }); + } + if (additionalFields.description) { + body.push({ + name: 'description', + value: additionalFields.description, + }); + } + if (additionalFields.facebookFans) { + body.push({ + name: 'facebookfans', + value: additionalFields.facebookFans, + }); + } + if (additionalFields.googlePlusPage) { + body.push({ + name: 'googleplus_page', + value: additionalFields.googlePlusPage, + }); + } + if (additionalFields.industry) { + body.push({ + name: 'industry', + value: additionalFields.industry, + }); + } + if (additionalFields.isPublic) { + body.push({ + name: 'is_public', + value: additionalFields.isPublic, + }); + } + if (additionalFields.leadStatus) { + body.push({ + name: 'hs_lead_status', + value: additionalFields.leadStatus, + }); + } + if (additionalFields.lifecycleStatus) { + body.push({ + name: 'lifecyclestage', + value: additionalFields.lifecycleStatus, + }); + } + if (additionalFields.linkedinBio) { + body.push({ + name: 'linkedinbio', + value: additionalFields.linkedinBio, + }); + } + if (additionalFields.linkedInCompanyPage) { + body.push({ + name: 'linkedin_company_page', + value: additionalFields.linkedInCompanyPage, + }); + } + if (additionalFields.numberOfEmployees) { + body.push({ + name: 'numberofemployees', + value: additionalFields.numberOfEmployees, + }); + } + if (additionalFields.originalSourceType) { + body.push({ + name: 'hs_analytics_source', + value: additionalFields.originalSourceType, + }); + } + if (additionalFields.phoneNumber) { + body.push({ + name: 'phone', + value: additionalFields.phoneNumber, + }); + } + if (additionalFields.postalCode) { + body.push({ + name: 'zip', + value: additionalFields.postalCode, + }); + } + if (additionalFields.stateRegion) { + body.push({ + name: 'state', + value: additionalFields.stateRegion, + }); + } + if (additionalFields.streetAddress) { + body.push({ + name: 'address', + value: additionalFields.streetAddress, + }); + } + if (additionalFields.streetAddress2) { + body.push({ + name: 'address2', + value: additionalFields.streetAddress2, + }); + } + if (additionalFields.targetAccount) { + body.push({ + name: 'hs_target_account', + value: additionalFields.targetAccount, + }); + } + if (additionalFields.timezone) { + body.push({ + name: 'timezone', + value: additionalFields.timezone, + }); + } + if (additionalFields.totalMoneyRaised) { + body.push({ + name: 'total_money_raised', + value: additionalFields.totalMoneyRaised, + }); + } + if (additionalFields.twitterBio) { + body.push({ + name: 'twitterbio', + value: additionalFields.twitterBio, + }); + } + if (additionalFields.twitterFollowers) { + body.push({ + name: 'twitterfollowers', + value: additionalFields.twitterFollowers, + }); + } + if (additionalFields.twitterHandle) { + body.push({ + name: 'twitterhandle', + value: additionalFields.twitterHandle, + }); + } + if (additionalFields.type) { + body.push({ + name: 'type', + value: additionalFields.type, + }); + } + if (additionalFields.websiteUrl) { + body.push({ + name: 'website', + value: additionalFields.websiteUrl, + }); + } + if (additionalFields.webTechnologies) { + body.push({ + name: 'web_technologies', + value: additionalFields.webTechnologies, + }); + } + if (additionalFields.yearFounded) { + body.push({ + name: 'founded_year', + value: additionalFields.yearFounded, + }); + } + if (additionalFields.customPropertiesUi) { + const customProperties = (additionalFields.customPropertiesUi as IDataObject).customPropertiesValues as IDataObject[]; - if (customProperties) { - for (const customProperty of customProperties) { - body.push({ - name: customProperty.property, - value: customProperty.value, - }); + if (customProperties) { + for (const customProperty of customProperties) { + body.push({ + name: customProperty.property, + value: customProperty.value, + }); + } } } + const endpoint = '/companies/v2/companies'; + responseData = await hubspotApiRequest.call(this, 'POST', endpoint, { properties: body }); } - const endpoint = `/companies/v2/companies/${companyId}`; - responseData = await hubspotApiRequest.call(this, 'PUT', endpoint, { properties: body }); - } - //https://developers.hubspot.com/docs/methods/companies/get_company - if (operation === 'get') { - const companyId = this.getNodeParameter('companyId', i) as string; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - if (additionalFields.includeMergeAudits) { - qs.includeMergeAudits = additionalFields.includeMergeAudits as boolean; + //https://developers.hubspot.com/docs/methods/companies/update_company + if (operation === 'update') { + const companyId = this.getNodeParameter('companyId', i) as string; + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + const body: IDataObject[] = []; + if (updateFields.name) { + body.push({ + name: 'name', + value: updateFields.name, + }); + } + if (updateFields.aboutUs) { + body.push({ + name: 'about_us', + value: updateFields.aboutUs, + }); + } + if (updateFields.annualRevenue) { + body.push({ + name: 'annualrevenue', + value: (updateFields.annualRevenue as number).toString(), + }); + } + if (updateFields.city) { + body.push({ + name: 'city', + value: updateFields.city, + }); + } + if (updateFields.closeDate) { + body.push({ + name: 'closedate', + value: new Date(updateFields.closeDate as string).getTime(), + }); + } + if (updateFields.companyDomainName) { + body.push({ + name: 'domain', + value: updateFields.companyDomainName, + }); + } + if (updateFields.companyOwner) { + body.push({ + name: 'hubspot_owner_id', + value: updateFields.companyOwner, + }); + } + if (updateFields.countryRegion) { + body.push({ + name: 'country', + value: updateFields.countryRegion, + }); + } + if (updateFields.description) { + body.push({ + name: 'description', + value: updateFields.description, + }); + } + if (updateFields.facebookFans) { + body.push({ + name: 'facebookfans', + value: updateFields.facebookFans, + }); + } + if (updateFields.googlePlusPage) { + body.push({ + name: 'googleplus_page', + value: updateFields.googlePlusPage, + }); + } + if (updateFields.industry) { + body.push({ + name: 'industry', + value: updateFields.industry, + }); + } + if (updateFields.isPublic) { + body.push({ + name: 'is_public', + value: updateFields.isPublic, + }); + } + if (updateFields.leadStatus) { + body.push({ + name: 'hs_lead_status', + value: updateFields.leadStatus, + }); + } + if (updateFields.lifecycleStatus) { + body.push({ + name: 'lifecyclestage', + value: updateFields.lifecycleStatus, + }); + } + if (updateFields.linkedinBio) { + body.push({ + name: 'linkedinbio', + value: updateFields.linkedinBio, + }); + } + if (updateFields.linkedInCompanyPage) { + body.push({ + name: 'linkedin_company_page', + value: updateFields.linkedInCompanyPage, + }); + } + if (updateFields.numberOfEmployees) { + body.push({ + name: 'numberofemployees', + value: updateFields.numberOfEmployees, + }); + } + if (updateFields.originalSourceType) { + body.push({ + name: 'hs_analytics_source', + value: updateFields.originalSourceType, + }); + } + if (updateFields.phoneNumber) { + body.push({ + name: 'phone', + value: updateFields.phoneNumber, + }); + } + if (updateFields.postalCode) { + body.push({ + name: 'zip', + value: updateFields.postalCode, + }); + } + if (updateFields.stateRegion) { + body.push({ + name: 'state', + value: updateFields.stateRegion, + }); + } + if (updateFields.streetAddress) { + body.push({ + name: 'address', + value: updateFields.streetAddress, + }); + } + if (updateFields.streetAddress2) { + body.push({ + name: 'address2', + value: updateFields.streetAddress2, + }); + } + if (updateFields.targetAccount) { + body.push({ + name: 'hs_target_account', + value: updateFields.targetAccount, + }); + } + if (updateFields.timezone) { + body.push({ + name: 'timezone', + value: updateFields.timezone, + }); + } + if (updateFields.totalMoneyRaised) { + body.push({ + name: 'total_money_raised', + value: updateFields.totalMoneyRaised, + }); + } + if (updateFields.twitterBio) { + body.push({ + name: 'twitterbio', + value: updateFields.twitterBio, + }); + } + if (updateFields.twitterFollowers) { + body.push({ + name: 'twitterfollowers', + value: updateFields.twitterFollowers, + }); + } + if (updateFields.twitterHandle) { + body.push({ + name: 'twitterhandle', + value: updateFields.twitterHandle, + }); + } + if (updateFields.type) { + body.push({ + name: 'type', + value: updateFields.type, + }); + } + if (updateFields.websiteUrl) { + body.push({ + name: 'website', + value: updateFields.websiteUrl, + }); + } + if (updateFields.webTechnologies) { + body.push({ + name: 'web_technologies', + value: updateFields.webTechnologies, + }); + } + if (updateFields.yearFounded) { + body.push({ + name: 'founded_year', + value: updateFields.yearFounded, + }); + } + if (updateFields.customPropertiesUi) { + const customProperties = (updateFields.customPropertiesUi as IDataObject).customPropertiesValues as IDataObject[]; + + if (customProperties) { + for (const customProperty of customProperties) { + body.push({ + name: customProperty.property, + value: customProperty.value, + }); + } + } + } + const endpoint = `/companies/v2/companies/${companyId}`; + responseData = await hubspotApiRequest.call(this, 'PUT', endpoint, { properties: body }); } - const endpoint = `/companies/v2/companies/${companyId}`; - responseData = await hubspotApiRequest.call(this, 'GET', endpoint, {}, qs); - } - //https://developers.hubspot.com/docs/methods/companies/get-all-companies - if (operation === 'getAll') { - const options = this.getNodeParameter('options', i) as IDataObject; - const returnAll = this.getNodeParameter('returnAll', 0) as boolean; - if (options.includeMergeAudits) { - qs.includeMergeAudits = options.includeMergeAudits as boolean; - } - if (options.properties) { - qs.properties = options.properties as string[]; - } - if (options.propertiesWithHistory) { - qs.propertiesWithHistory = (options.propertiesWithHistory as string).split(','); - } - const endpoint = `/companies/v2/companies/paged`; - if (returnAll) { - responseData = await hubspotApiRequestAllItems.call(this, 'companies', 'GET', endpoint, {}, qs); - } else { - qs.limit = this.getNodeParameter('limit', 0) as number; + //https://developers.hubspot.com/docs/methods/companies/get_company + if (operation === 'get') { + const companyId = this.getNodeParameter('companyId', i) as string; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + if (additionalFields.includeMergeAudits) { + qs.includeMergeAudits = additionalFields.includeMergeAudits as boolean; + } + const endpoint = `/companies/v2/companies/${companyId}`; responseData = await hubspotApiRequest.call(this, 'GET', endpoint, {}, qs); - responseData = responseData.companies; + } + //https://developers.hubspot.com/docs/methods/companies/get-all-companies + if (operation === 'getAll') { + const options = this.getNodeParameter('options', i) as IDataObject; + const returnAll = this.getNodeParameter('returnAll', 0) as boolean; + if (options.includeMergeAudits) { + qs.includeMergeAudits = options.includeMergeAudits as boolean; + } + if (options.properties) { + qs.properties = options.properties as string[]; + } + if (options.propertiesWithHistory) { + qs.propertiesWithHistory = (options.propertiesWithHistory as string).split(','); + } + const endpoint = `/companies/v2/companies/paged`; + if (returnAll) { + responseData = await hubspotApiRequestAllItems.call(this, 'companies', 'GET', endpoint, {}, qs); + } else { + qs.limit = this.getNodeParameter('limit', 0) as number; + responseData = await hubspotApiRequest.call(this, 'GET', endpoint, {}, qs); + responseData = responseData.companies; + } + } + //https://developers.hubspot.com/docs/methods/companies/get_companies_modified + if (operation === 'getRecentlyCreated' || operation === 'getRecentlyModified') { + let endpoint; + const returnAll = this.getNodeParameter('returnAll', 0) as boolean; + if (operation === 'getRecentlyCreated') { + endpoint = `/companies/v2/companies/recent/created`; + } else { + const filters = this.getNodeParameter('filters', i) as IDataObject; + if (filters.since) { + qs.since = new Date(filters.since as string).getTime(); + } + endpoint = `/companies/v2/companies/recent/modified`; + } + if (returnAll) { + responseData = await hubspotApiRequestAllItems.call(this, 'results', 'GET', endpoint, {}, qs); + } else { + qs.count = this.getNodeParameter('limit', 0) as number; + responseData = await hubspotApiRequest.call(this, 'GET', endpoint, {}, qs); + responseData = responseData.results; + } + } + //https://developers.hubspot.com/docs/methods/companies/search_companies_by_domain + if (operation === 'searchByDomain') { + const domain = this.getNodeParameter('domain', i) as string; + const options = this.getNodeParameter('options', i) as IDataObject; + const returnAll = this.getNodeParameter('returnAll', 0) as boolean; + const body: IDataObject = { + requestOptions: {}, + }; + if (options.properties) { + body.requestOptions = { properties: options.properties as string[] }; + } + const endpoint = `/companies/v2/domains/${domain}/companies`; + if (returnAll) { + responseData = await hubspotApiRequestAllItems.call(this, 'results', 'POST', endpoint, body); + } else { + body.limit = this.getNodeParameter('limit', 0) as number; + responseData = await hubspotApiRequest.call(this, 'POST', endpoint, body); + responseData = responseData.results; + } + } + //https://developers.hubspot.com/docs/methods/companies/delete_company + if (operation === 'delete') { + const companyId = this.getNodeParameter('companyId', i) as string; + const endpoint = `/companies/v2/companies/${companyId}`; + responseData = await hubspotApiRequest.call(this, 'DELETE', endpoint); } } - //https://developers.hubspot.com/docs/methods/companies/get_companies_modified - if (operation === 'getRecentlyCreated' || operation === 'getRecentlyModified') { - let endpoint; - const returnAll = this.getNodeParameter('returnAll', 0) as boolean; - if (operation === 'getRecentlyCreated') { - endpoint = `/companies/v2/companies/recent/created`; - } else { + //https://developers.hubspot.com/docs/methods/deals/deals_overview + if (resource === 'deal') { + if (operation === 'create') { + const body: IDeal = {}; + body.properties = []; + const association: IAssociation = {}; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const stage = this.getNodeParameter('stage', i) as string; + if (stage) { + 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) { + body.properties.push({ + name: 'dealname', + value: additionalFields.dealName as string, + }); + } + if (additionalFields.closeDate) { + body.properties.push({ + name: 'closedate', + value: new Date(additionalFields.closeDate as string).getTime(), + }); + } + if (additionalFields.amount) { + body.properties.push({ + name: 'amount', + value: additionalFields.amount as string, + }); + } + if (additionalFields.dealType) { + body.properties.push({ + name: 'dealtype', + value: additionalFields.dealType as string, + }); + } + if (additionalFields.pipeline) { + body.properties.push({ + name: 'pipeline', + value: additionalFields.pipeline as string, + }); + } + if (additionalFields.description) { + body.properties.push({ + name: 'description', + value: additionalFields.description as string, + }); + } + if (additionalFields.customPropertiesUi) { + const customProperties = (additionalFields.customPropertiesUi as IDataObject).customPropertiesValues as IDataObject[]; + if (customProperties) { + for (const customProperty of customProperties) { + body.properties.push({ + name: customProperty.property, + value: customProperty.value, + }); + } + } + } + body.associations = association; + const endpoint = '/deals/v1/deal'; + responseData = await hubspotApiRequest.call(this, 'POST', endpoint, body); + } + if (operation === 'update') { + const body: IDeal = {}; + body.properties = []; + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + const dealId = this.getNodeParameter('dealId', i) as string; + if (updateFields.stage) { + body.properties.push({ + name: 'dealstage', + value: updateFields.stage as string, + }); + } + if (updateFields.dealName) { + body.properties.push({ + name: 'dealname', + value: updateFields.dealName as string, + }); + } + if (updateFields.closeDate) { + body.properties.push({ + name: 'closedate', + value: new Date(updateFields.closeDate as string).getTime(), + }); + } + if (updateFields.amount) { + body.properties.push({ + name: 'amount', + value: updateFields.amount as string, + }); + } + if (updateFields.dealType) { + body.properties.push({ + name: 'dealtype', + value: updateFields.dealType as string, + }); + } + if (updateFields.pipeline) { + body.properties.push({ + name: 'pipeline', + value: updateFields.pipeline as string, + }); + } + if (updateFields.description) { + body.properties.push({ + name: 'description', + value: updateFields.description as string, + }); + } + if (updateFields.customPropertiesUi) { + const customProperties = (updateFields.customPropertiesUi as IDataObject).customPropertiesValues as IDataObject[]; + if (customProperties) { + for (const customProperty of customProperties) { + body.properties.push({ + name: customProperty.property, + value: customProperty.value, + }); + } + } + } + const endpoint = `/deals/v1/deal/${dealId}`; + responseData = await hubspotApiRequest.call(this, 'PUT', endpoint, body); + } + if (operation === 'get') { + const dealId = this.getNodeParameter('dealId', i) as string; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + if (additionalFields.includePropertyVersions) { + qs.includePropertyVersions = additionalFields.includePropertyVersions as boolean; + } + const endpoint = `/deals/v1/deal/${dealId}`; + responseData = await hubspotApiRequest.call(this, 'GET', endpoint); + } + if (operation === 'getAll') { const filters = this.getNodeParameter('filters', i) as IDataObject; + const returnAll = this.getNodeParameter('returnAll', 0) as boolean; + if (filters.includeAssociations) { + qs.includeAssociations = filters.includeAssociations as boolean; + } + if (filters.properties) { + qs.properties = (filters.properties as string).split(','); + } + if (filters.propertiesWithHistory) { + qs.propertiesWithHistory = (filters.propertiesWithHistory as string).split(','); + } + const endpoint = `/deals/v1/deal/paged`; + if (returnAll) { + responseData = await hubspotApiRequestAllItems.call(this, 'deals', 'GET', endpoint, {}, qs); + } else { + qs.limit = this.getNodeParameter('limit', 0) as number; + responseData = await hubspotApiRequest.call(this, 'GET', endpoint, {}, qs); + responseData = responseData.deals; + } + } + if (operation === 'getRecentlyCreated' || operation === 'getRecentlyModified') { + let endpoint; + const filters = this.getNodeParameter('filters', i) as IDataObject; + const returnAll = this.getNodeParameter('returnAll', 0) as boolean; if (filters.since) { qs.since = new Date(filters.since as string).getTime(); } - endpoint = `/companies/v2/companies/recent/modified`; - } - if (returnAll) { - responseData = await hubspotApiRequestAllItems.call(this, 'results', 'GET', endpoint, {}, qs); - } else { - qs.count = this.getNodeParameter('limit', 0) as number; - responseData = await hubspotApiRequest.call(this, 'GET', endpoint, {}, qs); - responseData = responseData.results; - } - } - //https://developers.hubspot.com/docs/methods/companies/search_companies_by_domain - if (operation === 'searchByDomain') { - const domain = this.getNodeParameter('domain', i) as string; - const options = this.getNodeParameter('options', i) as IDataObject; - const returnAll = this.getNodeParameter('returnAll', 0) as boolean; - const body: IDataObject = { - requestOptions: {}, - }; - if (options.properties) { - body.requestOptions = { properties: options.properties as string[] }; - } - const endpoint = `/companies/v2/domains/${domain}/companies`; - if (returnAll) { - responseData = await hubspotApiRequestAllItems.call(this, 'results', 'POST', endpoint, body); - } else { - body.limit = this.getNodeParameter('limit', 0) as number; - responseData = await hubspotApiRequest.call(this, 'POST', endpoint, body); - responseData = responseData.results; - } - } - //https://developers.hubspot.com/docs/methods/companies/delete_company - if (operation === 'delete') { - const companyId = this.getNodeParameter('companyId', i) as string; - const endpoint = `/companies/v2/companies/${companyId}`; - responseData = await hubspotApiRequest.call(this, 'DELETE', endpoint); - } - } - //https://developers.hubspot.com/docs/methods/deals/deals_overview - if (resource === 'deal') { - if (operation === 'create') { - const body: IDeal = {}; - body.properties = []; - const association: IAssociation = {}; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const stage = this.getNodeParameter('stage', i) as string; - if (stage) { - 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) { - body.properties.push({ - name: 'dealname', - value: additionalFields.dealName as string, - }); - } - if (additionalFields.closeDate) { - body.properties.push({ - name: 'closedate', - value: new Date(additionalFields.closeDate as string).getTime(), - }); - } - if (additionalFields.amount) { - body.properties.push({ - name: 'amount', - value: additionalFields.amount as string, - }); - } - if (additionalFields.dealType) { - body.properties.push({ - name: 'dealtype', - value: additionalFields.dealType as string, - }); - } - if (additionalFields.pipeline) { - body.properties.push({ - name: 'pipeline', - value: additionalFields.pipeline as string, - }); - } - if (additionalFields.description) { - body.properties.push({ - name: 'description', - value: additionalFields.description as string, - }); - } - if (additionalFields.customPropertiesUi) { - const customProperties = (additionalFields.customPropertiesUi as IDataObject).customPropertiesValues as IDataObject[]; - if (customProperties) { - for (const customProperty of customProperties) { - body.properties.push({ - name: customProperty.property, - value: customProperty.value, - }); - } + if (filters.includePropertyVersions) { + qs.includePropertyVersions = filters.includePropertyVersions as boolean; + } + if (operation === 'getRecentlyCreated') { + endpoint = `/deals/v1/deal/recent/created`; + } else { + endpoint = `/deals/v1/deal/recent/modified`; + } + if (returnAll) { + responseData = await hubspotApiRequestAllItems.call(this, 'results', 'GET', endpoint, {}, qs); + } else { + qs.count = this.getNodeParameter('limit', 0) as number; + responseData = await hubspotApiRequest.call(this, 'GET', endpoint, {}, qs); + responseData = responseData.results; } } - body.associations = association; - const endpoint = '/deals/v1/deal'; - responseData = await hubspotApiRequest.call(this, 'POST', endpoint, body); - } - if (operation === 'update') { - const body: IDeal = {}; - body.properties = []; - const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; - const dealId = this.getNodeParameter('dealId', i) as string; - if (updateFields.stage) { - body.properties.push({ - name: 'dealstage', - value: updateFields.stage as string, - }); + if (operation === 'delete') { + const dealId = this.getNodeParameter('dealId', i) as string; + const endpoint = `/deals/v1/deal/${dealId}`; + responseData = await hubspotApiRequest.call(this, 'DELETE', endpoint); } - if (updateFields.dealName) { - body.properties.push({ - name: 'dealname', - value: updateFields.dealName as string, - }); - } - if (updateFields.closeDate) { - body.properties.push({ - name: 'closedate', - value: new Date(updateFields.closeDate as string).getTime(), - }); - } - if (updateFields.amount) { - body.properties.push({ - name: 'amount', - value: updateFields.amount as string, - }); - } - if (updateFields.dealType) { - body.properties.push({ - name: 'dealtype', - value: updateFields.dealType as string, - }); - } - if (updateFields.pipeline) { - body.properties.push({ - name: 'pipeline', - value: updateFields.pipeline as string, - }); - } - if (updateFields.description) { - body.properties.push({ - name: 'description', - value: updateFields.description as string, - }); - } - if (updateFields.customPropertiesUi) { - const customProperties = (updateFields.customPropertiesUi as IDataObject).customPropertiesValues as IDataObject[]; - if (customProperties) { - for (const customProperty of customProperties) { - body.properties.push({ - name: customProperty.property, - value: customProperty.value, - }); - } - } - } - const endpoint = `/deals/v1/deal/${dealId}`; - responseData = await hubspotApiRequest.call(this, 'PUT', endpoint, body); - } - if (operation === 'get') { - const dealId = this.getNodeParameter('dealId', i) as string; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - if (additionalFields.includePropertyVersions) { - qs.includePropertyVersions = additionalFields.includePropertyVersions as boolean; - } - const endpoint = `/deals/v1/deal/${dealId}`; - responseData = await hubspotApiRequest.call(this, 'GET', endpoint); - } - if (operation === 'getAll') { - const filters = this.getNodeParameter('filters', i) as IDataObject; - const returnAll = this.getNodeParameter('returnAll', 0) as boolean; - if (filters.includeAssociations) { - qs.includeAssociations = filters.includeAssociations as boolean; - } - if (filters.properties) { - qs.properties = (filters.properties as string).split(','); - } - if (filters.propertiesWithHistory) { - qs.propertiesWithHistory = (filters.propertiesWithHistory as string).split(','); - } - const endpoint = `/deals/v1/deal/paged`; - if (returnAll) { - responseData = await hubspotApiRequestAllItems.call(this, 'deals', 'GET', endpoint, {}, qs); - } else { - qs.limit = this.getNodeParameter('limit', 0) as number; - responseData = await hubspotApiRequest.call(this, 'GET', endpoint, {}, qs); - responseData = responseData.deals; - } - } - if (operation === 'getRecentlyCreated' || operation === 'getRecentlyModified') { - let endpoint; - const filters = this.getNodeParameter('filters', i) as IDataObject; - const returnAll = this.getNodeParameter('returnAll', 0) as boolean; - if (filters.since) { - qs.since = new Date(filters.since as string).getTime(); - } - if (filters.includePropertyVersions) { - qs.includePropertyVersions = filters.includePropertyVersions as boolean; - } - if (operation === 'getRecentlyCreated') { - endpoint = `/deals/v1/deal/recent/created`; - } else { - endpoint = `/deals/v1/deal/recent/modified`; - } - if (returnAll) { - responseData = await hubspotApiRequestAllItems.call(this, 'results', 'GET', endpoint, {}, qs); - } else { - qs.count = this.getNodeParameter('limit', 0) as number; - responseData = await hubspotApiRequest.call(this, 'GET', endpoint, {}, qs); - responseData = responseData.results; - } - } - if (operation === 'delete') { - const dealId = this.getNodeParameter('dealId', i) as string; - const endpoint = `/deals/v1/deal/${dealId}`; - responseData = await hubspotApiRequest.call(this, 'DELETE', endpoint); - } - //https://developers.hubspot.com/docs/api/crm/search - if (operation === 'search') { - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const returnAll = this.getNodeParameter('returnAll', 0) as boolean; - const filtersGroupsUi = this.getNodeParameter('filterGroupsUi', i) as IDataObject; - const sortBy = additionalFields.sortBy || 'createdate'; - const direction = additionalFields.direction || 'DESCENDING'; + //https://developers.hubspot.com/docs/api/crm/search + if (operation === 'search') { + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const returnAll = this.getNodeParameter('returnAll', 0) as boolean; + const filtersGroupsUi = this.getNodeParameter('filterGroupsUi', i) as IDataObject; + const sortBy = additionalFields.sortBy || 'createdate'; + const direction = additionalFields.direction || 'DESCENDING'; - const body: IDataObject = { - sorts: [ - { - propertyName: sortBy, - direction, - }, - ], - }; + const body: IDataObject = { + sorts: [ + { + propertyName: sortBy, + direction, + }, + ], + }; - if (filtersGroupsUi) { - const filterGroupValues = (filtersGroupsUi as IDataObject).filterGroupsValues as IDataObject[]; - if (filterGroupValues) { - body.filterGroups = []; - for (const filterGroupValue of filterGroupValues) { - if (filterGroupValue.filtersUi) { - const filterValues = (filterGroupValue.filtersUi as IDataObject).filterValues as IDataObject[]; - if (filterValues) { - //@ts-ignore - body.filterGroups.push({ filters: filterValues }); + if (filtersGroupsUi) { + const filterGroupValues = (filtersGroupsUi as IDataObject).filterGroupsValues as IDataObject[]; + if (filterGroupValues) { + body.filterGroups = []; + for (const filterGroupValue of filterGroupValues) { + if (filterGroupValue.filtersUi) { + const filterValues = (filterGroupValue.filtersUi as IDataObject).filterValues as IDataObject[]; + if (filterValues) { + //@ts-ignore + body.filterGroups.push({ filters: filterValues }); + } } } } } - } - Object.assign(body, additionalFields); + Object.assign(body, additionalFields); - const endpoint = '/crm/v3/objects/deals/search'; + const endpoint = '/crm/v3/objects/deals/search'; - if (returnAll) { + if (returnAll) { - responseData = await hubspotApiRequestAllItems.call(this, 'results', 'POST', endpoint, body, qs); - - } else { - body.limit = this.getNodeParameter('limit', 0) as number; - responseData = await hubspotApiRequest.call(this, 'POST', endpoint, body, qs); - responseData = responseData.results; - } - } - } - //https://developers.hubspot.com/docs/methods/forms/forms_overview - if (resource === 'form') { - //https://developers.hubspot.com/docs/methods/forms/v2/get_fields - if (operation === 'getFields') { - const formId = this.getNodeParameter('formId', i) as string; - responseData = await hubspotApiRequest.call(this, 'GET', `/forms/v2/fields/${formId}`); - } - //https://developers.hubspot.com/docs/methods/forms/submit_form_v3 - if (operation === 'submit') { - const formId = this.getNodeParameter('formId', i) as string; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const context = (this.getNodeParameter('contextUi', i) as IDataObject).contextValue as IDataObject; - const legalConsent = (this.getNodeParameter('lengalConsentUi', i) as IDataObject).lengalConsentValues as IDataObject; - const legitimateInteres = (this.getNodeParameter('lengalConsentUi', i) as IDataObject).legitimateInterestValues as IDataObject; - const { portalId } = await hubspotApiRequest.call(this, 'GET', `/forms/v2/forms/${formId}`); - const body: IForm = { - formId, - portalId, - legalConsentOptions: {}, - fields: [], - }; - if (additionalFields.submittedAt) { - body.submittedAt = new Date(additionalFields.submittedAt as string).getTime(); - } - if (additionalFields.skipValidation) { - body.skipValidation = additionalFields.skipValidation as boolean; - } - const consent: IDataObject = {}; - if (legalConsent) { - if (legalConsent.consentToProcess) { - consent!.consentToProcess = legalConsent.consentToProcess as boolean; - } - if (legalConsent.text) { - consent!.text = legalConsent.text as string; - } - if (legalConsent.communicationsUi) { - consent.communications = (legalConsent.communicationsUi as IDataObject).communicationValues as IDataObject; + responseData = await hubspotApiRequestAllItems.call(this, 'results', 'POST', endpoint, body, qs); + + } else { + body.limit = this.getNodeParameter('limit', 0) as number; + responseData = await hubspotApiRequest.call(this, 'POST', endpoint, body, qs); + responseData = responseData.results; } } - body.legalConsentOptions!.consent = consent; - const fields: IDataObject = items[i].json; - for (const key of Object.keys(fields)) { - body.fields?.push({ name: key, value: fields[key] }); - } - if (body.legalConsentOptions!.legitimateInterest) { - Object.assign(body, { legalConsentOptions: { legitimateInterest: legitimateInteres } }); - } - if (context) { - Object.assign(body, { context }); - } - const uri = `https://api.hsforms.com/submissions/v3/integration/submit/${portalId}/${formId}`; - responseData = await hubspotApiRequest.call(this, 'POST', '', body, {}, uri); } - } - //https://developers.hubspot.com/docs/methods/tickets/tickets-overview - if (resource === 'ticket') { - //https://developers.hubspot.com/docs/methods/tickets/create-ticket - if (operation === 'create') { - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const pipelineId = this.getNodeParameter('pipelineId', i) as string; - const stageId = this.getNodeParameter('stageId', i) as string; - const ticketName = this.getNodeParameter('ticketName', i) as string; - const body: IDataObject[] = [ - { - name: 'hs_pipeline', - value: pipelineId, - }, - { - name: 'hs_pipeline_stage', - value: stageId, - }, - { - name: 'subject', - value: ticketName, - }, - ]; - if (additionalFields.category) { - body.push({ - name: 'hs_ticket_category', - value: additionalFields.category as string, - }); + //https://developers.hubspot.com/docs/methods/forms/forms_overview + if (resource === 'form') { + //https://developers.hubspot.com/docs/methods/forms/v2/get_fields + if (operation === 'getFields') { + const formId = this.getNodeParameter('formId', i) as string; + responseData = await hubspotApiRequest.call(this, 'GET', `/forms/v2/fields/${formId}`); } - if (additionalFields.closeDate) { - body.push({ - name: 'closed_date', - value: new Date(additionalFields.closeDate as string).getTime(), - }); + //https://developers.hubspot.com/docs/methods/forms/submit_form_v3 + if (operation === 'submit') { + const formId = this.getNodeParameter('formId', i) as string; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const context = (this.getNodeParameter('contextUi', i) as IDataObject).contextValue as IDataObject; + const legalConsent = (this.getNodeParameter('lengalConsentUi', i) as IDataObject).lengalConsentValues as IDataObject; + const legitimateInteres = (this.getNodeParameter('lengalConsentUi', i) as IDataObject).legitimateInterestValues as IDataObject; + const { portalId } = await hubspotApiRequest.call(this, 'GET', `/forms/v2/forms/${formId}`); + const body: IForm = { + formId, + portalId, + legalConsentOptions: {}, + fields: [], + }; + if (additionalFields.submittedAt) { + body.submittedAt = new Date(additionalFields.submittedAt as string).getTime(); + } + if (additionalFields.skipValidation) { + body.skipValidation = additionalFields.skipValidation as boolean; + } + const consent: IDataObject = {}; + if (legalConsent) { + if (legalConsent.consentToProcess) { + consent!.consentToProcess = legalConsent.consentToProcess as boolean; + } + if (legalConsent.text) { + consent!.text = legalConsent.text as string; + } + if (legalConsent.communicationsUi) { + consent.communications = (legalConsent.communicationsUi as IDataObject).communicationValues as IDataObject; + } + } + body.legalConsentOptions!.consent = consent; + const fields: IDataObject = items[i].json; + for (const key of Object.keys(fields)) { + body.fields?.push({ name: key, value: fields[key] }); + } + if (body.legalConsentOptions!.legitimateInterest) { + Object.assign(body, { legalConsentOptions: { legitimateInterest: legitimateInteres } }); + } + if (context) { + Object.assign(body, { context }); + } + const uri = `https://api.hsforms.com/submissions/v3/integration/submit/${portalId}/${formId}`; + responseData = await hubspotApiRequest.call(this, 'POST', '', body, {}, uri); } - if (additionalFields.createDate) { - body.push({ - name: 'createdate', - value: new Date(additionalFields.createDate as string).getTime(), - }); - } - if (additionalFields.description) { - body.push({ - name: 'content', - value: additionalFields.description as string, - }); - } - if (additionalFields.priority) { - body.push({ - name: 'hs_ticket_priority', - value: additionalFields.priority as string, - }); - } - if (additionalFields.resolution) { - body.push({ - name: 'hs_resolution', - value: additionalFields.resolution as string, - }); - } - if (additionalFields.source) { - body.push({ - name: 'source_type', - value: additionalFields.source as string, - }); - } - if (additionalFields.ticketOwnerId) { - body.push({ - name: 'hubspot_owner_id', - value: additionalFields.ticketOwnerId as string, - }); - } - const endpoint = '/crm-objects/v1/objects/tickets'; - responseData = await hubspotApiRequest.call(this, 'POST', endpoint, body); - - if (additionalFields.associatedCompanyIds) { - const companyAssociations: IDataObject[] = []; - for (const companyId of additionalFields.associatedCompanyIds as IDataObject[]) { - companyAssociations.push({ - fromObjectId: responseData.objectId, - toObjectId: companyId, - category: 'HUBSPOT_DEFINED', - definitionId: 26, + } + //https://developers.hubspot.com/docs/methods/tickets/tickets-overview + if (resource === 'ticket') { + //https://developers.hubspot.com/docs/methods/tickets/create-ticket + if (operation === 'create') { + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const pipelineId = this.getNodeParameter('pipelineId', i) as string; + const stageId = this.getNodeParameter('stageId', i) as string; + const ticketName = this.getNodeParameter('ticketName', i) as string; + const body: IDataObject[] = [ + { + name: 'hs_pipeline', + value: pipelineId, + }, + { + name: 'hs_pipeline_stage', + value: stageId, + }, + { + name: 'subject', + value: ticketName, + }, + ]; + if (additionalFields.category) { + body.push({ + name: 'hs_ticket_category', + value: additionalFields.category as string, }); } - await hubspotApiRequest.call(this, 'PUT', '/crm-associations/v1/associations/create-batch', companyAssociations); - } - - if (additionalFields.associatedContactIds) { - const contactAssociations: IDataObject[] = []; - for (const contactId of additionalFields.associatedContactIds as IDataObject[]) { - contactAssociations.push({ - fromObjectId: responseData.objectId, - toObjectId: contactId, - category: 'HUBSPOT_DEFINED', - definitionId: 16, + if (additionalFields.closeDate) { + body.push({ + name: 'closed_date', + value: new Date(additionalFields.closeDate as string).getTime(), }); } - await hubspotApiRequest.call(this, 'PUT', '/crm-associations/v1/associations/create-batch', contactAssociations); - } - } - //https://developers.hubspot.com/docs/methods/tickets/get_ticket_by_id - if (operation === 'get') { - const ticketId = this.getNodeParameter('ticketId', i) as string; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - if (additionalFields.properties) { - qs.properties = additionalFields.properties as string[]; - } - if (additionalFields.propertiesWithHistory) { - qs.propertiesWithHistory = (additionalFields.propertiesWithHistory as string).split(','); - } - if (additionalFields.includeDeleted) { - qs.includeDeleted = additionalFields.includeDeleted as boolean; - } - const endpoint = `/crm-objects/v1/objects/tickets/${ticketId}`; - responseData = await hubspotApiRequest.call(this, 'GET', endpoint, {}, qs); - } - //https://developers.hubspot.com/docs/methods/tickets/get-all-tickets - if (operation === 'getAll') { - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const returnAll = this.getNodeParameter('returnAll', 0) as boolean; - if (additionalFields.properties) { - qs.properties = additionalFields.properties as string[]; - } - if (additionalFields.propertiesWithHistory) { - qs.propertiesWithHistory = (additionalFields.propertiesWithHistory as string).split(','); - } - const endpoint = `/crm-objects/v1/objects/tickets/paged`; - if (returnAll) { - responseData = await hubspotApiRequestAllItems.call(this, 'objects', 'GET', endpoint, {}, qs); - } else { - qs.limit = this.getNodeParameter('limit', 0) as number; - responseData = await hubspotApiRequestAllItems.call(this, 'objects', 'GET', endpoint, {}, qs); - responseData = responseData.splice(0, qs.limit); - } - } - //https://developers.hubspot.com/docs/methods/tickets/delete-ticket - if (operation === 'delete') { - const ticketId = this.getNodeParameter('ticketId', i) as string; - const endpoint = `/crm-objects/v1/objects/tickets/${ticketId}`; - await hubspotApiRequest.call(this, 'DELETE', endpoint); - responseData = { success: true }; - } - //https://developers.hubspot.com/docs/methods/tickets/update-ticket - if (operation === 'update') { - const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; - const ticketId = this.getNodeParameter('ticketId', i) as string; - const body: IDataObject[] = []; - if (updateFields.pipelineId) { - body.push({ - name: 'hs_pipeline', - value: updateFields.pipelineId as string, - }); - } - if (updateFields.ticketName) { - body.push({ - name: 'subject', - value: updateFields.ticketName as string, - }); - } - if (updateFields.category) { - body.push({ - name: 'hs_ticket_category', - value: updateFields.category as string, - }); - } - if (updateFields.closeDate) { - body.push({ - name: 'closed_date', - value: new Date(updateFields.createDate as string).getTime(), - }); - } - if (updateFields.createDate) { - body.push({ - name: 'createdate', - value: new Date(updateFields.createDate as string).getTime(), - }); - } - if (updateFields.description) { - body.push({ - name: 'content', - value: updateFields.description as string, - }); - } - if (updateFields.priority) { - body.push({ - name: 'hs_ticket_priority', - value: updateFields.priority as string, - }); - } - if (updateFields.resolution) { - body.push({ - name: 'hs_resolution', - value: updateFields.resolution as string, - }); - } - if (updateFields.source) { - body.push({ - name: 'source_type', - value: updateFields.source as string, - }); - } - if (updateFields.ticketOwnerId) { - body.push({ - name: 'hubspot_owner_id', - value: updateFields.ticketOwnerId as string, - }); - } - const endpoint = `/crm-objects/v1/objects/tickets/${ticketId}`; - responseData = await hubspotApiRequest.call(this, 'PUT', endpoint, body); - - if (updateFields.associatedCompanyIds) { - const companyAssociations: IDataObject[] = []; - for (const companyId of updateFields.associatedCompanyIds as IDataObject[]) { - companyAssociations.push({ - fromObjectId: responseData.objectId, - toObjectId: companyId, - category: 'HUBSPOT_DEFINED', - definitionId: 26, + if (additionalFields.createDate) { + body.push({ + name: 'createdate', + value: new Date(additionalFields.createDate as string).getTime(), }); } - await hubspotApiRequest.call(this, 'PUT', '/crm-associations/v1/associations/create-batch', companyAssociations); - } - - if (updateFields.associatedContactIds) { - const contactAssociations: IDataObject[] = []; - for (const contactId of updateFields.associatedContactIds as IDataObject[]) { - contactAssociations.push({ - fromObjectId: responseData.objectId, - toObjectId: contactId, - category: 'HUBSPOT_DEFINED', - definitionId: 16, + if (additionalFields.description) { + body.push({ + name: 'content', + value: additionalFields.description as string, }); } - await hubspotApiRequest.call(this, 'PUT', '/crm-associations/v1/associations/create-batch', contactAssociations); + if (additionalFields.priority) { + body.push({ + name: 'hs_ticket_priority', + value: additionalFields.priority as string, + }); + } + if (additionalFields.resolution) { + body.push({ + name: 'hs_resolution', + value: additionalFields.resolution as string, + }); + } + if (additionalFields.source) { + body.push({ + name: 'source_type', + value: additionalFields.source as string, + }); + } + if (additionalFields.ticketOwnerId) { + body.push({ + name: 'hubspot_owner_id', + value: additionalFields.ticketOwnerId as string, + }); + } + const endpoint = '/crm-objects/v1/objects/tickets'; + responseData = await hubspotApiRequest.call(this, 'POST', endpoint, body); + + if (additionalFields.associatedCompanyIds) { + const companyAssociations: IDataObject[] = []; + for (const companyId of additionalFields.associatedCompanyIds as IDataObject[]) { + companyAssociations.push({ + fromObjectId: responseData.objectId, + toObjectId: companyId, + category: 'HUBSPOT_DEFINED', + definitionId: 26, + }); + } + await hubspotApiRequest.call(this, 'PUT', '/crm-associations/v1/associations/create-batch', companyAssociations); + } + + if (additionalFields.associatedContactIds) { + const contactAssociations: IDataObject[] = []; + for (const contactId of additionalFields.associatedContactIds as IDataObject[]) { + contactAssociations.push({ + fromObjectId: responseData.objectId, + toObjectId: contactId, + category: 'HUBSPOT_DEFINED', + definitionId: 16, + }); + } + await hubspotApiRequest.call(this, 'PUT', '/crm-associations/v1/associations/create-batch', contactAssociations); + } + } + //https://developers.hubspot.com/docs/methods/tickets/get_ticket_by_id + if (operation === 'get') { + const ticketId = this.getNodeParameter('ticketId', i) as string; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + if (additionalFields.properties) { + qs.properties = additionalFields.properties as string[]; + } + if (additionalFields.propertiesWithHistory) { + qs.propertiesWithHistory = (additionalFields.propertiesWithHistory as string).split(','); + } + if (additionalFields.includeDeleted) { + qs.includeDeleted = additionalFields.includeDeleted as boolean; + } + const endpoint = `/crm-objects/v1/objects/tickets/${ticketId}`; + responseData = await hubspotApiRequest.call(this, 'GET', endpoint, {}, qs); + } + //https://developers.hubspot.com/docs/methods/tickets/get-all-tickets + if (operation === 'getAll') { + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const returnAll = this.getNodeParameter('returnAll', 0) as boolean; + if (additionalFields.properties) { + qs.properties = additionalFields.properties as string[]; + } + if (additionalFields.propertiesWithHistory) { + qs.propertiesWithHistory = (additionalFields.propertiesWithHistory as string).split(','); + } + const endpoint = `/crm-objects/v1/objects/tickets/paged`; + if (returnAll) { + responseData = await hubspotApiRequestAllItems.call(this, 'objects', 'GET', endpoint, {}, qs); + } else { + qs.limit = this.getNodeParameter('limit', 0) as number; + responseData = await hubspotApiRequestAllItems.call(this, 'objects', 'GET', endpoint, {}, qs); + responseData = responseData.splice(0, qs.limit); + } + } + //https://developers.hubspot.com/docs/methods/tickets/delete-ticket + if (operation === 'delete') { + const ticketId = this.getNodeParameter('ticketId', i) as string; + const endpoint = `/crm-objects/v1/objects/tickets/${ticketId}`; + await hubspotApiRequest.call(this, 'DELETE', endpoint); + responseData = { success: true }; + } + //https://developers.hubspot.com/docs/methods/tickets/update-ticket + if (operation === 'update') { + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + const ticketId = this.getNodeParameter('ticketId', i) as string; + const body: IDataObject[] = []; + if (updateFields.pipelineId) { + body.push({ + name: 'hs_pipeline', + value: updateFields.pipelineId as string, + }); + } + if (updateFields.ticketName) { + body.push({ + name: 'subject', + value: updateFields.ticketName as string, + }); + } + if (updateFields.category) { + body.push({ + name: 'hs_ticket_category', + value: updateFields.category as string, + }); + } + if (updateFields.closeDate) { + body.push({ + name: 'closed_date', + value: new Date(updateFields.createDate as string).getTime(), + }); + } + if (updateFields.createDate) { + body.push({ + name: 'createdate', + value: new Date(updateFields.createDate as string).getTime(), + }); + } + if (updateFields.description) { + body.push({ + name: 'content', + value: updateFields.description as string, + }); + } + if (updateFields.priority) { + body.push({ + name: 'hs_ticket_priority', + value: updateFields.priority as string, + }); + } + if (updateFields.resolution) { + body.push({ + name: 'hs_resolution', + value: updateFields.resolution as string, + }); + } + if (updateFields.source) { + body.push({ + name: 'source_type', + value: updateFields.source as string, + }); + } + if (updateFields.ticketOwnerId) { + body.push({ + name: 'hubspot_owner_id', + value: updateFields.ticketOwnerId as string, + }); + } + const endpoint = `/crm-objects/v1/objects/tickets/${ticketId}`; + responseData = await hubspotApiRequest.call(this, 'PUT', endpoint, body); + + if (updateFields.associatedCompanyIds) { + const companyAssociations: IDataObject[] = []; + for (const companyId of updateFields.associatedCompanyIds as IDataObject[]) { + companyAssociations.push({ + fromObjectId: responseData.objectId, + toObjectId: companyId, + category: 'HUBSPOT_DEFINED', + definitionId: 26, + }); + } + await hubspotApiRequest.call(this, 'PUT', '/crm-associations/v1/associations/create-batch', companyAssociations); + } + + if (updateFields.associatedContactIds) { + const contactAssociations: IDataObject[] = []; + for (const contactId of updateFields.associatedContactIds as IDataObject[]) { + contactAssociations.push({ + fromObjectId: responseData.objectId, + toObjectId: contactId, + category: 'HUBSPOT_DEFINED', + definitionId: 16, + }); + } + await hubspotApiRequest.call(this, 'PUT', '/crm-associations/v1/associations/create-batch', contactAssociations); + } } } - } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else { - returnData.push(responseData as IDataObject); + if (Array.isArray(responseData)) { + returnData.push.apply(returnData, responseData as IDataObject[]); + } else { + returnData.push(responseData as IDataObject); + } + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } } } diff --git a/packages/nodes-base/nodes/Hunter/Hunter.node.ts b/packages/nodes-base/nodes/Hunter/Hunter.node.ts index c3f6d147d7..2fceda8df5 100644 --- a/packages/nodes-base/nodes/Hunter/Hunter.node.ts +++ b/packages/nodes-base/nodes/Hunter/Hunter.node.ts @@ -292,85 +292,93 @@ export class Hunter implements INodeType { const qs: IDataObject = {}; let responseData; for (let i = 0; i < length; i++) { - const operation = this.getNodeParameter('operation', 0) as string; - //https://hunter.io/api-documentation/v2#domain-search - if (operation === 'domainSearch') { - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - const filters = this.getNodeParameter('filters', i) as IDataObject; - const domain = this.getNodeParameter('domain', i) as string; - const onlyEmails = this.getNodeParameter('onlyEmails', i, false) as boolean; + try { + const operation = this.getNodeParameter('operation', 0) as string; + //https://hunter.io/api-documentation/v2#domain-search + if (operation === 'domainSearch') { + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + const filters = this.getNodeParameter('filters', i) as IDataObject; + const domain = this.getNodeParameter('domain', i) as string; + const onlyEmails = this.getNodeParameter('onlyEmails', i, false) as boolean; - qs.domain = domain; - if (filters.type){ - qs.type = filters.type; - } - if (filters.seniority){ - qs.seniority = (filters.seniority as string[]).join(','); - } - if (filters.department){ - qs.department = (filters.department as string[]).join(','); - } - if (returnAll) { - responseData = await hunterApiRequestAllItems.call(this, 'data', 'GET', '/domain-search', {}, qs); + qs.domain = domain; + if (filters.type){ + qs.type = filters.type; + } + if (filters.seniority){ + qs.seniority = (filters.seniority as string[]).join(','); + } + if (filters.department){ + qs.department = (filters.department as string[]).join(','); + } + if (returnAll) { + responseData = await hunterApiRequestAllItems.call(this, 'data', 'GET', '/domain-search', {}, qs); - // Make sure that the company information is there only once and - // the emails are combined underneath it. - if (onlyEmails === false) { - let tempReturnData: IDataObject = {}; + // Make sure that the company information is there only once and + // the emails are combined underneath it. + if (onlyEmails === false) { + let tempReturnData: IDataObject = {}; - for (let i = 0; i < responseData.length; i++) { - if (i === 0) { - tempReturnData = responseData[i]; - continue; + for (let i = 0; i < responseData.length; i++) { + if (i === 0) { + tempReturnData = responseData[i]; + continue; + } + ((tempReturnData as IDataObject).emails as IDataObject[]).push.apply(tempReturnData.emails, responseData[i].emails); } - ((tempReturnData as IDataObject).emails as IDataObject[]).push.apply(tempReturnData.emails, responseData[i].emails); + + responseData = tempReturnData; + } + } else { + const limit = this.getNodeParameter('limit', i) as number; + qs.limit = limit; + responseData = await hunterApiRequest.call(this, 'GET', '/domain-search', {}, qs); + responseData = responseData.data; + } + + if (onlyEmails === true) { + let tempReturnData: IDataObject[] = []; + + if (Array.isArray(responseData)) { + for (const data of responseData) { + tempReturnData.push.apply(tempReturnData, data.emails); + } + } else { + tempReturnData = responseData.emails; } responseData = tempReturnData; } - } else { - const limit = this.getNodeParameter('limit', i) as number; - qs.limit = limit; - responseData = await hunterApiRequest.call(this, 'GET', '/domain-search', {}, qs); + } + //https://hunter.io/api-documentation/v2#email-finder + if (operation === 'emailFinder') { + const domain = this.getNodeParameter('domain', i) as string; + const firstname = this.getNodeParameter('firstname', i) as string; + const lastname = this.getNodeParameter('lastname', i) as string; + qs.first_name = firstname; + qs.last_name = lastname; + qs.domain = domain; + responseData = await hunterApiRequest.call(this, 'GET', '/email-finder', {}, qs); responseData = responseData.data; } - - if (onlyEmails === true) { - let tempReturnData: IDataObject[] = []; - - if (Array.isArray(responseData)) { - for (const data of responseData) { - tempReturnData.push.apply(tempReturnData, data.emails); - } - } else { - tempReturnData = responseData.emails; - } - - responseData = tempReturnData; + //https://hunter.io/api-documentation/v2#email-verifier + if (operation === 'emailVerifier') { + const email = this.getNodeParameter('email', i) as string; + qs.email = email; + responseData = await hunterApiRequest.call(this, 'GET', '/email-verifier', {}, qs); + responseData = responseData.data; } - } - //https://hunter.io/api-documentation/v2#email-finder - if (operation === 'emailFinder') { - const domain = this.getNodeParameter('domain', i) as string; - const firstname = this.getNodeParameter('firstname', i) as string; - const lastname = this.getNodeParameter('lastname', i) as string; - qs.first_name = firstname; - qs.last_name = lastname; - qs.domain = domain; - responseData = await hunterApiRequest.call(this, 'GET', '/email-finder', {}, qs); - responseData = responseData.data; - } - //https://hunter.io/api-documentation/v2#email-verifier - if (operation === 'emailVerifier') { - const email = this.getNodeParameter('email', i) as string; - qs.email = email; - responseData = await hunterApiRequest.call(this, 'GET', '/email-verifier', {}, qs); - responseData = responseData.data; - } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else { - returnData.push(responseData as IDataObject); + if (Array.isArray(responseData)) { + returnData.push.apply(returnData, responseData as IDataObject[]); + } else { + returnData.push(responseData as IDataObject); + } + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } } return [this.helpers.returnJsonArray(returnData)]; diff --git a/packages/nodes-base/nodes/Intercom/Intercom.node.ts b/packages/nodes-base/nodes/Intercom/Intercom.node.ts index ac53077900..0c51c7fe68 100644 --- a/packages/nodes-base/nodes/Intercom/Intercom.node.ts +++ b/packages/nodes-base/nodes/Intercom/Intercom.node.ts @@ -127,429 +127,437 @@ export class Intercom implements INodeType { let qs: IDataObject; let responseData; for (let i = 0; i < length; i++) { - qs = {}; - const resource = this.getNodeParameter('resource', 0) as string; - const operation = this.getNodeParameter('operation', 0) as string; - //https://developers.intercom.com/intercom-api-reference/reference#leads - if (resource === 'lead') { - if (operation === 'create' || operation === 'update') { - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const jsonActive = this.getNodeParameter('jsonParameters', i) as boolean; - const body: ILead = {}; - if (operation === 'create') { - body.email = this.getNodeParameter('email', i) as string; - } - if (additionalFields.email) { - body.email = additionalFields.email as string; - } - if (additionalFields.phone) { - body.phone = additionalFields.phone as string; - } - if (additionalFields.name) { - body.name = additionalFields.name as string; - } - if (additionalFields.unsubscribedFromEmails) { - body.unsubscribed_from_emails = additionalFields.unsubscribedFromEmails as boolean; - } - if (additionalFields.updateLastRequestAt) { - body.update_last_request_at = additionalFields.updateLastRequestAt as boolean; - } - if (additionalFields.utmSource) { - body.utm_source = additionalFields.utmSource as string; - } - if (additionalFields.utmMedium) { - body.utm_medium = additionalFields.utmMedium as string; - } - if (additionalFields.utmCampaign) { - body.utm_campaign = additionalFields.utmCampaign as string; - } - if (additionalFields.utmTerm) { - body.utm_term = additionalFields.utmTerm as string; - } - if (additionalFields.utmContent) { - body.utm_content = additionalFields.utmContent as string; - } - if (additionalFields.avatar) { - const avatar: IAvatar = { - type: 'avatar', - image_url: additionalFields.avatar as string, - }; - body.avatar = avatar; - } - if (additionalFields.companies) { - const companies: ILeadCompany[] = []; - // @ts-ignore - additionalFields.companies.forEach(o => { - const company: ILeadCompany = {}; - company.company_id = o; - companies.push(company); - }); - body.companies = companies; - } - if (!jsonActive) { - const customAttributesValues = (this.getNodeParameter('customAttributesUi', i) as IDataObject).customAttributesValues as IDataObject[]; - if (customAttributesValues) { - const customAttributes = {}; - for (let i = 0; i < customAttributesValues.length; i++) { - // @ts-ignore - customAttributes[customAttributesValues[i].name] = customAttributesValues[i].value; + try { + qs = {}; + const resource = this.getNodeParameter('resource', 0) as string; + const operation = this.getNodeParameter('operation', 0) as string; + //https://developers.intercom.com/intercom-api-reference/reference#leads + if (resource === 'lead') { + if (operation === 'create' || operation === 'update') { + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const jsonActive = this.getNodeParameter('jsonParameters', i) as boolean; + const body: ILead = {}; + if (operation === 'create') { + body.email = this.getNodeParameter('email', i) as string; + } + if (additionalFields.email) { + body.email = additionalFields.email as string; + } + if (additionalFields.phone) { + body.phone = additionalFields.phone as string; + } + if (additionalFields.name) { + body.name = additionalFields.name as string; + } + if (additionalFields.unsubscribedFromEmails) { + body.unsubscribed_from_emails = additionalFields.unsubscribedFromEmails as boolean; + } + if (additionalFields.updateLastRequestAt) { + body.update_last_request_at = additionalFields.updateLastRequestAt as boolean; + } + if (additionalFields.utmSource) { + body.utm_source = additionalFields.utmSource as string; + } + if (additionalFields.utmMedium) { + body.utm_medium = additionalFields.utmMedium as string; + } + if (additionalFields.utmCampaign) { + body.utm_campaign = additionalFields.utmCampaign as string; + } + if (additionalFields.utmTerm) { + body.utm_term = additionalFields.utmTerm as string; + } + if (additionalFields.utmContent) { + body.utm_content = additionalFields.utmContent as string; + } + if (additionalFields.avatar) { + const avatar: IAvatar = { + type: 'avatar', + image_url: additionalFields.avatar as string, + }; + body.avatar = avatar; + } + if (additionalFields.companies) { + const companies: ILeadCompany[] = []; + // @ts-ignore + additionalFields.companies.forEach(o => { + const company: ILeadCompany = {}; + company.company_id = o; + companies.push(company); + }); + body.companies = companies; + } + if (!jsonActive) { + const customAttributesValues = (this.getNodeParameter('customAttributesUi', i) as IDataObject).customAttributesValues as IDataObject[]; + if (customAttributesValues) { + const customAttributes = {}; + for (let i = 0; i < customAttributesValues.length; i++) { + // @ts-ignore + customAttributes[customAttributesValues[i].name] = customAttributesValues[i].value; + } + body.custom_attributes = customAttributes; + } + } else { + const customAttributesJson = validateJSON(this.getNodeParameter('customAttributesJson', i) as string); + if (customAttributesJson) { + body.custom_attributes = customAttributesJson; } - body.custom_attributes = customAttributes; } - } else { - const customAttributesJson = validateJSON(this.getNodeParameter('customAttributesJson', i) as string); - if (customAttributesJson) { - body.custom_attributes = customAttributesJson; + + if (operation === 'update') { + const updateBy = this.getNodeParameter('updateBy', 0) as string; + const value = this.getNodeParameter('value', i) as string; + if (updateBy === 'userId') { + body.user_id = value; + } + if (updateBy === 'id') { + body.id = value; + } + } + + try { + responseData = await intercomApiRequest.call(this, '/contacts', 'POST', body); + } catch (error) { + throw new NodeApiError(this.getNode(), error); } } - - if (operation === 'update') { - const updateBy = this.getNodeParameter('updateBy', 0) as string; + if (operation === 'get') { + const selectBy = this.getNodeParameter('selectBy', 0) as string; const value = this.getNodeParameter('value', i) as string; - if (updateBy === 'userId') { - body.user_id = value; + if (selectBy === 'email') { + qs.email = value; } - if (updateBy === 'id') { - body.id = value; - } - } - - try { - responseData = await intercomApiRequest.call(this, '/contacts', 'POST', body); - } catch (error) { - throw new NodeApiError(this.getNode(), error); - } - } - if (operation === 'get') { - const selectBy = this.getNodeParameter('selectBy', 0) as string; - const value = this.getNodeParameter('value', i) as string; - if (selectBy === 'email') { - qs.email = value; - } - if (selectBy === 'userId') { - qs.user_id = value; - } - if (selectBy === 'phone') { - qs.phone = value; - } - try { - if (selectBy === 'id') { - responseData = await intercomApiRequest.call(this, `/contacts/${value}`, 'GET'); - } else { - responseData = await intercomApiRequest.call(this, '/contacts', 'GET', {}, qs); - responseData = responseData.contacts; - } - } catch (error) { - throw new NodeApiError(this.getNode(), error); - } - } - if (operation === 'getAll') { - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - const filters = this.getNodeParameter('filters', i) as IDataObject; - Object.assign(qs, filters); - - try { - if (returnAll === true) { - responseData = await intercomApiRequestAllItems.call(this, 'contacts', '/contacts', 'GET', {}, qs); - } else { - qs.per_page = this.getNodeParameter('limit', i) as number; - responseData = await intercomApiRequest.call(this, '/contacts', 'GET', {}, qs); - responseData = responseData.contacts; - } - } catch (error) { - throw new NodeApiError(this.getNode(), error); - } - } - if (operation === 'delete') { - const deleteBy = this.getNodeParameter('deleteBy', 0) as string; - const value = this.getNodeParameter('value', i) as string; - try { - if (deleteBy === 'id') { - responseData = await intercomApiRequest.call(this, `/contacts/${value}`, 'DELETE'); - } else { + if (selectBy === 'userId') { qs.user_id = value; - responseData = await intercomApiRequest.call(this, '/contacts', 'DELETE', {}, qs); } - } catch (error) { - throw new NodeApiError(this.getNode(), error); - } - } - } - //https://developers.intercom.com/intercom-api-reference/reference#users - if (resource === 'user') { - if (operation === 'create' || operation === 'update') { - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const jsonActive = this.getNodeParameter('jsonParameters', i) as boolean; - const body: IUser = {}; - - if (operation === 'create') { - const identifierType = this.getNodeParameter('identifierType', i) as string; - if (identifierType === 'email') { - body.email = this.getNodeParameter('idValue', i) as string; - } else if (identifierType === 'userId') { - body.user_id = this.getNodeParameter('idValue', i) as string; + if (selectBy === 'phone') { + qs.phone = value; } - } - - if (additionalFields.email) { - body.email = additionalFields.email as string; - } - if (additionalFields.userId) { - body.user_id = additionalFields.userId as string; - } - if (additionalFields.phone) { - body.phone = additionalFields.phone as string; - } - if (additionalFields.name) { - body.name = additionalFields.name as string; - } - if (additionalFields.unsubscribedFromEmails) { - body.unsubscribed_from_emails = additionalFields.unsubscribedFromEmails as boolean; - } - if (additionalFields.updateLastRequestAt) { - body.update_last_request_at = additionalFields.updateLastRequestAt as boolean; - } - if (additionalFields.sessionCount) { - body.session_count = additionalFields.sessionCount as number; - } - if (additionalFields.avatar) { - const avatar: IAvatar = { - type: 'avatar', - image_url: additionalFields.avatar as string, - }; - body.avatar = avatar; - } - if (additionalFields.utmSource) { - body.utm_source = additionalFields.utmSource as string; - } - if (additionalFields.utmMedium) { - body.utm_medium = additionalFields.utmMedium as string; - } - if (additionalFields.utmCampaign) { - body.utm_campaign = additionalFields.utmCampaign as string; - } - if (additionalFields.utmTerm) { - body.utm_term = additionalFields.utmTerm as string; - } - if (additionalFields.utmContent) { - body.utm_content = additionalFields.utmContent as string; - } - if (additionalFields.companies) { - const companies: IUserCompany[] = []; - // @ts-ignore - additionalFields.companies.forEach(o => { - const company: IUserCompany = {}; - company.company_id = o; - companies.push(company); - }); - body.companies = companies; - } - if (additionalFields.sessionCount) { - body.session_count = additionalFields.sessionCount as number; - } - if (!jsonActive) { - const customAttributesValues = (this.getNodeParameter('customAttributesUi', i) as IDataObject).customAttributesValues as IDataObject[]; - if (customAttributesValues) { - const customAttributes = {}; - for (let i = 0; i < customAttributesValues.length; i++) { - // @ts-ignore - customAttributes[customAttributesValues[i].name] = customAttributesValues[i].value; + try { + if (selectBy === 'id') { + responseData = await intercomApiRequest.call(this, `/contacts/${value}`, 'GET'); + } else { + responseData = await intercomApiRequest.call(this, '/contacts', 'GET', {}, qs); + responseData = responseData.contacts; } - body.custom_attributes = customAttributes; - } - } else { - const customAttributesJson = validateJSON(this.getNodeParameter('customAttributesJson', i) as string); - if (customAttributesJson) { - body.custom_attributes = customAttributesJson; + } catch (error) { + throw new NodeApiError(this.getNode(), error); } } + if (operation === 'getAll') { + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + const filters = this.getNodeParameter('filters', i) as IDataObject; + Object.assign(qs, filters); - if (operation === 'update') { - const updateBy = this.getNodeParameter('updateBy', 0) as string; - const value = this.getNodeParameter('value', i) as string; - if (updateBy === 'userId') { - body.user_id = value; - } - if (updateBy === 'id') { - body.id = value; - } - if (updateBy === 'email') { - body.email = value; - } - } - - try { - responseData = await intercomApiRequest.call(this, '/users', 'POST', body, qs); - } catch (error) { - throw new NodeApiError(this.getNode(), error); - } - } - if (operation === 'get') { - const selectBy = this.getNodeParameter('selectBy', 0) as string; - const value = this.getNodeParameter('value', i) as string; - if (selectBy === 'userId') { - qs.user_id = value; - } - try { - if (selectBy === 'id') { - responseData = await intercomApiRequest.call(this, `/users/${value}`, 'GET', {}, qs); - } else { - responseData = await intercomApiRequest.call(this, '/users', 'GET', {}, qs); - } - } catch (error) { - throw new NodeApiError(this.getNode(), error); - } - } - if (operation === 'getAll') { - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - const filters = this.getNodeParameter('filters', i) as IDataObject; - Object.assign(qs, filters); - - try { - if (returnAll === true) { - responseData = await intercomApiRequestAllItems.call(this, 'users', '/users', 'GET', {}, qs); - } else { - qs.per_page = this.getNodeParameter('limit', i) as number; - responseData = await intercomApiRequest.call(this, '/users', 'GET', {}, qs); - responseData = responseData.users; - } - } catch (error) { - throw new NodeApiError(this.getNode(), error); - } - } - if (operation === 'delete') { - const id = this.getNodeParameter('id', i) as string; - try { - responseData = await intercomApiRequest.call(this, `/users/${id}`, 'DELETE'); - } catch (error) { - throw new NodeOperationError(this.getNode(), `Intercom Error: ${JSON.stringify(error)}`); - } - } - } - //https://developers.intercom.com/intercom-api-reference/reference#companies - if (resource === 'company') { - if (operation === 'create' || operation === 'update') { - const id = this.getNodeParameter('companyId', i) as string; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const jsonActive = this.getNodeParameter('jsonParameters', i) as boolean; - const body: ICompany = { - company_id: id, - }; - if (additionalFields.monthlySpend) { - body.monthly_spend = additionalFields.monthlySpend as number; - } - if (additionalFields.name) { - body.name = additionalFields.name as string; - } - if (additionalFields.plan) { - body.plan = additionalFields.plan as string; - } - if (additionalFields.size) { - body.size = additionalFields.size as number; - } - if (additionalFields.website) { - body.website = additionalFields.website as string; - } - if (additionalFields.industry) { - body.industry = additionalFields.industry as string; - } - if (!jsonActive) { - const customAttributesValues = (this.getNodeParameter('customAttributesUi', i) as IDataObject).customAttributesValues as IDataObject[]; - if (customAttributesValues) { - const customAttributes = {}; - for (let i = 0; i < customAttributesValues.length; i++) { - // @ts-ignore - customAttributes[customAttributesValues[i].name] = customAttributesValues[i].value; - } - body.custom_attributes = customAttributes; - } - } else { - const customAttributesJson = validateJSON(this.getNodeParameter('customAttributesJson', i) as string); - if (customAttributesJson) { - body.custom_attributes = customAttributesJson; - } - } - try { - responseData = await intercomApiRequest.call(this, '/companies', 'POST', body, qs); - } catch (error) { - throw new NodeOperationError(this.getNode(), `Intercom Error: ${JSON.stringify(error)}`); - } - } - if (operation === 'get') { - const selectBy = this.getNodeParameter('selectBy', 0) as string; - const value = this.getNodeParameter('value', i) as string; - if (selectBy === 'companyId') { - qs.company_id = value; - } - if (selectBy === 'name') { - qs.name = value; - } - try { - if (selectBy === 'id') { - responseData = await intercomApiRequest.call(this, `/companies/${value}`, 'GET', {}, qs); - } else { - responseData = await intercomApiRequest.call(this, '/companies', 'GET', {}, qs); - } - } catch (error) { - throw new NodeOperationError(this.getNode(), `Intercom Error: ${JSON.stringify(error)}`); - } - } - if (operation === 'getAll') { - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - const filters = this.getNodeParameter('filters', i) as IDataObject; - Object.assign(qs, filters); - - try { - if (returnAll === true) { - responseData = await intercomApiRequestAllItems.call(this, 'companies', '/companies', 'GET', {}, qs); - } else { - qs.per_page = this.getNodeParameter('limit', i) as number; - responseData = await intercomApiRequest.call(this, '/companies', 'GET', {}, qs); - responseData = responseData.companies; - } - } catch (error) { - throw new NodeOperationError(this.getNode(), `Intercom Error: ${JSON.stringify(error)}`); - } - } - if (operation === 'users') { - const listBy = this.getNodeParameter('listBy', 0) as string; - const value = this.getNodeParameter('value', i) as string; - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - - if (listBy === 'companyId') { - qs.company_id = value; - } - - try { - if (listBy === 'id') { + try { if (returnAll === true) { - responseData = await intercomApiRequestAllItems.call(this, 'users', `/companies/${value}/users`, 'GET', {}, qs); + responseData = await intercomApiRequestAllItems.call(this, 'contacts', '/contacts', 'GET', {}, qs); } else { qs.per_page = this.getNodeParameter('limit', i) as number; - responseData = await intercomApiRequest.call(this, `/companies/${value}/users`, 'GET', {}, qs); + responseData = await intercomApiRequest.call(this, '/contacts', 'GET', {}, qs); + responseData = responseData.contacts; + } + } catch (error) { + throw new NodeApiError(this.getNode(), error); + } + } + if (operation === 'delete') { + const deleteBy = this.getNodeParameter('deleteBy', 0) as string; + const value = this.getNodeParameter('value', i) as string; + try { + if (deleteBy === 'id') { + responseData = await intercomApiRequest.call(this, `/contacts/${value}`, 'DELETE'); + } else { + qs.user_id = value; + responseData = await intercomApiRequest.call(this, '/contacts', 'DELETE', {}, qs); + } + } catch (error) { + throw new NodeApiError(this.getNode(), error); + } + } + } + //https://developers.intercom.com/intercom-api-reference/reference#users + if (resource === 'user') { + if (operation === 'create' || operation === 'update') { + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const jsonActive = this.getNodeParameter('jsonParameters', i) as boolean; + const body: IUser = {}; + + if (operation === 'create') { + const identifierType = this.getNodeParameter('identifierType', i) as string; + if (identifierType === 'email') { + body.email = this.getNodeParameter('idValue', i) as string; + } else if (identifierType === 'userId') { + body.user_id = this.getNodeParameter('idValue', i) as string; + } + } + + if (additionalFields.email) { + body.email = additionalFields.email as string; + } + if (additionalFields.userId) { + body.user_id = additionalFields.userId as string; + } + if (additionalFields.phone) { + body.phone = additionalFields.phone as string; + } + if (additionalFields.name) { + body.name = additionalFields.name as string; + } + if (additionalFields.unsubscribedFromEmails) { + body.unsubscribed_from_emails = additionalFields.unsubscribedFromEmails as boolean; + } + if (additionalFields.updateLastRequestAt) { + body.update_last_request_at = additionalFields.updateLastRequestAt as boolean; + } + if (additionalFields.sessionCount) { + body.session_count = additionalFields.sessionCount as number; + } + if (additionalFields.avatar) { + const avatar: IAvatar = { + type: 'avatar', + image_url: additionalFields.avatar as string, + }; + body.avatar = avatar; + } + if (additionalFields.utmSource) { + body.utm_source = additionalFields.utmSource as string; + } + if (additionalFields.utmMedium) { + body.utm_medium = additionalFields.utmMedium as string; + } + if (additionalFields.utmCampaign) { + body.utm_campaign = additionalFields.utmCampaign as string; + } + if (additionalFields.utmTerm) { + body.utm_term = additionalFields.utmTerm as string; + } + if (additionalFields.utmContent) { + body.utm_content = additionalFields.utmContent as string; + } + if (additionalFields.companies) { + const companies: IUserCompany[] = []; + // @ts-ignore + additionalFields.companies.forEach(o => { + const company: IUserCompany = {}; + company.company_id = o; + companies.push(company); + }); + body.companies = companies; + } + if (additionalFields.sessionCount) { + body.session_count = additionalFields.sessionCount as number; + } + if (!jsonActive) { + const customAttributesValues = (this.getNodeParameter('customAttributesUi', i) as IDataObject).customAttributesValues as IDataObject[]; + if (customAttributesValues) { + const customAttributes = {}; + for (let i = 0; i < customAttributesValues.length; i++) { + // @ts-ignore + customAttributes[customAttributesValues[i].name] = customAttributesValues[i].value; + } + body.custom_attributes = customAttributes; + } + } else { + const customAttributesJson = validateJSON(this.getNodeParameter('customAttributesJson', i) as string); + if (customAttributesJson) { + body.custom_attributes = customAttributesJson; + } + } + + if (operation === 'update') { + const updateBy = this.getNodeParameter('updateBy', 0) as string; + const value = this.getNodeParameter('value', i) as string; + if (updateBy === 'userId') { + body.user_id = value; + } + if (updateBy === 'id') { + body.id = value; + } + if (updateBy === 'email') { + body.email = value; + } + } + + try { + responseData = await intercomApiRequest.call(this, '/users', 'POST', body, qs); + } catch (error) { + throw new NodeApiError(this.getNode(), error); + } + } + if (operation === 'get') { + const selectBy = this.getNodeParameter('selectBy', 0) as string; + const value = this.getNodeParameter('value', i) as string; + if (selectBy === 'userId') { + qs.user_id = value; + } + try { + if (selectBy === 'id') { + responseData = await intercomApiRequest.call(this, `/users/${value}`, 'GET', {}, qs); + } else { + responseData = await intercomApiRequest.call(this, '/users', 'GET', {}, qs); + } + } catch (error) { + throw new NodeApiError(this.getNode(), error); + } + } + if (operation === 'getAll') { + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + const filters = this.getNodeParameter('filters', i) as IDataObject; + Object.assign(qs, filters); + + try { + if (returnAll === true) { + responseData = await intercomApiRequestAllItems.call(this, 'users', '/users', 'GET', {}, qs); + } else { + qs.per_page = this.getNodeParameter('limit', i) as number; + responseData = await intercomApiRequest.call(this, '/users', 'GET', {}, qs); responseData = responseData.users; } - + } catch (error) { + throw new NodeApiError(this.getNode(), error); + } + } + if (operation === 'delete') { + const id = this.getNodeParameter('id', i) as string; + try { + responseData = await intercomApiRequest.call(this, `/users/${id}`, 'DELETE'); + } catch (error) { + throw new NodeOperationError(this.getNode(), `Intercom Error: ${JSON.stringify(error)}`); + } + } + } + //https://developers.intercom.com/intercom-api-reference/reference#companies + if (resource === 'company') { + if (operation === 'create' || operation === 'update') { + const id = this.getNodeParameter('companyId', i) as string; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const jsonActive = this.getNodeParameter('jsonParameters', i) as boolean; + const body: ICompany = { + company_id: id, + }; + if (additionalFields.monthlySpend) { + body.monthly_spend = additionalFields.monthlySpend as number; + } + if (additionalFields.name) { + body.name = additionalFields.name as string; + } + if (additionalFields.plan) { + body.plan = additionalFields.plan as string; + } + if (additionalFields.size) { + body.size = additionalFields.size as number; + } + if (additionalFields.website) { + body.website = additionalFields.website as string; + } + if (additionalFields.industry) { + body.industry = additionalFields.industry as string; + } + if (!jsonActive) { + const customAttributesValues = (this.getNodeParameter('customAttributesUi', i) as IDataObject).customAttributesValues as IDataObject[]; + if (customAttributesValues) { + const customAttributes = {}; + for (let i = 0; i < customAttributesValues.length; i++) { + // @ts-ignore + customAttributes[customAttributesValues[i].name] = customAttributesValues[i].value; + } + body.custom_attributes = customAttributes; + } } else { - qs.type = 'users'; + const customAttributesJson = validateJSON(this.getNodeParameter('customAttributesJson', i) as string); + if (customAttributesJson) { + body.custom_attributes = customAttributesJson; + } + } + try { + responseData = await intercomApiRequest.call(this, '/companies', 'POST', body, qs); + } catch (error) { + throw new NodeOperationError(this.getNode(), `Intercom Error: ${JSON.stringify(error)}`); + } + } + if (operation === 'get') { + const selectBy = this.getNodeParameter('selectBy', 0) as string; + const value = this.getNodeParameter('value', i) as string; + if (selectBy === 'companyId') { + qs.company_id = value; + } + if (selectBy === 'name') { + qs.name = value; + } + try { + if (selectBy === 'id') { + responseData = await intercomApiRequest.call(this, `/companies/${value}`, 'GET', {}, qs); + } else { + responseData = await intercomApiRequest.call(this, '/companies', 'GET', {}, qs); + } + } catch (error) { + throw new NodeOperationError(this.getNode(), `Intercom Error: ${JSON.stringify(error)}`); + } + } + if (operation === 'getAll') { + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + const filters = this.getNodeParameter('filters', i) as IDataObject; + Object.assign(qs, filters); + try { if (returnAll === true) { - responseData = await intercomApiRequestAllItems.call(this, 'users', '/companies', 'GET', {}, qs); + responseData = await intercomApiRequestAllItems.call(this, 'companies', '/companies', 'GET', {}, qs); } else { qs.per_page = this.getNodeParameter('limit', i) as number; responseData = await intercomApiRequest.call(this, '/companies', 'GET', {}, qs); - responseData = responseData.users; + responseData = responseData.companies; } + } catch (error) { + throw new NodeOperationError(this.getNode(), `Intercom Error: ${JSON.stringify(error)}`); + } + } + if (operation === 'users') { + const listBy = this.getNodeParameter('listBy', 0) as string; + const value = this.getNodeParameter('value', i) as string; + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + + if (listBy === 'companyId') { + qs.company_id = value; + } + + try { + if (listBy === 'id') { + if (returnAll === true) { + responseData = await intercomApiRequestAllItems.call(this, 'users', `/companies/${value}/users`, 'GET', {}, qs); + } else { + qs.per_page = this.getNodeParameter('limit', i) as number; + responseData = await intercomApiRequest.call(this, `/companies/${value}/users`, 'GET', {}, qs); + responseData = responseData.users; + } + + } else { + qs.type = 'users'; + + if (returnAll === true) { + responseData = await intercomApiRequestAllItems.call(this, 'users', '/companies', 'GET', {}, qs); + } else { + qs.per_page = this.getNodeParameter('limit', i) as number; + responseData = await intercomApiRequest.call(this, '/companies', 'GET', {}, qs); + responseData = responseData.users; + } + } + } catch (error) { + throw new NodeOperationError(this.getNode(), `Intercom Error: ${JSON.stringify(error)}`); } - } catch (error) { - throw new NodeOperationError(this.getNode(), `Intercom Error: ${JSON.stringify(error)}`); } } - } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else { - returnData.push(responseData as IDataObject); + if (Array.isArray(responseData)) { + returnData.push.apply(returnData, responseData as IDataObject[]); + } else { + returnData.push(responseData as IDataObject); + } + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } } return [this.helpers.returnJsonArray(returnData)]; diff --git a/packages/nodes-base/nodes/InvoiceNinja/InvoiceNinja.node.ts b/packages/nodes-base/nodes/InvoiceNinja/InvoiceNinja.node.ts index 3327997f7f..0ffcf7d347 100644 --- a/packages/nodes-base/nodes/InvoiceNinja/InvoiceNinja.node.ts +++ b/packages/nodes-base/nodes/InvoiceNinja/InvoiceNinja.node.ts @@ -250,556 +250,564 @@ export class InvoiceNinja implements INodeType { const operation = this.getNodeParameter('operation', 0) as string; for (let i = 0; i < length; i++) { //Routes: https://github.com/invoiceninja/invoiceninja/blob/ff455c8ed9fd0c0326956175ecd509efa8bad263/routes/api.php - if (resource === 'client') { - if (operation === 'create') { - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const body: IClient = {}; - if (additionalFields.clientName) { - body.name = additionalFields.clientName as string; - } - if (additionalFields.clientName) { - body.name = additionalFields.clientName as string; - } - if (additionalFields.idNumber) { - body.id_number = additionalFields.idNumber as string; - } - if (additionalFields.idNumber) { - body.id_number = additionalFields.idNumber as string; - } - if (additionalFields.privateNotes) { - body.private_notes = additionalFields.privateNotes as string; - } - if (additionalFields.vatNumber) { - body.vat_number = additionalFields.vatNumber as string; - } - if (additionalFields.workPhone) { - body.work_phone = additionalFields.workPhone as string; - } - if (additionalFields.website) { - body.website = additionalFields.website as string; - } - const contactsValues = (this.getNodeParameter('contactsUi', i) as IDataObject).contacstValues as IDataObject[]; - if (contactsValues) { - const contacts: IContact[] = []; - for (const contactValue of contactsValues) { - const contact: IContact = { - first_name: contactValue.firstName as string, - last_name: contactValue.lastName as string, - email: contactValue.email as string, - phone: contactValue.phone as string, - }; - contacts.push(contact); + try { + if (resource === 'client') { + if (operation === 'create') { + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const body: IClient = {}; + if (additionalFields.clientName) { + body.name = additionalFields.clientName as string; } - body.contacts = contacts; - } - const shippingAddressValue = (this.getNodeParameter('shippingAddressUi', i) as IDataObject).shippingAddressValue as IDataObject; - if (shippingAddressValue) { - body.shipping_address1 = shippingAddressValue.streetAddress as string; - body.shipping_address2 = shippingAddressValue.aptSuite as string; - body.shipping_city = shippingAddressValue.city as string; - body.shipping_state = shippingAddressValue.state as string; - body.shipping_postal_code = shippingAddressValue.postalCode as string; - body.shipping_country_id = parseInt(shippingAddressValue.countryCode as string, 10); - } - const billingAddressValue = (this.getNodeParameter('billingAddressUi', i) as IDataObject).billingAddressValue as IDataObject; - if (billingAddressValue) { - body.address1 = billingAddressValue.streetAddress as string; - body.address2 = billingAddressValue.aptSuite as string; - body.city = billingAddressValue.city as string; - body.state = billingAddressValue.state as string; - body.postal_code = billingAddressValue.postalCode as string; - body.country_id = parseInt(billingAddressValue.countryCode as string, 10); - } - responseData = await invoiceNinjaApiRequest.call(this, 'POST', '/clients', body); - responseData = responseData.data; - } - if (operation === 'get') { - const clientId = this.getNodeParameter('clientId', i) as string; - const options = this.getNodeParameter('options', i) as IDataObject; - if (options.include) { - qs.include = options.include as string; - } - responseData = await invoiceNinjaApiRequest.call(this, 'GET', `/clients/${clientId}`, {}, qs); - responseData = responseData.data; - } - if (operation === 'getAll') { - const returnAll = this.getNodeParameter('returnAll', 0) as boolean; - const options = this.getNodeParameter('options', i) as IDataObject; - if (options.include) { - qs.include = options.include as string; - } - if (returnAll === true) { - responseData = await invoiceNinjaApiRequestAllItems.call(this, 'data', 'GET', '/clients', {}, qs); - } else { - qs.per_page = this.getNodeParameter('limit', 0) as number; - responseData = await invoiceNinjaApiRequest.call(this, 'GET', '/clients', {}, qs); - responseData = responseData.data; - } - } - if (operation === 'delete') { - const clientId = this.getNodeParameter('clientId', i) as string; - responseData = await invoiceNinjaApiRequest.call(this, 'DELETE', `/clients/${clientId}`); - responseData = responseData.data; - } - } - if (resource === 'invoice') { - if (operation === 'create') { - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const body: IInvoice = {}; - if (additionalFields.email) { - body.email = additionalFields.email as string; - } - if (additionalFields.client) { - body.client_id = additionalFields.client as number; - } - if (additionalFields.autoBill) { - body.auto_bill = additionalFields.autoBill as boolean; - } - if (additionalFields.customValue1) { - body.custom_value1 = additionalFields.customValue1 as number; - } - if (additionalFields.customValue2) { - body.custom_value2 = additionalFields.customValue2 as number; - } - if (additionalFields.dueDate) { - body.due_date = additionalFields.dueDate as string; - } - if (additionalFields.invoiceDate) { - body.invoice_date = additionalFields.invoiceDate as string; - } - if (additionalFields.invoiceNumber) { - body.invoice_number = additionalFields.invoiceNumber as string; - } - if (additionalFields.invoiceStatus) { - body.invoice_status_id = additionalFields.invoiceStatus as number; - } - if (additionalFields.isAmountDiscount) { - body.is_amount_discount = additionalFields.isAmountDiscount as boolean; - } - if (additionalFields.partial) { - body.partial = additionalFields.partial as number; - } - if (additionalFields.partialDueDate) { - body.partial_due_date = additionalFields.partialDueDate as string; - } - if (additionalFields.poNumber) { - body.po_number = additionalFields.poNumber as string; - } - if (additionalFields.privateNotes) { - body.private_notes = additionalFields.privateNotes as string; - } - if (additionalFields.publicNotes) { - body.public_notes = additionalFields.publicNotes as string; - } - if (additionalFields.taxName1) { - body.tax_name1 = additionalFields.taxName1 as string; - } - if (additionalFields.taxName2) { - body.tax_name2 = additionalFields.taxName2 as string; - } - if (additionalFields.taxtRate1) { - body.tax_rate1 = additionalFields.taxtRate1 as number; - } - if (additionalFields.taxtRate2) { - body.tax_rate2 = additionalFields.taxtRate2 as number; - } - if (additionalFields.discount) { - body.discount = additionalFields.discount as number; - } - if (additionalFields.paid) { - body.paid = additionalFields.paid as number; - } - if (additionalFields.emailInvoice) { - body.email_invoice = additionalFields.emailInvoice as boolean; - } - const invoceItemsValues = (this.getNodeParameter('invoiceItemsUi', i) as IDataObject).invoiceItemsValues as IDataObject[]; - if (invoceItemsValues) { - const items: IItem[] = []; - for (const itemValue of invoceItemsValues) { - const item: IItem = { - cost: itemValue.cost as number, - notes: itemValue.description as string, - product_key: itemValue.service as string, - qty: itemValue.hours as number, - tax_rate1: itemValue.taxRate1 as number, - tax_rate2: itemValue.taxRate2 as number, - tax_name1: itemValue.taxName1 as string, - tax_name2: itemValue.taxName2 as string, - }; - items.push(item); + if (additionalFields.clientName) { + body.name = additionalFields.clientName as string; } - body.invoice_items = items; - } - responseData = await invoiceNinjaApiRequest.call(this, 'POST', '/invoices', body); - responseData = responseData.data; - } - if (operation === 'email') { - const invoiceId = this.getNodeParameter('invoiceId', i) as string; - responseData = await invoiceNinjaApiRequest.call(this, 'POST', '/email_invoice', { id: invoiceId }); - } - if (operation === 'get') { - const invoiceId = this.getNodeParameter('invoiceId', i) as string; - const options = this.getNodeParameter('options', i) as IDataObject; - if (options.include) { - qs.include = options.include as string; - } - responseData = await invoiceNinjaApiRequest.call(this, 'GET', `/invoices/${invoiceId}`, {}, qs); - responseData = responseData.data; - } - if (operation === 'getAll') { - const returnAll = this.getNodeParameter('returnAll', 0) as boolean; - const options = this.getNodeParameter('options', i) as IDataObject; - if (options.include) { - qs.include = options.include as string; - } - if (options.invoiceNumber) { - qs.invoice_number = options.invoiceNumber as string; - } - if (returnAll === true) { - responseData = await invoiceNinjaApiRequestAllItems.call(this, 'data', 'GET', '/invoices', {}, qs); - } else { - qs.per_page = this.getNodeParameter('limit', 0) as number; - responseData = await invoiceNinjaApiRequest.call(this, 'GET', '/invoices', {}, qs); - responseData = responseData.data; - } - } - if (operation === 'delete') { - const invoiceId = this.getNodeParameter('invoiceId', i) as string; - responseData = await invoiceNinjaApiRequest.call(this, 'DELETE', `/invoices/${invoiceId}`); - responseData = responseData.data; - } - } - if (resource === 'task') { - if (operation === 'create') { - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const body: ITask = {}; - if (additionalFields.client) { - body.client_id = additionalFields.client as number; - } - if (additionalFields.project) { - body.project_id = additionalFields.project as number; - } - if (additionalFields.customValue1) { - body.custom_value1 = additionalFields.customValue1 as string; - } - if (additionalFields.customValue2) { - body.custom_value2 = additionalFields.customValue2 as string; - } - if (additionalFields.description) { - body.description = additionalFields.description as string; - } - const timeLogsValues = (this.getNodeParameter('timeLogsUi', i) as IDataObject).timeLogsValues as IDataObject[]; - if (timeLogsValues) { - const logs: number[][] = []; - for (const logValue of timeLogsValues) { - let from = 0, to; - if (logValue.startDate) { - from = new Date(logValue.startDate as string).getTime() / 1000 as number; + if (additionalFields.idNumber) { + body.id_number = additionalFields.idNumber as string; + } + if (additionalFields.idNumber) { + body.id_number = additionalFields.idNumber as string; + } + if (additionalFields.privateNotes) { + body.private_notes = additionalFields.privateNotes as string; + } + if (additionalFields.vatNumber) { + body.vat_number = additionalFields.vatNumber as string; + } + if (additionalFields.workPhone) { + body.work_phone = additionalFields.workPhone as string; + } + if (additionalFields.website) { + body.website = additionalFields.website as string; + } + const contactsValues = (this.getNodeParameter('contactsUi', i) as IDataObject).contacstValues as IDataObject[]; + if (contactsValues) { + const contacts: IContact[] = []; + for (const contactValue of contactsValues) { + const contact: IContact = { + first_name: contactValue.firstName as string, + last_name: contactValue.lastName as string, + email: contactValue.email as string, + phone: contactValue.phone as string, + }; + contacts.push(contact); } - if (logValue.endDate) { - to = new Date(logValue.endDate as string).getTime() / 1000 as number; - } - if (logValue.duration) { - to = from + (logValue.duration as number * 3600); - } - logs.push([from as number, to as number]); + body.contacts = contacts; } - body.time_log = JSON.stringify(logs); - } - responseData = await invoiceNinjaApiRequest.call(this, 'POST', '/tasks', body); - responseData = responseData.data; - } - if (operation === 'get') { - const taskId = this.getNodeParameter('taskId', i) as string; - const options = this.getNodeParameter('options', i) as IDataObject; - if (options.include) { - qs.include = options.include as string; - } - responseData = await invoiceNinjaApiRequest.call(this, 'GET', `/tasks/${taskId}`, {}, qs); - responseData = responseData.data; - } - if (operation === 'getAll') { - const returnAll = this.getNodeParameter('returnAll', 0) as boolean; - const options = this.getNodeParameter('options', i) as IDataObject; - if (options.include) { - qs.include = options.include as string; - } - if (returnAll === true) { - responseData = await invoiceNinjaApiRequestAllItems.call(this, 'data', 'GET', '/tasks', {}, qs); - } else { - qs.per_page = this.getNodeParameter('limit', 0) as number; - responseData = await invoiceNinjaApiRequest.call(this, 'GET', '/tasks', {}, qs); - responseData = responseData.data; - } - } - if (operation === 'delete') { - const taskId = this.getNodeParameter('taskId', i) as string; - responseData = await invoiceNinjaApiRequest.call(this, 'DELETE', `/tasks/${taskId}`); - responseData = responseData.data; - } - } - if (resource === 'payment') { - if (operation === 'create') { - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const invoice = this.getNodeParameter('invoice', i) as number; - const amount = this.getNodeParameter('amount', i) as number; - const body: IPayment = { - invoice_id: invoice, - amount, - }; - if (additionalFields.paymentType) { - body.payment_type_id = additionalFields.paymentType as number; - } - if (additionalFields.transferReference) { - body.transaction_reference = additionalFields.transferReference as string; - } - if (additionalFields.privateNotes) { - body.private_notes = additionalFields.privateNotes as string; - } - responseData = await invoiceNinjaApiRequest.call(this, 'POST', '/payments', body); - responseData = responseData.data; - } - if (operation === 'get') { - const paymentId = this.getNodeParameter('paymentId', i) as string; - const options = this.getNodeParameter('options', i) as IDataObject; - if (options.include) { - qs.include = options.include as string; - } - responseData = await invoiceNinjaApiRequest.call(this, 'GET', `/payments/${paymentId}`, {}, qs); - responseData = responseData.data; - } - if (operation === 'getAll') { - const returnAll = this.getNodeParameter('returnAll', 0) as boolean; - const options = this.getNodeParameter('options', i) as IDataObject; - if (options.include) { - qs.include = options.include as string; - } - if (returnAll === true) { - responseData = await invoiceNinjaApiRequestAllItems.call(this, 'data', 'GET', '/payments', {}, qs); - } else { - qs.per_page = this.getNodeParameter('limit', 0) as number; - responseData = await invoiceNinjaApiRequest.call(this, 'GET', '/payments', {}, qs); - responseData = responseData.data; - } - } - if (operation === 'delete') { - const paymentId = this.getNodeParameter('paymentId', i) as string; - responseData = await invoiceNinjaApiRequest.call(this, 'DELETE', `/payments/${paymentId}`); - responseData = responseData.data; - } - } - if (resource === 'expense') { - if (operation === 'create') { - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const body: IExpense = {}; - if (additionalFields.amount) { - body.amount = additionalFields.amount as number; - } - if (additionalFields.billable) { - body.should_be_invoiced = additionalFields.billable as boolean; - } - if (additionalFields.client) { - body.client_id = additionalFields.client as number; - } - if (additionalFields.customValue1) { - body.custom_value1 = additionalFields.customValue1 as string; - } - if (additionalFields.customValue2) { - body.custom_value2 = additionalFields.customValue2 as string; - } - if (additionalFields.category) { - body.expense_category_id = additionalFields.category as number; - } - if (additionalFields.expenseDate) { - body.expense_date = additionalFields.expenseDate as string; - } - if (additionalFields.paymentDate) { - body.payment_date = additionalFields.paymentDate as string; - } - if (additionalFields.paymentType) { - body.payment_type_id = additionalFields.paymentType as number; - } - if (additionalFields.publicNotes) { - body.public_notes = additionalFields.publicNotes as string; - } - if (additionalFields.privateNotes) { - body.private_notes = additionalFields.privateNotes as string; - } - if (additionalFields.taxName1) { - body.tax_name1 = additionalFields.taxName1 as string; - } - if (additionalFields.taxName2) { - body.tax_name2 = additionalFields.taxName2 as string; - } - if (additionalFields.taxRate1) { - body.tax_rate1 = additionalFields.taxRate1 as number; - } - if (additionalFields.taxRate2) { - body.tax_rate2 = additionalFields.taxRate2 as number; - } - if (additionalFields.transactionReference) { - body.transaction_reference = additionalFields.transactionReference as string; - } - if (additionalFields.vendor) { - body.vendor_id = additionalFields.vendor as number; - } - responseData = await invoiceNinjaApiRequest.call(this, 'POST', '/expenses', body); - responseData = responseData.data; - } - if (operation === 'get') { - const expenseId = this.getNodeParameter('expenseId', i) as string; - responseData = await invoiceNinjaApiRequest.call(this, 'GET', `/expenses/${expenseId}`, {}, qs); - responseData = responseData.data; - } - if (operation === 'getAll') { - const returnAll = this.getNodeParameter('returnAll', 0) as boolean; - if (returnAll === true) { - responseData = await invoiceNinjaApiRequestAllItems.call(this, 'data', 'GET', '/expenses', {}, qs); - } else { - qs.per_page = this.getNodeParameter('limit', 0) as number; - responseData = await invoiceNinjaApiRequest.call(this, 'GET', '/expenses', {}, qs); - responseData = responseData.data; - } - } - if (operation === 'delete') { - const expenseId = this.getNodeParameter('expenseId', i) as string; - responseData = await invoiceNinjaApiRequest.call(this, 'DELETE', `/expenses/${expenseId}`); - responseData = responseData.data; - } - } - if (resource === 'quote') { - if (operation === 'create') { - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const body: IQuote = { - is_quote: true, - }; - if (additionalFields.client) { - body.client_id = additionalFields.client as number; - } - if (additionalFields.email) { - body.email = additionalFields.email as string; - } - if (additionalFields.autoBill) { - body.auto_bill = additionalFields.autoBill as boolean; - } - if (additionalFields.customValue1) { - body.custom_value1 = additionalFields.customValue1 as number; - } - if (additionalFields.customValue2) { - body.custom_value2 = additionalFields.customValue2 as number; - } - if (additionalFields.dueDate) { - body.due_date = additionalFields.dueDate as string; - } - if (additionalFields.quouteDate) { - body.invoice_date = additionalFields.quouteDate as string; - } - if (additionalFields.quoteNumber) { - body.invoice_number = additionalFields.quoteNumber as string; - } - if (additionalFields.invoiceStatus) { - body.invoice_status_id = additionalFields.invoiceStatus as number; - } - if (additionalFields.isAmountDiscount) { - body.is_amount_discount = additionalFields.isAmountDiscount as boolean; - } - if (additionalFields.partial) { - body.partial = additionalFields.partial as number; - } - if (additionalFields.partialDueDate) { - body.partial_due_date = additionalFields.partialDueDate as string; - } - if (additionalFields.poNumber) { - body.po_number = additionalFields.poNumber as string; - } - if (additionalFields.privateNotes) { - body.private_notes = additionalFields.privateNotes as string; - } - if (additionalFields.publicNotes) { - body.public_notes = additionalFields.publicNotes as string; - } - if (additionalFields.taxName1) { - body.tax_name1 = additionalFields.taxName1 as string; - } - if (additionalFields.taxName2) { - body.tax_name2 = additionalFields.taxName2 as string; - } - if (additionalFields.taxtRate1) { - body.tax_rate1 = additionalFields.taxtRate1 as number; - } - if (additionalFields.taxtRate2) { - body.tax_rate2 = additionalFields.taxtRate2 as number; - } - if (additionalFields.discount) { - body.discount = additionalFields.discount as number; - } - if (additionalFields.paid) { - body.paid = additionalFields.paid as number; - } - if (additionalFields.emailQuote) { - body.email_invoice = additionalFields.emailQuote as boolean; - } - const invoceItemsValues = (this.getNodeParameter('invoiceItemsUi', i) as IDataObject).invoiceItemsValues as IDataObject[]; - if (invoceItemsValues) { - const items: IItem[] = []; - for (const itemValue of invoceItemsValues) { - const item: IItem = { - cost: itemValue.cost as number, - notes: itemValue.description as string, - product_key: itemValue.service as string, - qty: itemValue.hours as number, - tax_rate1: itemValue.taxRate1 as number, - tax_rate2: itemValue.taxRate2 as number, - tax_name1: itemValue.taxName1 as string, - tax_name2: itemValue.taxName2 as string, - }; - items.push(item); + const shippingAddressValue = (this.getNodeParameter('shippingAddressUi', i) as IDataObject).shippingAddressValue as IDataObject; + if (shippingAddressValue) { + body.shipping_address1 = shippingAddressValue.streetAddress as string; + body.shipping_address2 = shippingAddressValue.aptSuite as string; + body.shipping_city = shippingAddressValue.city as string; + body.shipping_state = shippingAddressValue.state as string; + body.shipping_postal_code = shippingAddressValue.postalCode as string; + body.shipping_country_id = parseInt(shippingAddressValue.countryCode as string, 10); } - body.invoice_items = items; + const billingAddressValue = (this.getNodeParameter('billingAddressUi', i) as IDataObject).billingAddressValue as IDataObject; + if (billingAddressValue) { + body.address1 = billingAddressValue.streetAddress as string; + body.address2 = billingAddressValue.aptSuite as string; + body.city = billingAddressValue.city as string; + body.state = billingAddressValue.state as string; + body.postal_code = billingAddressValue.postalCode as string; + body.country_id = parseInt(billingAddressValue.countryCode as string, 10); + } + responseData = await invoiceNinjaApiRequest.call(this, 'POST', '/clients', body); + responseData = responseData.data; } - responseData = await invoiceNinjaApiRequest.call(this, 'POST', '/invoices', body); - responseData = responseData.data; - } - if (operation === 'email') { - const quoteId = this.getNodeParameter('quoteId', i) as string; - responseData = await invoiceNinjaApiRequest.call(this, 'POST', '/email_invoice', { id: quoteId }); - } - if (operation === 'get') { - const quoteId = this.getNodeParameter('quoteId', i) as string; - const options = this.getNodeParameter('options', i) as IDataObject; - if (options.include) { - qs.include = options.include as string; + if (operation === 'get') { + const clientId = this.getNodeParameter('clientId', i) as string; + const options = this.getNodeParameter('options', i) as IDataObject; + if (options.include) { + qs.include = options.include as string; + } + responseData = await invoiceNinjaApiRequest.call(this, 'GET', `/clients/${clientId}`, {}, qs); + responseData = responseData.data; } - responseData = await invoiceNinjaApiRequest.call(this, 'GET', `/invoices/${quoteId}`, {}, qs); - responseData = responseData.data; - } - if (operation === 'getAll') { - const returnAll = this.getNodeParameter('returnAll', 0) as boolean; - const options = this.getNodeParameter('options', i) as IDataObject; - if (options.include) { - qs.include = options.include as string; + if (operation === 'getAll') { + const returnAll = this.getNodeParameter('returnAll', 0) as boolean; + const options = this.getNodeParameter('options', i) as IDataObject; + if (options.include) { + qs.include = options.include as string; + } + if (returnAll === true) { + responseData = await invoiceNinjaApiRequestAllItems.call(this, 'data', 'GET', '/clients', {}, qs); + } else { + qs.per_page = this.getNodeParameter('limit', 0) as number; + responseData = await invoiceNinjaApiRequest.call(this, 'GET', '/clients', {}, qs); + responseData = responseData.data; + } } - if (options.invoiceNumber) { - qs.invoice_number = options.invoiceNumber as string; - } - if (returnAll === true) { - responseData = await invoiceNinjaApiRequestAllItems.call(this, 'data', 'GET', '/quotes', {}, qs); - } else { - qs.per_page = this.getNodeParameter('limit', 0) as number; - responseData = await invoiceNinjaApiRequest.call(this, 'GET', '/quotes', {}, qs); + if (operation === 'delete') { + const clientId = this.getNodeParameter('clientId', i) as string; + responseData = await invoiceNinjaApiRequest.call(this, 'DELETE', `/clients/${clientId}`); responseData = responseData.data; } } - if (operation === 'delete') { - const quoteId = this.getNodeParameter('quoteId', i) as string; - responseData = await invoiceNinjaApiRequest.call(this, 'DELETE', `/invoices/${quoteId}`); - responseData = responseData.data; + if (resource === 'invoice') { + if (operation === 'create') { + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const body: IInvoice = {}; + if (additionalFields.email) { + body.email = additionalFields.email as string; + } + if (additionalFields.client) { + body.client_id = additionalFields.client as number; + } + if (additionalFields.autoBill) { + body.auto_bill = additionalFields.autoBill as boolean; + } + if (additionalFields.customValue1) { + body.custom_value1 = additionalFields.customValue1 as number; + } + if (additionalFields.customValue2) { + body.custom_value2 = additionalFields.customValue2 as number; + } + if (additionalFields.dueDate) { + body.due_date = additionalFields.dueDate as string; + } + if (additionalFields.invoiceDate) { + body.invoice_date = additionalFields.invoiceDate as string; + } + if (additionalFields.invoiceNumber) { + body.invoice_number = additionalFields.invoiceNumber as string; + } + if (additionalFields.invoiceStatus) { + body.invoice_status_id = additionalFields.invoiceStatus as number; + } + if (additionalFields.isAmountDiscount) { + body.is_amount_discount = additionalFields.isAmountDiscount as boolean; + } + if (additionalFields.partial) { + body.partial = additionalFields.partial as number; + } + if (additionalFields.partialDueDate) { + body.partial_due_date = additionalFields.partialDueDate as string; + } + if (additionalFields.poNumber) { + body.po_number = additionalFields.poNumber as string; + } + if (additionalFields.privateNotes) { + body.private_notes = additionalFields.privateNotes as string; + } + if (additionalFields.publicNotes) { + body.public_notes = additionalFields.publicNotes as string; + } + if (additionalFields.taxName1) { + body.tax_name1 = additionalFields.taxName1 as string; + } + if (additionalFields.taxName2) { + body.tax_name2 = additionalFields.taxName2 as string; + } + if (additionalFields.taxtRate1) { + body.tax_rate1 = additionalFields.taxtRate1 as number; + } + if (additionalFields.taxtRate2) { + body.tax_rate2 = additionalFields.taxtRate2 as number; + } + if (additionalFields.discount) { + body.discount = additionalFields.discount as number; + } + if (additionalFields.paid) { + body.paid = additionalFields.paid as number; + } + if (additionalFields.emailInvoice) { + body.email_invoice = additionalFields.emailInvoice as boolean; + } + const invoceItemsValues = (this.getNodeParameter('invoiceItemsUi', i) as IDataObject).invoiceItemsValues as IDataObject[]; + if (invoceItemsValues) { + const items: IItem[] = []; + for (const itemValue of invoceItemsValues) { + const item: IItem = { + cost: itemValue.cost as number, + notes: itemValue.description as string, + product_key: itemValue.service as string, + qty: itemValue.hours as number, + tax_rate1: itemValue.taxRate1 as number, + tax_rate2: itemValue.taxRate2 as number, + tax_name1: itemValue.taxName1 as string, + tax_name2: itemValue.taxName2 as string, + }; + items.push(item); + } + body.invoice_items = items; + } + responseData = await invoiceNinjaApiRequest.call(this, 'POST', '/invoices', body); + responseData = responseData.data; + } + if (operation === 'email') { + const invoiceId = this.getNodeParameter('invoiceId', i) as string; + responseData = await invoiceNinjaApiRequest.call(this, 'POST', '/email_invoice', { id: invoiceId }); + } + if (operation === 'get') { + const invoiceId = this.getNodeParameter('invoiceId', i) as string; + const options = this.getNodeParameter('options', i) as IDataObject; + if (options.include) { + qs.include = options.include as string; + } + responseData = await invoiceNinjaApiRequest.call(this, 'GET', `/invoices/${invoiceId}`, {}, qs); + responseData = responseData.data; + } + if (operation === 'getAll') { + const returnAll = this.getNodeParameter('returnAll', 0) as boolean; + const options = this.getNodeParameter('options', i) as IDataObject; + if (options.include) { + qs.include = options.include as string; + } + if (options.invoiceNumber) { + qs.invoice_number = options.invoiceNumber as string; + } + if (returnAll === true) { + responseData = await invoiceNinjaApiRequestAllItems.call(this, 'data', 'GET', '/invoices', {}, qs); + } else { + qs.per_page = this.getNodeParameter('limit', 0) as number; + responseData = await invoiceNinjaApiRequest.call(this, 'GET', '/invoices', {}, qs); + responseData = responseData.data; + } + } + if (operation === 'delete') { + const invoiceId = this.getNodeParameter('invoiceId', i) as string; + responseData = await invoiceNinjaApiRequest.call(this, 'DELETE', `/invoices/${invoiceId}`); + responseData = responseData.data; + } } - } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else { - returnData.push(responseData as IDataObject); + if (resource === 'task') { + if (operation === 'create') { + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const body: ITask = {}; + if (additionalFields.client) { + body.client_id = additionalFields.client as number; + } + if (additionalFields.project) { + body.project_id = additionalFields.project as number; + } + if (additionalFields.customValue1) { + body.custom_value1 = additionalFields.customValue1 as string; + } + if (additionalFields.customValue2) { + body.custom_value2 = additionalFields.customValue2 as string; + } + if (additionalFields.description) { + body.description = additionalFields.description as string; + } + const timeLogsValues = (this.getNodeParameter('timeLogsUi', i) as IDataObject).timeLogsValues as IDataObject[]; + if (timeLogsValues) { + const logs: number[][] = []; + for (const logValue of timeLogsValues) { + let from = 0, to; + if (logValue.startDate) { + from = new Date(logValue.startDate as string).getTime() / 1000 as number; + } + if (logValue.endDate) { + to = new Date(logValue.endDate as string).getTime() / 1000 as number; + } + if (logValue.duration) { + to = from + (logValue.duration as number * 3600); + } + logs.push([from as number, to as number]); + } + body.time_log = JSON.stringify(logs); + } + responseData = await invoiceNinjaApiRequest.call(this, 'POST', '/tasks', body); + responseData = responseData.data; + } + if (operation === 'get') { + const taskId = this.getNodeParameter('taskId', i) as string; + const options = this.getNodeParameter('options', i) as IDataObject; + if (options.include) { + qs.include = options.include as string; + } + responseData = await invoiceNinjaApiRequest.call(this, 'GET', `/tasks/${taskId}`, {}, qs); + responseData = responseData.data; + } + if (operation === 'getAll') { + const returnAll = this.getNodeParameter('returnAll', 0) as boolean; + const options = this.getNodeParameter('options', i) as IDataObject; + if (options.include) { + qs.include = options.include as string; + } + if (returnAll === true) { + responseData = await invoiceNinjaApiRequestAllItems.call(this, 'data', 'GET', '/tasks', {}, qs); + } else { + qs.per_page = this.getNodeParameter('limit', 0) as number; + responseData = await invoiceNinjaApiRequest.call(this, 'GET', '/tasks', {}, qs); + responseData = responseData.data; + } + } + if (operation === 'delete') { + const taskId = this.getNodeParameter('taskId', i) as string; + responseData = await invoiceNinjaApiRequest.call(this, 'DELETE', `/tasks/${taskId}`); + responseData = responseData.data; + } + } + if (resource === 'payment') { + if (operation === 'create') { + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const invoice = this.getNodeParameter('invoice', i) as number; + const amount = this.getNodeParameter('amount', i) as number; + const body: IPayment = { + invoice_id: invoice, + amount, + }; + if (additionalFields.paymentType) { + body.payment_type_id = additionalFields.paymentType as number; + } + if (additionalFields.transferReference) { + body.transaction_reference = additionalFields.transferReference as string; + } + if (additionalFields.privateNotes) { + body.private_notes = additionalFields.privateNotes as string; + } + responseData = await invoiceNinjaApiRequest.call(this, 'POST', '/payments', body); + responseData = responseData.data; + } + if (operation === 'get') { + const paymentId = this.getNodeParameter('paymentId', i) as string; + const options = this.getNodeParameter('options', i) as IDataObject; + if (options.include) { + qs.include = options.include as string; + } + responseData = await invoiceNinjaApiRequest.call(this, 'GET', `/payments/${paymentId}`, {}, qs); + responseData = responseData.data; + } + if (operation === 'getAll') { + const returnAll = this.getNodeParameter('returnAll', 0) as boolean; + const options = this.getNodeParameter('options', i) as IDataObject; + if (options.include) { + qs.include = options.include as string; + } + if (returnAll === true) { + responseData = await invoiceNinjaApiRequestAllItems.call(this, 'data', 'GET', '/payments', {}, qs); + } else { + qs.per_page = this.getNodeParameter('limit', 0) as number; + responseData = await invoiceNinjaApiRequest.call(this, 'GET', '/payments', {}, qs); + responseData = responseData.data; + } + } + if (operation === 'delete') { + const paymentId = this.getNodeParameter('paymentId', i) as string; + responseData = await invoiceNinjaApiRequest.call(this, 'DELETE', `/payments/${paymentId}`); + responseData = responseData.data; + } + } + if (resource === 'expense') { + if (operation === 'create') { + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const body: IExpense = {}; + if (additionalFields.amount) { + body.amount = additionalFields.amount as number; + } + if (additionalFields.billable) { + body.should_be_invoiced = additionalFields.billable as boolean; + } + if (additionalFields.client) { + body.client_id = additionalFields.client as number; + } + if (additionalFields.customValue1) { + body.custom_value1 = additionalFields.customValue1 as string; + } + if (additionalFields.customValue2) { + body.custom_value2 = additionalFields.customValue2 as string; + } + if (additionalFields.category) { + body.expense_category_id = additionalFields.category as number; + } + if (additionalFields.expenseDate) { + body.expense_date = additionalFields.expenseDate as string; + } + if (additionalFields.paymentDate) { + body.payment_date = additionalFields.paymentDate as string; + } + if (additionalFields.paymentType) { + body.payment_type_id = additionalFields.paymentType as number; + } + if (additionalFields.publicNotes) { + body.public_notes = additionalFields.publicNotes as string; + } + if (additionalFields.privateNotes) { + body.private_notes = additionalFields.privateNotes as string; + } + if (additionalFields.taxName1) { + body.tax_name1 = additionalFields.taxName1 as string; + } + if (additionalFields.taxName2) { + body.tax_name2 = additionalFields.taxName2 as string; + } + if (additionalFields.taxRate1) { + body.tax_rate1 = additionalFields.taxRate1 as number; + } + if (additionalFields.taxRate2) { + body.tax_rate2 = additionalFields.taxRate2 as number; + } + if (additionalFields.transactionReference) { + body.transaction_reference = additionalFields.transactionReference as string; + } + if (additionalFields.vendor) { + body.vendor_id = additionalFields.vendor as number; + } + responseData = await invoiceNinjaApiRequest.call(this, 'POST', '/expenses', body); + responseData = responseData.data; + } + if (operation === 'get') { + const expenseId = this.getNodeParameter('expenseId', i) as string; + responseData = await invoiceNinjaApiRequest.call(this, 'GET', `/expenses/${expenseId}`, {}, qs); + responseData = responseData.data; + } + if (operation === 'getAll') { + const returnAll = this.getNodeParameter('returnAll', 0) as boolean; + if (returnAll === true) { + responseData = await invoiceNinjaApiRequestAllItems.call(this, 'data', 'GET', '/expenses', {}, qs); + } else { + qs.per_page = this.getNodeParameter('limit', 0) as number; + responseData = await invoiceNinjaApiRequest.call(this, 'GET', '/expenses', {}, qs); + responseData = responseData.data; + } + } + if (operation === 'delete') { + const expenseId = this.getNodeParameter('expenseId', i) as string; + responseData = await invoiceNinjaApiRequest.call(this, 'DELETE', `/expenses/${expenseId}`); + responseData = responseData.data; + } + } + if (resource === 'quote') { + if (operation === 'create') { + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const body: IQuote = { + is_quote: true, + }; + if (additionalFields.client) { + body.client_id = additionalFields.client as number; + } + if (additionalFields.email) { + body.email = additionalFields.email as string; + } + if (additionalFields.autoBill) { + body.auto_bill = additionalFields.autoBill as boolean; + } + if (additionalFields.customValue1) { + body.custom_value1 = additionalFields.customValue1 as number; + } + if (additionalFields.customValue2) { + body.custom_value2 = additionalFields.customValue2 as number; + } + if (additionalFields.dueDate) { + body.due_date = additionalFields.dueDate as string; + } + if (additionalFields.quouteDate) { + body.invoice_date = additionalFields.quouteDate as string; + } + if (additionalFields.quoteNumber) { + body.invoice_number = additionalFields.quoteNumber as string; + } + if (additionalFields.invoiceStatus) { + body.invoice_status_id = additionalFields.invoiceStatus as number; + } + if (additionalFields.isAmountDiscount) { + body.is_amount_discount = additionalFields.isAmountDiscount as boolean; + } + if (additionalFields.partial) { + body.partial = additionalFields.partial as number; + } + if (additionalFields.partialDueDate) { + body.partial_due_date = additionalFields.partialDueDate as string; + } + if (additionalFields.poNumber) { + body.po_number = additionalFields.poNumber as string; + } + if (additionalFields.privateNotes) { + body.private_notes = additionalFields.privateNotes as string; + } + if (additionalFields.publicNotes) { + body.public_notes = additionalFields.publicNotes as string; + } + if (additionalFields.taxName1) { + body.tax_name1 = additionalFields.taxName1 as string; + } + if (additionalFields.taxName2) { + body.tax_name2 = additionalFields.taxName2 as string; + } + if (additionalFields.taxtRate1) { + body.tax_rate1 = additionalFields.taxtRate1 as number; + } + if (additionalFields.taxtRate2) { + body.tax_rate2 = additionalFields.taxtRate2 as number; + } + if (additionalFields.discount) { + body.discount = additionalFields.discount as number; + } + if (additionalFields.paid) { + body.paid = additionalFields.paid as number; + } + if (additionalFields.emailQuote) { + body.email_invoice = additionalFields.emailQuote as boolean; + } + const invoceItemsValues = (this.getNodeParameter('invoiceItemsUi', i) as IDataObject).invoiceItemsValues as IDataObject[]; + if (invoceItemsValues) { + const items: IItem[] = []; + for (const itemValue of invoceItemsValues) { + const item: IItem = { + cost: itemValue.cost as number, + notes: itemValue.description as string, + product_key: itemValue.service as string, + qty: itemValue.hours as number, + tax_rate1: itemValue.taxRate1 as number, + tax_rate2: itemValue.taxRate2 as number, + tax_name1: itemValue.taxName1 as string, + tax_name2: itemValue.taxName2 as string, + }; + items.push(item); + } + body.invoice_items = items; + } + responseData = await invoiceNinjaApiRequest.call(this, 'POST', '/invoices', body); + responseData = responseData.data; + } + if (operation === 'email') { + const quoteId = this.getNodeParameter('quoteId', i) as string; + responseData = await invoiceNinjaApiRequest.call(this, 'POST', '/email_invoice', { id: quoteId }); + } + if (operation === 'get') { + const quoteId = this.getNodeParameter('quoteId', i) as string; + const options = this.getNodeParameter('options', i) as IDataObject; + if (options.include) { + qs.include = options.include as string; + } + responseData = await invoiceNinjaApiRequest.call(this, 'GET', `/invoices/${quoteId}`, {}, qs); + responseData = responseData.data; + } + if (operation === 'getAll') { + const returnAll = this.getNodeParameter('returnAll', 0) as boolean; + const options = this.getNodeParameter('options', i) as IDataObject; + if (options.include) { + qs.include = options.include as string; + } + if (options.invoiceNumber) { + qs.invoice_number = options.invoiceNumber as string; + } + if (returnAll === true) { + responseData = await invoiceNinjaApiRequestAllItems.call(this, 'data', 'GET', '/quotes', {}, qs); + } else { + qs.per_page = this.getNodeParameter('limit', 0) as number; + responseData = await invoiceNinjaApiRequest.call(this, 'GET', '/quotes', {}, qs); + responseData = responseData.data; + } + } + if (operation === 'delete') { + const quoteId = this.getNodeParameter('quoteId', i) as string; + responseData = await invoiceNinjaApiRequest.call(this, 'DELETE', `/invoices/${quoteId}`); + responseData = responseData.data; + } + } + if (Array.isArray(responseData)) { + returnData.push.apply(returnData, responseData as IDataObject[]); + } else { + returnData.push(responseData as IDataObject); + } + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } } return [this.helpers.returnJsonArray(returnData)]; diff --git a/packages/nodes-base/nodes/Kafka/Kafka.node.ts b/packages/nodes-base/nodes/Kafka/Kafka.node.ts index 6270da679a..81dcabd21f 100644 --- a/packages/nodes-base/nodes/Kafka/Kafka.node.ts +++ b/packages/nodes-base/nodes/Kafka/Kafka.node.ts @@ -167,110 +167,118 @@ export class Kafka implements INodeType { let responseData: IDataObject[]; - const options = this.getNodeParameter('options', 0) as IDataObject; - const sendInputData = this.getNodeParameter('sendInputData', 0) as boolean; + try { + const options = this.getNodeParameter('options', 0) as IDataObject; + const sendInputData = this.getNodeParameter('sendInputData', 0) as boolean; - const timeout = options.timeout as number; + const timeout = options.timeout as number; - let compression = CompressionTypes.None; + let compression = CompressionTypes.None; - const acks = (options.acks === true) ? 1 : 0; + const acks = (options.acks === true) ? 1 : 0; - if (options.compression === true) { - compression = CompressionTypes.GZIP; - } - - const credentials = this.getCredentials('kafka') as IDataObject; - - const brokers = (credentials.brokers as string || '').split(',').map(item => item.trim()) as string[]; - - const clientId = credentials.clientId as string; - - const ssl = credentials.ssl as boolean; - - const config: KafkaConfig = { - clientId, - brokers, - ssl, - }; - - if (credentials.authentication === true) { - if(!(credentials.username && credentials.password)) { - throw new NodeOperationError(this.getNode(), 'Username and password are required for authentication'); - } - config.sasl = { - username: credentials.username as string, - password: credentials.password as string, - mechanism: credentials.saslMechanism as string, - } as SASLOptions; - } - - const kafka = new apacheKafka(config); - - const producer = kafka.producer(); - - await producer.connect(); - - let message: string; - - for (let i = 0; i < length; i++) { - if (sendInputData === true) { - message = JSON.stringify(items[i].json); - } else { - message = this.getNodeParameter('message', i) as string; + if (options.compression === true) { + compression = CompressionTypes.GZIP; } - const topic = this.getNodeParameter('topic', i) as string; + const credentials = this.getCredentials('kafka') as IDataObject; - const jsonParameters = this.getNodeParameter('jsonParameters', i) as boolean; + const brokers = (credentials.brokers as string || '').split(',').map(item => item.trim()) as string[]; - let headers; + const clientId = credentials.clientId as string; - if (jsonParameters === true) { - headers = this.getNodeParameter('headerParametersJson', i) as string; - try { - headers = JSON.parse(headers); - } catch (exception) { - throw new NodeOperationError(this.getNode(), 'Headers must be a valid json'); + const ssl = credentials.ssl as boolean; + + const config: KafkaConfig = { + clientId, + brokers, + ssl, + }; + + if (credentials.authentication === true) { + if(!(credentials.username && credentials.password)) { + throw new NodeOperationError(this.getNode(), 'Username and password are required for authentication'); } - } else { - const values = (this.getNodeParameter('headersUi', i) as IDataObject).headerValues as IDataObject[]; - headers = {}; - if (values !== undefined) { - for (const value of values) { - //@ts-ignore - headers[value.key] = value.value; + config.sasl = { + username: credentials.username as string, + password: credentials.password as string, + mechanism: credentials.saslMechanism as string, + } as SASLOptions; + } + + const kafka = new apacheKafka(config); + + const producer = kafka.producer(); + + await producer.connect(); + + let message: string; + + for (let i = 0; i < length; i++) { + if (sendInputData === true) { + message = JSON.stringify(items[i].json); + } else { + message = this.getNodeParameter('message', i) as string; + } + + const topic = this.getNodeParameter('topic', i) as string; + + const jsonParameters = this.getNodeParameter('jsonParameters', i) as boolean; + + let headers; + + if (jsonParameters === true) { + headers = this.getNodeParameter('headerParametersJson', i) as string; + try { + headers = JSON.parse(headers); + } catch (exception) { + throw new NodeOperationError(this.getNode(), 'Headers must be a valid json'); + } + } else { + const values = (this.getNodeParameter('headersUi', i) as IDataObject).headerValues as IDataObject[]; + headers = {}; + if (values !== undefined) { + for (const value of values) { + //@ts-ignore + headers[value.key] = value.value; + } } } + + topicMessages.push( + { + topic, + messages: [{ + value: message, + headers, + }], + }); } - topicMessages.push( + responseData = await producer.sendBatch( { - topic, - messages: [{ - value: message, - headers, - }], + topicMessages, + timeout, + compression, + acks, + }, + ); + + if (responseData.length === 0) { + responseData.push({ + success: true, }); + } + + await producer.disconnect(); + + return [this.helpers.returnJsonArray(responseData)]; + } catch (error) { + if (this.continueOnFail()) { + return [this.helpers.returnJsonArray({ error: error.message })]; + } else { + throw error; + } } - - responseData = await producer.sendBatch( - { - topicMessages, - timeout, - compression, - acks, - }, - ); - - if (responseData.length === 0) { - responseData.push({ - success: true, - }); - } - - await producer.disconnect(); - - return [this.helpers.returnJsonArray(responseData)]; } } diff --git a/packages/nodes-base/nodes/Line/Line.node.ts b/packages/nodes-base/nodes/Line/Line.node.ts index 57ae68b263..2b2deac3ab 100644 --- a/packages/nodes-base/nodes/Line/Line.node.ts +++ b/packages/nodes-base/nodes/Line/Line.node.ts @@ -78,67 +78,75 @@ export class Line implements INodeType { const operation = this.getNodeParameter('operation', 0) as string; for (let i = 0; i < length; i++) { - if (resource === 'notification') { - //https://notify-bot.line.me/doc/en/ - if (operation === 'send') { - const message = this.getNodeParameter('message', i) as string; + try { + if (resource === 'notification') { + //https://notify-bot.line.me/doc/en/ + if (operation === 'send') { + const message = this.getNodeParameter('message', i) as string; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const body: IDataObject = { - message, - }; + const body: IDataObject = { + message, + }; - Object.assign(body, additionalFields); + Object.assign(body, additionalFields); - if (body.hasOwnProperty('notificationDisabled')) { - body.notificationDisabled = (body.notificationDisabled) ? 'true' : 'false'; - } - - if (body.stickerUi) { - const sticker = (body.stickerUi as IDataObject).stickerValue as IDataObject; - if (sticker) { - body.stickerId = sticker.stickerId; - body.stickerPackageId = sticker.stickerPackageId; + if (body.hasOwnProperty('notificationDisabled')) { + body.notificationDisabled = (body.notificationDisabled) ? 'true' : 'false'; } - delete body.stickerUi; - } - if (body.imageUi) { - const image = (body.imageUi as IDataObject).imageValue as IDataObject; - - if (image && image.binaryData === true) { - if (items[i].binary === undefined) { - throw new NodeOperationError(this.getNode(), 'No binary data exists on item!'); + if (body.stickerUi) { + const sticker = (body.stickerUi as IDataObject).stickerValue as IDataObject; + if (sticker) { + body.stickerId = sticker.stickerId; + body.stickerPackageId = sticker.stickerPackageId; } - //@ts-ignore - if (items[i].binary[image.binaryProperty] === undefined) { - throw new NodeOperationError(this.getNode(), `No binary data property "${image.binaryProperty}" does not exists on item!`); - } - - const binaryData = (items[i].binary as IBinaryKeyData)[image.binaryProperty as string]; - - body.imageFile = { - value: Buffer.from(binaryData.data, BINARY_ENCODING), - options: { - filename: binaryData.fileName, - }, - }; - } else { - body.imageFullsize = image.imageFullsize; - body.imageThumbnail = image.imageThumbnail; + delete body.stickerUi; } - delete body.imageUi; + + if (body.imageUi) { + const image = (body.imageUi as IDataObject).imageValue as IDataObject; + + if (image && image.binaryData === true) { + if (items[i].binary === undefined) { + throw new NodeOperationError(this.getNode(), 'No binary data exists on item!'); + } + //@ts-ignore + if (items[i].binary[image.binaryProperty] === undefined) { + throw new NodeOperationError(this.getNode(), `No binary data property "${image.binaryProperty}" does not exists on item!`); + } + + const binaryData = (items[i].binary as IBinaryKeyData)[image.binaryProperty as string]; + + body.imageFile = { + value: Buffer.from(binaryData.data, BINARY_ENCODING), + options: { + filename: binaryData.fileName, + }, + }; + } else { + body.imageFullsize = image.imageFullsize; + body.imageThumbnail = image.imageThumbnail; + } + delete body.imageUi; + } + responseData = await lineApiRequest.call(this, 'POST', '', {}, {}, 'https://notify-api.line.me/api/notify', { formData: body }); } - responseData = await lineApiRequest.call(this, 'POST', '', {}, {}, 'https://notify-api.line.me/api/notify', { formData: body }); } - } - } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); + if (Array.isArray(responseData)) { + returnData.push.apply(returnData, responseData as IDataObject[]); - } else if (responseData !== undefined) { - returnData.push(responseData as IDataObject); + } else if (responseData !== undefined) { + returnData.push(responseData as IDataObject); + } + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; + } } return [this.helpers.returnJsonArray(returnData)]; } diff --git a/packages/nodes-base/nodes/LinkedIn/LinkedIn.node.ts b/packages/nodes-base/nodes/LinkedIn/LinkedIn.node.ts index 3a93c55f7d..3665bd8487 100644 --- a/packages/nodes-base/nodes/LinkedIn/LinkedIn.node.ts +++ b/packages/nodes-base/nodes/LinkedIn/LinkedIn.node.ts @@ -81,173 +81,181 @@ export class LinkedIn implements INodeType { let body = {}; for (let i = 0; i < items.length; i++) { - if (resource === 'post') { - if (operation === 'create') { - const text = this.getNodeParameter('text', i) as string; - const shareMediaCategory = this.getNodeParameter('shareMediaCategory', i) as string; - const postAs = this.getNodeParameter('postAs', i) as string; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - - let authorUrn = ''; - let visibility = 'PUBLIC'; - - if (postAs === 'person') { - const personUrn = this.getNodeParameter('person', i) as string; - // Only if posting as a person can user decide if post visible by public or connections - visibility = additionalFields.visibility as string || 'PUBLIC'; - authorUrn = `urn:li:person:${personUrn}`; - } else { - const organizationUrn = this.getNodeParameter('organization', i) as string; - authorUrn = `urn:li:organization:${organizationUrn}`; - } - - let description = ''; - let title = ''; - let originalUrl = ''; - - if (shareMediaCategory === 'IMAGE') { - - if (additionalFields.description) { - description = additionalFields.description as string; - } - if (additionalFields.title) { - title = additionalFields.title as string; - } - // Send a REQUEST to prepare a register of a media image file - const registerRequest = { - registerUploadRequest: { - recipes: [ - 'urn:li:digitalmediaRecipe:feedshare-image', - ], - owner: authorUrn, - serviceRelationships: [ - { - relationshipType: 'OWNER', - identifier: 'urn:li:userGeneratedContent', - }, - ], - }, - }; - - const registerObject = await linkedInApiRequest.call(this, 'POST', '/assets?action=registerUpload', registerRequest); - - // Response provides a specific upload URL that is used to upload the binary image file - const uploadUrl = registerObject.value.uploadMechanism['com.linkedin.digitalmedia.uploading.MediaUploadHttpRequest'].uploadUrl as string; - const asset = registerObject.value.asset as string; - - // Prepare binary file upload - const item = items[i]; - - if (item.binary === undefined) { - throw new NodeOperationError(this.getNode(), 'No binary data exists on item!'); - } - - const propertyNameUpload = this.getNodeParameter('binaryPropertyName', i) as string; - - if (item.binary[propertyNameUpload] === undefined) { - throw new NodeOperationError(this.getNode(), `No binary data property "${propertyNameUpload}" does not exists on item!`); - } - - // Buffer binary data - const buffer = Buffer.from(item.binary[propertyNameUpload].data, BINARY_ENCODING) as Buffer; - // Upload image - await linkedInApiRequest.call(this, 'POST', uploadUrl, buffer, true); - - body = { - author: authorUrn, - lifecycleState: 'PUBLISHED', - specificContent: { - 'com.linkedin.ugc.ShareContent': { - shareCommentary: { - text, - }, - shareMediaCategory: 'IMAGE', - media: [ - { - status: 'READY', - description: { - text: description, - }, - media: asset, - title: { - text: title, - }, - }, - ], - }, - }, - visibility: { - 'com.linkedin.ugc.MemberNetworkVisibility': visibility, - }, - }; - - } else if (shareMediaCategory === 'ARTICLE') { + try { + if (resource === 'post') { + if (operation === 'create') { + const text = this.getNodeParameter('text', i) as string; + const shareMediaCategory = this.getNodeParameter('shareMediaCategory', i) as string; + const postAs = this.getNodeParameter('postAs', i) as string; const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - if (additionalFields.description) { - description = additionalFields.description as string; - } - if (additionalFields.title) { - title = additionalFields.title as string; - } - if (additionalFields.originalUrl) { - originalUrl = additionalFields.originalUrl as string; + let authorUrn = ''; + let visibility = 'PUBLIC'; + + if (postAs === 'person') { + const personUrn = this.getNodeParameter('person', i) as string; + // Only if posting as a person can user decide if post visible by public or connections + visibility = additionalFields.visibility as string || 'PUBLIC'; + authorUrn = `urn:li:person:${personUrn}`; + } else { + const organizationUrn = this.getNodeParameter('organization', i) as string; + authorUrn = `urn:li:organization:${organizationUrn}`; } - body = { - author: `${authorUrn}`, - lifecycleState: 'PUBLISHED', - specificContent: { - 'com.linkedin.ugc.ShareContent': { - shareCommentary: { - text, - }, - shareMediaCategory, - media: [ + let description = ''; + let title = ''; + let originalUrl = ''; + + if (shareMediaCategory === 'IMAGE') { + + if (additionalFields.description) { + description = additionalFields.description as string; + } + if (additionalFields.title) { + title = additionalFields.title as string; + } + // Send a REQUEST to prepare a register of a media image file + const registerRequest = { + registerUploadRequest: { + recipes: [ + 'urn:li:digitalmediaRecipe:feedshare-image', + ], + owner: authorUrn, + serviceRelationships: [ { - status: 'READY', - description: { - text: description, - }, - originalUrl, - title: { - text: title, - }, + relationshipType: 'OWNER', + identifier: 'urn:li:userGeneratedContent', }, ], }, - }, - visibility: { - 'com.linkedin.ugc.MemberNetworkVisibility': visibility, - }, - }; - } else { - body = { - author: authorUrn, - lifecycleState: 'PUBLISHED', - specificContent: { - 'com.linkedin.ugc.ShareContent': { - shareCommentary: { - text, + }; + + const registerObject = await linkedInApiRequest.call(this, 'POST', '/assets?action=registerUpload', registerRequest); + + // Response provides a specific upload URL that is used to upload the binary image file + const uploadUrl = registerObject.value.uploadMechanism['com.linkedin.digitalmedia.uploading.MediaUploadHttpRequest'].uploadUrl as string; + const asset = registerObject.value.asset as string; + + // Prepare binary file upload + const item = items[i]; + + if (item.binary === undefined) { + throw new NodeOperationError(this.getNode(), 'No binary data exists on item!'); + } + + const propertyNameUpload = this.getNodeParameter('binaryPropertyName', i) as string; + + if (item.binary[propertyNameUpload] === undefined) { + throw new NodeOperationError(this.getNode(), `No binary data property "${propertyNameUpload}" does not exists on item!`); + } + + // Buffer binary data + const buffer = Buffer.from(item.binary[propertyNameUpload].data, BINARY_ENCODING) as Buffer; + // Upload image + await linkedInApiRequest.call(this, 'POST', uploadUrl, buffer, true); + + body = { + author: authorUrn, + lifecycleState: 'PUBLISHED', + specificContent: { + 'com.linkedin.ugc.ShareContent': { + shareCommentary: { + text, + }, + shareMediaCategory: 'IMAGE', + media: [ + { + status: 'READY', + description: { + text: description, + }, + media: asset, + title: { + text: title, + }, + }, + ], }, - shareMediaCategory, }, - }, - visibility: { - 'com.linkedin.ugc.MemberNetworkVisibility': visibility, - }, - }; + visibility: { + 'com.linkedin.ugc.MemberNetworkVisibility': visibility, + }, + }; + + } else if (shareMediaCategory === 'ARTICLE') { + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + + if (additionalFields.description) { + description = additionalFields.description as string; + } + if (additionalFields.title) { + title = additionalFields.title as string; + } + if (additionalFields.originalUrl) { + originalUrl = additionalFields.originalUrl as string; + } + + body = { + author: `${authorUrn}`, + lifecycleState: 'PUBLISHED', + specificContent: { + 'com.linkedin.ugc.ShareContent': { + shareCommentary: { + text, + }, + shareMediaCategory, + media: [ + { + status: 'READY', + description: { + text: description, + }, + originalUrl, + title: { + text: title, + }, + }, + ], + }, + }, + visibility: { + 'com.linkedin.ugc.MemberNetworkVisibility': visibility, + }, + }; + } else { + body = { + author: authorUrn, + lifecycleState: 'PUBLISHED', + specificContent: { + 'com.linkedin.ugc.ShareContent': { + shareCommentary: { + text, + }, + shareMediaCategory, + }, + }, + visibility: { + 'com.linkedin.ugc.MemberNetworkVisibility': visibility, + }, + }; + } + + const endpoint = '/ugcPosts'; + responseData = await linkedInApiRequest.call(this, 'POST', endpoint, body); } - - const endpoint = '/ugcPosts'; - responseData = await linkedInApiRequest.call(this, 'POST', endpoint, body); } - } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else { - returnData.push(responseData as IDataObject); + if (Array.isArray(responseData)) { + returnData.push.apply(returnData, responseData as IDataObject[]); + } else { + returnData.push(responseData as IDataObject); + } + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } } diff --git a/packages/nodes-base/nodes/Mailcheck/Mailcheck.node.ts b/packages/nodes-base/nodes/Mailcheck/Mailcheck.node.ts index fc0e1ef6e5..2e93f7b66d 100644 --- a/packages/nodes-base/nodes/Mailcheck/Mailcheck.node.ts +++ b/packages/nodes-base/nodes/Mailcheck/Mailcheck.node.ts @@ -95,11 +95,19 @@ export class Mailcheck implements INodeType { 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 === 'email') { - if (operation === 'check') { - const email = this.getNodeParameter('email', i) as string; - responseData = await mailCheckApiRequest.call(this, 'POST', '/singleEmail:check', { email }); + try { + if (resource === 'email') { + if (operation === 'check') { + const email = this.getNodeParameter('email', i) as string; + responseData = await mailCheckApiRequest.call(this, 'POST', '/singleEmail:check', { email }); + } } + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } if (Array.isArray(responseData)) { returnData.push.apply(returnData, responseData as IDataObject[]); @@ -109,4 +117,4 @@ export class Mailcheck implements INodeType { } return [this.helpers.returnJsonArray(returnData)]; } -} \ No newline at end of file +} diff --git a/packages/nodes-base/nodes/Mailchimp/Mailchimp.node.ts b/packages/nodes-base/nodes/Mailchimp/Mailchimp.node.ts index 8426bae101..56c0780246 100644 --- a/packages/nodes-base/nodes/Mailchimp/Mailchimp.node.ts +++ b/packages/nodes-base/nodes/Mailchimp/Mailchimp.node.ts @@ -1862,215 +1862,64 @@ export class Mailchimp implements INodeType { const operation = this.getNodeParameter('operation', 0) as string; for (let i = 0; i < length; i++) { - if (resource === 'listGroup') { - //https://mailchimp.com/developer/reference/lists/interest-categories/#get_/lists/-list_id-/interest-categories/-interest_category_id- - if (operation === 'getAll') { - const listId = this.getNodeParameter('list', i) as string; - const categoryId = this.getNodeParameter('groupCategory', i) as string; - const returnAll = this.getNodeParameter('returnAll', i) as boolean; + try { + if (resource === 'listGroup') { + //https://mailchimp.com/developer/reference/lists/interest-categories/#get_/lists/-list_id-/interest-categories/-interest_category_id- + if (operation === 'getAll') { + const listId = this.getNodeParameter('list', i) as string; + const categoryId = this.getNodeParameter('groupCategory', i) as string; + const returnAll = this.getNodeParameter('returnAll', i) as boolean; - if (returnAll === true) { - responseData = await mailchimpApiRequestAllItems.call(this, `/lists/${listId}/interest-categories/${categoryId}/interests`, 'GET', 'interests', {}, qs); - } else { - qs.count = this.getNodeParameter('limit', i) as number; - responseData = await mailchimpApiRequest.call(this, `/lists/${listId}/interest-categories/${categoryId}/interests`, 'GET', {}, qs); - responseData = responseData.interests; + if (returnAll === true) { + responseData = await mailchimpApiRequestAllItems.call(this, `/lists/${listId}/interest-categories/${categoryId}/interests`, 'GET', 'interests', {}, qs); + } else { + qs.count = this.getNodeParameter('limit', i) as number; + responseData = await mailchimpApiRequest.call(this, `/lists/${listId}/interest-categories/${categoryId}/interests`, 'GET', {}, qs); + responseData = responseData.interests; + } } } - } - if (resource === 'member') { - //https://mailchimp.com/developer/reference/lists/list-members/#post_/lists/-list_id-/members - if (operation === 'create') { - const listId = this.getNodeParameter('list', i) as string; - const email = this.getNodeParameter('email', i) as string; - const status = this.getNodeParameter('status', i) as Status; - const options = this.getNodeParameter('options', i) as IDataObject; - const jsonActive = this.getNodeParameter('jsonParameters', i) as IDataObject; + if (resource === 'member') { + //https://mailchimp.com/developer/reference/lists/list-members/#post_/lists/-list_id-/members + if (operation === 'create') { + const listId = this.getNodeParameter('list', i) as string; + const email = this.getNodeParameter('email', i) as string; + const status = this.getNodeParameter('status', i) as Status; + const options = this.getNodeParameter('options', i) as IDataObject; + const jsonActive = this.getNodeParameter('jsonParameters', i) as IDataObject; - const body: ICreateMemberBody = { - listId, - email_address: email, - status, - }; - if (options.emailType) { - body.email_type = options.emailType as string; - } - if (options.language) { - body.language = options.language as string; - } - if (options.vip) { - body.vip = options.vip as boolean; - } - if (options.ipSignup) { - body.ip_signup = options.ipSignup as string; - } - if (options.ipOptIn) { - body.ip_opt = options.ipOptIn as string; - } - if (options.timestampOpt) { - body.timestamp_opt = moment(options.timestampOpt as string).format('YYYY-MM-DD HH:MM:SS') as string; - } - if (options.timestampSignup) { - body.timestamp_signup = moment(options.timestampSignup as string).format('YYYY-MM-DD HH:MM:SS') as string; - } - if (options.tags) { - // @ts-ignore - body.tags = options.tags.split(',') as string[]; - } - if (!jsonActive) { - const locationValues = (this.getNodeParameter('locationFieldsUi', i) as IDataObject).locationFieldsValues as IDataObject; - if (locationValues) { - const location: ILocation = {}; - for (const key of Object.keys(locationValues)) { - if (key === 'latitude') { - location.latitude = parseFloat(locationValues[key] as string) as number; - } else if (key === 'longitude') { - location.longitude = parseFloat(locationValues[key] as string) as number; - } - } - body.location = location; + const body: ICreateMemberBody = { + listId, + email_address: email, + status, + }; + if (options.emailType) { + body.email_type = options.emailType as string; } - const mergeFieldsValues = (this.getNodeParameter('mergeFieldsUi', i) as IDataObject).mergeFieldsValues as IDataObject[]; - if (mergeFieldsValues) { - const mergeFields = {}; - for (let i = 0; i < mergeFieldsValues.length; i++) { - // @ts-ignore - mergeFields[mergeFieldsValues[i].name] = mergeFieldsValues[i].value; - } - body.merge_fields = mergeFields; + if (options.language) { + body.language = options.language as string; } - - const groupsValues = (this.getNodeParameter('groupsUi', i) as IDataObject).groupsValues as IDataObject[]; - if (groupsValues) { - const groups = {}; - for (let i = 0; i < groupsValues.length; i++) { - // @ts-ignore - groups[groupsValues[i].categoryFieldId] = groupsValues[i].value; - } - body.interests = groups; + if (options.vip) { + body.vip = options.vip as boolean; } - } else { - const locationJson = validateJSON(this.getNodeParameter('locationJson', i) as string); - const mergeFieldsJson = validateJSON(this.getNodeParameter('mergeFieldsJson', i) as string); - const groupJson = validateJSON(this.getNodeParameter('groupJson', i) as string); - if (locationJson) { - body.location = locationJson; + if (options.ipSignup) { + body.ip_signup = options.ipSignup as string; } - if (mergeFieldsJson) { - body.merge_fields = mergeFieldsJson; + if (options.ipOptIn) { + body.ip_opt = options.ipOptIn as string; } - if (groupJson) { - body.interests = groupJson; + if (options.timestampOpt) { + body.timestamp_opt = moment(options.timestampOpt as string).format('YYYY-MM-DD HH:MM:SS') as string; } - } - responseData = await mailchimpApiRequest.call(this, `/lists/${listId}/members`, 'POST', body); - } - //https://mailchimp.com/developer/reference/lists/list-members/ - if (operation === 'delete') { - - const listId = this.getNodeParameter('list', i) as string; - const email = this.getNodeParameter('email', i) as string; - - responseData = await mailchimpApiRequest.call(this, `/lists/${listId}/members/${email}/actions/delete-permanent`, 'POST'); - responseData = { success: true }; - } - //https://mailchimp.com/developer/reference/lists/list-members/#get_/lists/-list_id-/members/-subscriber_hash- - if (operation === 'get') { - - const listId = this.getNodeParameter('list', i) as string; - const email = this.getNodeParameter('email', i) as string; - const options = this.getNodeParameter('options', i) as IDataObject; - - if (options.fields) { - qs.fields = options.fields as string; - } - - if (options.excludeFields) { - qs.exclude_fields = options.excludeFields as string; - } - - responseData = await mailchimpApiRequest.call(this, `/lists/${listId}/members/${email}`, 'GET', {}, qs); - } - //https://mailchimp.com/developer/reference/lists/list-members/#get_/lists/-list_id-/members - if (operation === 'getAll') { - const listId = this.getNodeParameter('list', i) as string; - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - const options = this.getNodeParameter('options', i) as IDataObject; - - if (options.beforeLastChanged) { - qs.before_last_changed = options.beforeLastChanged as string; - } - if (options.beforeTimestampOpt) { - qs.before_timestamp_opt = options.beforeTimestampOpt as string; - } - // TODO - //figure why for some reason when either fields or exclude_fields is set the endpoint returns nothing - // interestingly it works perfect when retriving just one member - - // if (options.fields) { - // qs.fields = options.fields as string; - // } - // if (options.excludeFields) { - // qs.exclude_fields = options.excludeFields as string; - // } - if (options.emailType) { - qs.email_type = options.emailType as string; - } - if (options.status) { - qs.status = options.status as string; - } - if (options.sinceLastChanged) { - qs.since_last_changed = options.sinceLastChanged as string; - } - if (returnAll === true) { - responseData = await mailchimpApiRequestAllItems.call(this, `/lists/${listId}/members`, 'GET', 'members', {}, qs); - } else { - qs.count = this.getNodeParameter('limit', i) as number; - responseData = await mailchimpApiRequest.call(this, `/lists/${listId}/members`, 'GET', {}, qs); - responseData = responseData.members; - } - } - //https://mailchimp.com/developer/reference/lists/list-members/#put_/lists/-list_id-/members/-subscriber_hash- - if (operation === 'update') { - - const listId = this.getNodeParameter('list', i) as string; - const email = this.getNodeParameter('email', i) as string; - const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; - const jsonActive = this.getNodeParameter('jsonParameters', i) as IDataObject; - const body: ICreateMemberBody = { - listId, - email_address: email, - }; - if (updateFields.skipMergeValidation) { - qs.skip_merge_validation = updateFields.skipMergeValidation as boolean; - } - if (updateFields.status) { - body.status = updateFields.status as Status; - } - if (updateFields.emailType) { - body.email_type = updateFields.emailType as string; - } - if (updateFields.language) { - body.language = updateFields.language as string; - } - if (updateFields.vip) { - body.vip = updateFields.vip as boolean; - } - if (updateFields.ipSignup) { - body.ip_signup = updateFields.ipSignup as string; - } - if (updateFields.ipOptIn) { - body.ip_opt = updateFields.ipOptIn as string; - } - if (updateFields.timestampOpt) { - body.timestamp_opt = moment(updateFields.timestampOpt as string).format('YYYY-MM-DD HH:MM:SS') as string; - } - if (updateFields.timestampSignup) { - body.timestamp_signup = moment(updateFields.timestampSignup as string).format('YYYY-MM-DD HH:MM:SS') as string; - } - if (!jsonActive) { - if (updateFields.locationFieldsUi) { - const locationValues = (updateFields.locationFieldsUi as IDataObject).locationFieldsValues as IDataObject; + if (options.timestampSignup) { + body.timestamp_signup = moment(options.timestampSignup as string).format('YYYY-MM-DD HH:MM:SS') as string; + } + if (options.tags) { + // @ts-ignore + body.tags = options.tags.split(',') as string[]; + } + if (!jsonActive) { + const locationValues = (this.getNodeParameter('locationFieldsUi', i) as IDataObject).locationFieldsValues as IDataObject; if (locationValues) { const location: ILocation = {}; for (const key of Object.keys(locationValues)) { @@ -2082,9 +1931,7 @@ export class Mailchimp implements INodeType { } body.location = location; } - } - if (updateFields.mergeFieldsUi) { - const mergeFieldsValues = (updateFields.mergeFieldsUi as IDataObject).mergeFieldsValues as IDataObject[]; + const mergeFieldsValues = (this.getNodeParameter('mergeFieldsUi', i) as IDataObject).mergeFieldsValues as IDataObject[]; if (mergeFieldsValues) { const mergeFields = {}; for (let i = 0; i < mergeFieldsValues.length; i++) { @@ -2093,9 +1940,8 @@ export class Mailchimp implements INodeType { } body.merge_fields = mergeFields; } - } - if (updateFields.groupsUi) { - const groupsValues = (updateFields.groupsUi as IDataObject).groupsValues as IDataObject[]; + + const groupsValues = (this.getNodeParameter('groupsUi', i) as IDataObject).groupsValues as IDataObject[]; if (groupsValues) { const groups = {}; for (let i = 0; i < groupsValues.length; i++) { @@ -2104,168 +1950,330 @@ export class Mailchimp implements INodeType { } body.interests = groups; } + } else { + const locationJson = validateJSON(this.getNodeParameter('locationJson', i) as string); + const mergeFieldsJson = validateJSON(this.getNodeParameter('mergeFieldsJson', i) as string); + const groupJson = validateJSON(this.getNodeParameter('groupJson', i) as string); + if (locationJson) { + body.location = locationJson; + } + if (mergeFieldsJson) { + body.merge_fields = mergeFieldsJson; + } + if (groupJson) { + body.interests = groupJson; + } } - } else { - const locationJson = validateJSON(this.getNodeParameter('locationJson', i) as string); - const mergeFieldsJson = validateJSON(this.getNodeParameter('mergeFieldsJson', i) as string); - const groupJson = validateJSON(this.getNodeParameter('groupJson', i) as string); + responseData = await mailchimpApiRequest.call(this, `/lists/${listId}/members`, 'POST', body); + } + //https://mailchimp.com/developer/reference/lists/list-members/ + if (operation === 'delete') { - if (locationJson) { - body.location = locationJson; + const listId = this.getNodeParameter('list', i) as string; + const email = this.getNodeParameter('email', i) as string; + + responseData = await mailchimpApiRequest.call(this, `/lists/${listId}/members/${email}/actions/delete-permanent`, 'POST'); + responseData = { success: true }; + } + //https://mailchimp.com/developer/reference/lists/list-members/#get_/lists/-list_id-/members/-subscriber_hash- + if (operation === 'get') { + + const listId = this.getNodeParameter('list', i) as string; + const email = this.getNodeParameter('email', i) as string; + const options = this.getNodeParameter('options', i) as IDataObject; + + if (options.fields) { + qs.fields = options.fields as string; } - if (mergeFieldsJson) { - body.merge_fields = mergeFieldsJson; + + if (options.excludeFields) { + qs.exclude_fields = options.excludeFields as string; } - if (groupJson) { - body.interests = groupJson; + + responseData = await mailchimpApiRequest.call(this, `/lists/${listId}/members/${email}`, 'GET', {}, qs); + } + //https://mailchimp.com/developer/reference/lists/list-members/#get_/lists/-list_id-/members + if (operation === 'getAll') { + const listId = this.getNodeParameter('list', i) as string; + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + const options = this.getNodeParameter('options', i) as IDataObject; + + if (options.beforeLastChanged) { + qs.before_last_changed = options.beforeLastChanged as string; + } + if (options.beforeTimestampOpt) { + qs.before_timestamp_opt = options.beforeTimestampOpt as string; + } + // TODO + //figure why for some reason when either fields or exclude_fields is set the endpoint returns nothing + // interestingly it works perfect when retriving just one member + + // if (options.fields) { + // qs.fields = options.fields as string; + // } + // if (options.excludeFields) { + // qs.exclude_fields = options.excludeFields as string; + // } + if (options.emailType) { + qs.email_type = options.emailType as string; + } + if (options.status) { + qs.status = options.status as string; + } + if (options.sinceLastChanged) { + qs.since_last_changed = options.sinceLastChanged as string; + } + if (returnAll === true) { + responseData = await mailchimpApiRequestAllItems.call(this, `/lists/${listId}/members`, 'GET', 'members', {}, qs); + } else { + qs.count = this.getNodeParameter('limit', i) as number; + responseData = await mailchimpApiRequest.call(this, `/lists/${listId}/members`, 'GET', {}, qs); + responseData = responseData.members; } } - responseData = await mailchimpApiRequest.call(this, `/lists/${listId}/members/${email}`, 'PUT', body); - } - } - if (resource === 'memberTag') { - //https://mailchimp.com/developer/reference/lists/list-members/list-member-tags/#post_/lists/-list_id-/members/-subscriber_hash-/tags - if (operation === 'create') { - const listId = this.getNodeParameter('list', i) as string; - const email = this.getNodeParameter('email', i) as string; - const tags = this.getNodeParameter('tags', i) as string[]; - const options = this.getNodeParameter('options', i) as IDataObject; + //https://mailchimp.com/developer/reference/lists/list-members/#put_/lists/-list_id-/members/-subscriber_hash- + if (operation === 'update') { - const body: IDataObject = { - tags: [], - }; - - if (options.isSyncing) { - body.is_syncing = options.isSyncing as boolean; - } - - for (const tag of tags) { - //@ts-ignore - body.tags.push({ - name: tag, - status: 'active', - }); - } - - responseData = await mailchimpApiRequest.call(this, `/lists/${listId}/members/${email}/tags`, 'POST', body); - responseData = { success: true }; - } - //https://mailchimp.com/developer/reference/lists/list-members/list-member-tags/#post_/lists/-list_id-/members/-subscriber_hash-/tags - if (operation === 'delete') { - - const listId = this.getNodeParameter('list', i) as string; - const email = this.getNodeParameter('email', i) as string; - const tags = this.getNodeParameter('tags', i) as string[]; - const options = this.getNodeParameter('options', i) as IDataObject; - - const body: IDataObject = { - tags: [], - }; - - if (options.isSyncing) { - body.is_syncing = options.isSyncing as boolean; - } - - for (const tag of tags) { - //@ts-ignore - body.tags.push({ - name: tag, - status: 'inactive', - }); - } - responseData = await mailchimpApiRequest.call(this, `/lists/${listId}/members/${email}/tags`, 'POST', body); - responseData = { success: true }; - } - } - if (resource === 'campaign') { - //https://mailchimp.com/developer/api/marketing/campaigns/list-campaigns/ - if (operation === 'getAll') { - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - const options = this.getNodeParameter('options', i) as IDataObject; - if (options.status) { - qs.status = options.status as string; - } - if (options.beforeCreateTime) { - qs.before_create_time = options.beforeCreateTime as string; - } - if (options.beforeSendTime) { - qs.before_send_time = options.beforeSendTime as string; - } - if (options.excludeFields) { - qs.exclude_fields = (options.exclude_fields as string[]).join(','); - } - if (options.fields) { - qs.fields = (options.fields as string[]).join(','); - if ((options.fields as string[]).includes('*')) { - qs.fields = campaignFieldsMetadata.join(','); + const listId = this.getNodeParameter('list', i) as string; + const email = this.getNodeParameter('email', i) as string; + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + const jsonActive = this.getNodeParameter('jsonParameters', i) as IDataObject; + const body: ICreateMemberBody = { + listId, + email_address: email, + }; + if (updateFields.skipMergeValidation) { + qs.skip_merge_validation = updateFields.skipMergeValidation as boolean; } - } else { - qs.fields = [ - 'campaigns.id', - 'campaigns.status', - 'campaigns.tracking', - 'campaigns.settings.from_name', - 'campaigns.settings.title', - 'campaigns.settings.reply_to', - ].join(','); - } + if (updateFields.status) { + body.status = updateFields.status as Status; + } + if (updateFields.emailType) { + body.email_type = updateFields.emailType as string; + } + if (updateFields.language) { + body.language = updateFields.language as string; + } + if (updateFields.vip) { + body.vip = updateFields.vip as boolean; + } + if (updateFields.ipSignup) { + body.ip_signup = updateFields.ipSignup as string; + } + if (updateFields.ipOptIn) { + body.ip_opt = updateFields.ipOptIn as string; + } + if (updateFields.timestampOpt) { + body.timestamp_opt = moment(updateFields.timestampOpt as string).format('YYYY-MM-DD HH:MM:SS') as string; + } + if (updateFields.timestampSignup) { + body.timestamp_signup = moment(updateFields.timestampSignup as string).format('YYYY-MM-DD HH:MM:SS') as string; + } + if (!jsonActive) { + if (updateFields.locationFieldsUi) { + const locationValues = (updateFields.locationFieldsUi as IDataObject).locationFieldsValues as IDataObject; + if (locationValues) { + const location: ILocation = {}; + for (const key of Object.keys(locationValues)) { + if (key === 'latitude') { + location.latitude = parseFloat(locationValues[key] as string) as number; + } else if (key === 'longitude') { + location.longitude = parseFloat(locationValues[key] as string) as number; + } + } + body.location = location; + } + } + if (updateFields.mergeFieldsUi) { + const mergeFieldsValues = (updateFields.mergeFieldsUi as IDataObject).mergeFieldsValues as IDataObject[]; + if (mergeFieldsValues) { + const mergeFields = {}; + for (let i = 0; i < mergeFieldsValues.length; i++) { + // @ts-ignore + mergeFields[mergeFieldsValues[i].name] = mergeFieldsValues[i].value; + } + body.merge_fields = mergeFields; + } + } + if (updateFields.groupsUi) { + const groupsValues = (updateFields.groupsUi as IDataObject).groupsValues as IDataObject[]; + if (groupsValues) { + const groups = {}; + for (let i = 0; i < groupsValues.length; i++) { + // @ts-ignore + groups[groupsValues[i].categoryFieldId] = groupsValues[i].value; + } + body.interests = groups; + } + } + } else { + const locationJson = validateJSON(this.getNodeParameter('locationJson', i) as string); + const mergeFieldsJson = validateJSON(this.getNodeParameter('mergeFieldsJson', i) as string); + const groupJson = validateJSON(this.getNodeParameter('groupJson', i) as string); - if (options.listId) { - qs.list_id = options.listId as string; - } - if (options.sinceCreateTime) { - qs.since_create_time = options.sinceCreateTime as string; - } - if (options.sinceSendTime) { - qs.since_send_time = options.sinceSendTime as string; - } - if (options.sortDirection) { - qs.sort_dir = options.sortDirection as string; - } - if (options.sortField) { - qs.sort_field = options.sortField as string; - } - if (returnAll === true) { - responseData = await mailchimpApiRequestAllItems.call(this, `/campaigns`, 'GET', 'campaigns', {}, qs); - } else { - qs.count = this.getNodeParameter('limit', i) as number; - responseData = await mailchimpApiRequest.call(this, `/campaigns`, 'GET', {}, qs); - responseData = responseData.campaigns; + if (locationJson) { + body.location = locationJson; + } + if (mergeFieldsJson) { + body.merge_fields = mergeFieldsJson; + } + if (groupJson) { + body.interests = groupJson; + } + } + responseData = await mailchimpApiRequest.call(this, `/lists/${listId}/members/${email}`, 'PUT', body); } } - //https://mailchimp.com/developer/api/marketing/campaigns/send-campaign/ - if (operation === 'send') { - const campaignId = this.getNodeParameter('campaignId', i) as string; - responseData = await mailchimpApiRequest.call(this, `/campaigns/${campaignId}/actions/send`, 'POST', {}); - responseData = { success: true }; - } - //https://mailchimp.com/developer/api/marketing/campaigns/get-campaign-info/ - if (operation === 'get') { - const campaignId = this.getNodeParameter('campaignId', i) as string; - responseData = await mailchimpApiRequest.call(this, `/campaigns/${campaignId}`, 'GET', {}); - } - //https://mailchimp.com/developer/api/marketing/campaigns/delete-campaign/ - if (operation === 'delete') { - const campaignId = this.getNodeParameter('campaignId', i) as string; - responseData = await mailchimpApiRequest.call(this, `/campaigns/${campaignId}`, 'DELETE', {}); - responseData = { success: true }; - } - //https://mailchimp.com/developer/api/marketing/campaigns/replicate-campaign/ - if (operation === 'replicate') { - const campaignId = this.getNodeParameter('campaignId', i) as string; - responseData = await mailchimpApiRequest.call(this, `/campaigns/${campaignId}/actions/replicate`, 'POST', {}); - } - //https://mailchimp.com/developer/api/marketing/campaigns/resend-campaign/ - if (operation === 'resend') { - const campaignId = this.getNodeParameter('campaignId', i) as string; - responseData = await mailchimpApiRequest.call(this, `/campaigns/${campaignId}/actions/create-resend`, 'POST', {}); - } - } + if (resource === 'memberTag') { + //https://mailchimp.com/developer/reference/lists/list-members/list-member-tags/#post_/lists/-list_id-/members/-subscriber_hash-/tags + if (operation === 'create') { + const listId = this.getNodeParameter('list', i) as string; + const email = this.getNodeParameter('email', i) as string; + const tags = this.getNodeParameter('tags', i) as string[]; + const options = this.getNodeParameter('options', i) as IDataObject; - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else { - returnData.push(responseData as IDataObject); + const body: IDataObject = { + tags: [], + }; + + if (options.isSyncing) { + body.is_syncing = options.isSyncing as boolean; + } + + for (const tag of tags) { + //@ts-ignore + body.tags.push({ + name: tag, + status: 'active', + }); + } + + responseData = await mailchimpApiRequest.call(this, `/lists/${listId}/members/${email}/tags`, 'POST', body); + responseData = { success: true }; + } + //https://mailchimp.com/developer/reference/lists/list-members/list-member-tags/#post_/lists/-list_id-/members/-subscriber_hash-/tags + if (operation === 'delete') { + + const listId = this.getNodeParameter('list', i) as string; + const email = this.getNodeParameter('email', i) as string; + const tags = this.getNodeParameter('tags', i) as string[]; + const options = this.getNodeParameter('options', i) as IDataObject; + + const body: IDataObject = { + tags: [], + }; + + if (options.isSyncing) { + body.is_syncing = options.isSyncing as boolean; + } + + for (const tag of tags) { + //@ts-ignore + body.tags.push({ + name: tag, + status: 'inactive', + }); + } + responseData = await mailchimpApiRequest.call(this, `/lists/${listId}/members/${email}/tags`, 'POST', body); + responseData = { success: true }; + } + } + if (resource === 'campaign') { + //https://mailchimp.com/developer/api/marketing/campaigns/list-campaigns/ + if (operation === 'getAll') { + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + const options = this.getNodeParameter('options', i) as IDataObject; + if (options.status) { + qs.status = options.status as string; + } + if (options.beforeCreateTime) { + qs.before_create_time = options.beforeCreateTime as string; + } + if (options.beforeSendTime) { + qs.before_send_time = options.beforeSendTime as string; + } + if (options.excludeFields) { + qs.exclude_fields = (options.exclude_fields as string[]).join(','); + } + if (options.fields) { + qs.fields = (options.fields as string[]).join(','); + if ((options.fields as string[]).includes('*')) { + qs.fields = campaignFieldsMetadata.join(','); + } + } else { + qs.fields = [ + 'campaigns.id', + 'campaigns.status', + 'campaigns.tracking', + 'campaigns.settings.from_name', + 'campaigns.settings.title', + 'campaigns.settings.reply_to', + ].join(','); + } + + if (options.listId) { + qs.list_id = options.listId as string; + } + if (options.sinceCreateTime) { + qs.since_create_time = options.sinceCreateTime as string; + } + if (options.sinceSendTime) { + qs.since_send_time = options.sinceSendTime as string; + } + if (options.sortDirection) { + qs.sort_dir = options.sortDirection as string; + } + if (options.sortField) { + qs.sort_field = options.sortField as string; + } + if (returnAll === true) { + responseData = await mailchimpApiRequestAllItems.call(this, `/campaigns`, 'GET', 'campaigns', {}, qs); + } else { + qs.count = this.getNodeParameter('limit', i) as number; + responseData = await mailchimpApiRequest.call(this, `/campaigns`, 'GET', {}, qs); + responseData = responseData.campaigns; + } + } + //https://mailchimp.com/developer/api/marketing/campaigns/send-campaign/ + if (operation === 'send') { + const campaignId = this.getNodeParameter('campaignId', i) as string; + responseData = await mailchimpApiRequest.call(this, `/campaigns/${campaignId}/actions/send`, 'POST', {}); + responseData = { success: true }; + } + //https://mailchimp.com/developer/api/marketing/campaigns/get-campaign-info/ + if (operation === 'get') { + const campaignId = this.getNodeParameter('campaignId', i) as string; + responseData = await mailchimpApiRequest.call(this, `/campaigns/${campaignId}`, 'GET', {}); + } + //https://mailchimp.com/developer/api/marketing/campaigns/delete-campaign/ + if (operation === 'delete') { + const campaignId = this.getNodeParameter('campaignId', i) as string; + responseData = await mailchimpApiRequest.call(this, `/campaigns/${campaignId}`, 'DELETE', {}); + responseData = { success: true }; + } + //https://mailchimp.com/developer/api/marketing/campaigns/replicate-campaign/ + if (operation === 'replicate') { + const campaignId = this.getNodeParameter('campaignId', i) as string; + responseData = await mailchimpApiRequest.call(this, `/campaigns/${campaignId}/actions/replicate`, 'POST', {}); + } + //https://mailchimp.com/developer/api/marketing/campaigns/resend-campaign/ + if (operation === 'resend') { + const campaignId = this.getNodeParameter('campaignId', i) as string; + responseData = await mailchimpApiRequest.call(this, `/campaigns/${campaignId}/actions/create-resend`, 'POST', {}); + } + } + + if (Array.isArray(responseData)) { + returnData.push.apply(returnData, responseData as IDataObject[]); + } else { + returnData.push(responseData as IDataObject); + } + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } } return [this.helpers.returnJsonArray(returnData)]; diff --git a/packages/nodes-base/nodes/MailerLite/MailerLite.node.ts b/packages/nodes-base/nodes/MailerLite/MailerLite.node.ts index 1e383fd0b8..5af98721b7 100644 --- a/packages/nodes-base/nodes/MailerLite/MailerLite.node.ts +++ b/packages/nodes-base/nodes/MailerLite/MailerLite.node.ts @@ -88,90 +88,97 @@ export class MailerLite implements INodeType { const resource = this.getNodeParameter('resource', 0) as string; const operation = this.getNodeParameter('operation', 0) as string; for (let i = 0; i < length; i++) { + try { + if (resource === 'subscriber') { + //https://developers.mailerlite.com/reference#create-a-subscriber + if (operation === 'create') { + const email = this.getNodeParameter('email', i) as string; - if (resource === 'subscriber') { - //https://developers.mailerlite.com/reference#create-a-subscriber - if (operation === 'create') { - const email = this.getNodeParameter('email', i) as string; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const body: IDataObject = { + email, + fields: [], + }; - const body: IDataObject = { - email, - fields: [], - }; + Object.assign(body, additionalFields); - Object.assign(body, additionalFields); + if (additionalFields.customFieldsUi) { + const customFieldsValues = (additionalFields.customFieldsUi as IDataObject).customFieldsValues as IDataObject[]; - if (additionalFields.customFieldsUi) { - const customFieldsValues = (additionalFields.customFieldsUi as IDataObject).customFieldsValues as IDataObject[]; + if (customFieldsValues) { + const fields = {}; - if (customFieldsValues) { - const fields = {}; + for (const customFieldValue of customFieldsValues) { + //@ts-ignore + fields[customFieldValue.fieldId] = customFieldValue.value; + } - for (const customFieldValue of customFieldsValues) { - //@ts-ignore - fields[customFieldValue.fieldId] = customFieldValue.value; + body.fields = fields; + delete body.customFieldsUi; } + } - body.fields = fields; - delete body.customFieldsUi; + responseData = await mailerliteApiRequest.call(this, 'POST', '/subscribers', body); + } + //https://developers.mailerlite.com/reference#single-subscriber + if (operation === 'get') { + const subscriberId = this.getNodeParameter('subscriberId', i) as string; + + responseData = await mailerliteApiRequest.call(this, 'GET', `/subscribers/${subscriberId}`); + } + //https://developers.mailerlite.com/reference#subscribers + if (operation === 'getAll') { + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + + const filters = this.getNodeParameter('filters', i) as IDataObject; + + Object.assign(qs, filters); + + if (returnAll) { + + responseData = await mailerliteApiRequestAllItems.call(this, 'GET', `/subscribers`, {}, qs); + } else { + qs.limit = this.getNodeParameter('limit', i) as number; + + responseData = await mailerliteApiRequest.call(this, 'GET', `/subscribers`, {}, qs); } } + //https://developers.mailerlite.com/reference#update-subscriber + if (operation === 'update') { + const subscriberId = this.getNodeParameter('subscriberId', i) as string; - responseData = await mailerliteApiRequest.call(this, 'POST', '/subscribers', body); - } - //https://developers.mailerlite.com/reference#single-subscriber - if (operation === 'get') { - const subscriberId = this.getNodeParameter('subscriberId', i) as string; + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; - responseData = await mailerliteApiRequest.call(this, 'GET', `/subscribers/${subscriberId}`); - } - //https://developers.mailerlite.com/reference#subscribers - if (operation === 'getAll') { - const returnAll = this.getNodeParameter('returnAll', i) as boolean; + const body: IDataObject = {}; - const filters = this.getNodeParameter('filters', i) as IDataObject; + Object.assign(body, updateFields); - Object.assign(qs, filters); + if (updateFields.customFieldsUi) { + const customFieldsValues = (updateFields.customFieldsUi as IDataObject).customFieldsValues as IDataObject[]; - if (returnAll) { + if (customFieldsValues) { + const fields = {}; - responseData = await mailerliteApiRequestAllItems.call(this, 'GET', `/subscribers`, {}, qs); - } else { - qs.limit = this.getNodeParameter('limit', i) as number; + for (const customFieldValue of customFieldsValues) { + //@ts-ignore + fields[customFieldValue.fieldId] = customFieldValue.value; + } - responseData = await mailerliteApiRequest.call(this, 'GET', `/subscribers`, {}, qs); - } - } - //https://developers.mailerlite.com/reference#update-subscriber - if (operation === 'update') { - const subscriberId = this.getNodeParameter('subscriberId', i) as string; - - const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; - - const body: IDataObject = {}; - - Object.assign(body, updateFields); - - if (updateFields.customFieldsUi) { - const customFieldsValues = (updateFields.customFieldsUi as IDataObject).customFieldsValues as IDataObject[]; - - if (customFieldsValues) { - const fields = {}; - - for (const customFieldValue of customFieldsValues) { - //@ts-ignore - fields[customFieldValue.fieldId] = customFieldValue.value; + body.fields = fields; + delete body.customFieldsUi; } - - body.fields = fields; - delete body.customFieldsUi; } - } - responseData = await mailerliteApiRequest.call(this, 'PUT', `/subscribers/${subscriberId}`, body); + responseData = await mailerliteApiRequest.call(this, 'PUT', `/subscribers/${subscriberId}`, body); + } } + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } } if (Array.isArray(responseData)) { diff --git a/packages/nodes-base/nodes/Mailgun/Mailgun.node.ts b/packages/nodes-base/nodes/Mailgun/Mailgun.node.ts index b59db606d0..8bde27f8bb 100644 --- a/packages/nodes-base/nodes/Mailgun/Mailgun.node.ts +++ b/packages/nodes-base/nodes/Mailgun/Mailgun.node.ts @@ -115,86 +115,94 @@ export class Mailgun implements INodeType { let item: INodeExecutionData; for (let itemIndex = 0; itemIndex < length; itemIndex++) { - item = items[itemIndex]; + try { + item = items[itemIndex]; - const fromEmail = this.getNodeParameter('fromEmail', itemIndex) as string; - const toEmail = this.getNodeParameter('toEmail', itemIndex) as string; - const ccEmail = this.getNodeParameter('ccEmail', itemIndex) as string; - const bccEmail = this.getNodeParameter('bccEmail', itemIndex) as string; - const subject = this.getNodeParameter('subject', itemIndex) as string; - const text = this.getNodeParameter('text', itemIndex) as string; - const html = this.getNodeParameter('html', itemIndex) as string; - const attachmentPropertyString = this.getNodeParameter('attachments', itemIndex) as string; + const fromEmail = this.getNodeParameter('fromEmail', itemIndex) as string; + const toEmail = this.getNodeParameter('toEmail', itemIndex) as string; + const ccEmail = this.getNodeParameter('ccEmail', itemIndex) as string; + const bccEmail = this.getNodeParameter('bccEmail', itemIndex) as string; + const subject = this.getNodeParameter('subject', itemIndex) as string; + const text = this.getNodeParameter('text', itemIndex) as string; + const html = this.getNodeParameter('html', itemIndex) as string; + const attachmentPropertyString = this.getNodeParameter('attachments', itemIndex) as string; - const credentials = this.getCredentials('mailgunApi'); + const credentials = this.getCredentials('mailgunApi'); - if (credentials === undefined) { - throw new NodeOperationError(this.getNode(), 'No credentials got returned!'); - } + if (credentials === undefined) { + throw new NodeOperationError(this.getNode(), 'No credentials got returned!'); + } - const formData: IDataObject = { - from: fromEmail, - to: toEmail, - subject, - text, - html, - }; + const formData: IDataObject = { + from: fromEmail, + to: toEmail, + subject, + text, + html, + }; - if (ccEmail.length !== 0) { - formData.cc = ccEmail; - } - if (bccEmail.length !== 0) { - formData.bcc = bccEmail; - } + if (ccEmail.length !== 0) { + formData.cc = ccEmail; + } + if (bccEmail.length !== 0) { + formData.bcc = bccEmail; + } - if (attachmentPropertyString && item.binary) { + if (attachmentPropertyString && item.binary) { - const attachments = []; - const attachmentProperties: string[] = attachmentPropertyString.split(',').map((propertyName) => { - return propertyName.trim(); - }); - - for (const propertyName of attachmentProperties) { - if (!item.binary.hasOwnProperty(propertyName)) { - continue; - } - attachments.push({ - value: Buffer.from(item.binary[propertyName].data, BINARY_ENCODING), - options: { - filename: item.binary[propertyName].fileName || 'unknown', - - }, + const attachments = []; + const attachmentProperties: string[] = attachmentPropertyString.split(',').map((propertyName) => { + return propertyName.trim(); }); + + for (const propertyName of attachmentProperties) { + if (!item.binary.hasOwnProperty(propertyName)) { + continue; + } + attachments.push({ + value: Buffer.from(item.binary[propertyName].data, BINARY_ENCODING), + options: { + filename: item.binary[propertyName].fileName || 'unknown', + + }, + }); + } + + if (attachments.length) { + // @ts-ignore + formData.attachment = attachments; + } } - if (attachments.length) { - // @ts-ignore - formData.attachment = attachments; + const options = { + method: 'POST', + formData, + uri: `https://${credentials.apiDomain}/v3/${credentials.emailDomain}/messages`, + auth: { + user: 'api', + pass: credentials.apiKey as string, + }, + json: true, + }; + + let responseData; + + try { + responseData = await this.helpers.request(options); + } catch (error) { + throw new NodeApiError(this.getNode(), error); } + + returnData.push({ + json: responseData, + }); + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ json: { error: error.message } }); + continue; + } + throw error; } - - const options = { - method: 'POST', - formData, - uri: `https://${credentials.apiDomain}/v3/${credentials.emailDomain}/messages`, - auth: { - user: 'api', - pass: credentials.apiKey as string, - }, - json: true, - }; - - let responseData; - - try { - responseData = await this.helpers.request(options); - } catch (error) { - throw new NodeApiError(this.getNode(), error); - } - - returnData.push({ - json: responseData, - }); } return this.prepareOutputData(returnData); } diff --git a/packages/nodes-base/nodes/Mailjet/Mailjet.node.ts b/packages/nodes-base/nodes/Mailjet/Mailjet.node.ts index 5e85b47848..f32dc440bf 100644 --- a/packages/nodes-base/nodes/Mailjet/Mailjet.node.ts +++ b/packages/nodes-base/nodes/Mailjet/Mailjet.node.ts @@ -117,175 +117,183 @@ export class Mailjet implements INodeType { const operation = this.getNodeParameter('operation', 0) as string; for (let i = 0; i < length; i++) { - if (resource === 'email') { - //https://dev.mailjet.com/email/guides/send-api-v31/#send-a-basic-email - if (operation === 'send') { - const fromEmail = this.getNodeParameter('fromEmail', i) as string; - const htmlBody = this.getNodeParameter('html', i) as string; - const textBody = this.getNodeParameter('text', i) as string; - const subject = this.getNodeParameter('subject', i) as string; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const toEmail = (this.getNodeParameter('toEmail', i) as string).split(',') as string[]; - const variables = (this.getNodeParameter('variablesUi', i) as IDataObject).variablesValues as IDataObject[]; + try { + if (resource === 'email') { + //https://dev.mailjet.com/email/guides/send-api-v31/#send-a-basic-email + if (operation === 'send') { + const fromEmail = this.getNodeParameter('fromEmail', i) as string; + const htmlBody = this.getNodeParameter('html', i) as string; + const textBody = this.getNodeParameter('text', i) as string; + const subject = this.getNodeParameter('subject', i) as string; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const toEmail = (this.getNodeParameter('toEmail', i) as string).split(',') as string[]; + const variables = (this.getNodeParameter('variablesUi', i) as IDataObject).variablesValues as IDataObject[]; - const body: IMessage = { - From: { - Email: fromEmail, - }, - Subject: subject, - To: [], - Cc: [], - Bcc: [], - Variables: {}, - }; - - for (const email of toEmail) { - body.To?.push({ - Email: email, - }); - } - if (variables) { - for (const variable of variables) { - body.Variables![variable.name as string] = variable.value; - } - } - if (htmlBody) { - body.HTMLPart = htmlBody; - } - if (textBody) { - body.TextPart = textBody; - } - if (additionalFields.bccEmail) { - const bccEmail = (additionalFields.bccEmail as string).split(',') as string[]; - for (const email of bccEmail) { - body.Bcc!.push({ - Email: email, - }); - } - } - if (additionalFields.ccAddresses) { - const ccEmail = (additionalFields.ccAddresses as string).split(',') as string[]; - for (const email of ccEmail) { - body.Cc!.push({ - Email: email, - }); - } - } - if (additionalFields.trackOpens) { - body.TrackOpens = additionalFields.trackOpens as string; - } - if (additionalFields.replyTo) { - const replyTo = additionalFields.replyTo as string; - body['ReplyTo'] = { - Email: replyTo, + const body: IMessage = { + From: { + Email: fromEmail, + }, + Subject: subject, + To: [], + Cc: [], + Bcc: [], + Variables: {}, }; - } - if (additionalFields.trackClicks) { - body.TrackClicks = additionalFields.trackClicks as string; - } - if (additionalFields.fromName) { - body.From!.Name = additionalFields.fromName as string; - } - if (additionalFields.templateLanguage) { - body.TemplateLanguage = additionalFields.templateLanguage as boolean; - } - if (additionalFields.priority) { - body.Priority = additionalFields.priority as number; - } - responseData = await mailjetApiRequest.call(this, 'POST', '/v3.1/send', { Messages: [body] }); - responseData = responseData.Messages; - } - //https://dev.mailjet.com/email/guides/send-api-v31/#use-a-template - if (operation === 'sendTemplate') { - const fromEmail = this.getNodeParameter('fromEmail', i) as string; - const templateId = parseInt(this.getNodeParameter('templateId', i) as string, 10); - const subject = this.getNodeParameter('subject', i) as string; - const variables = (this.getNodeParameter('variablesUi', i) as IDataObject).variablesValues as IDataObject[]; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const toEmail = (this.getNodeParameter('toEmail', i) as string).split(',') as string[]; - - const body: IMessage = { - From: { - Email: fromEmail, - }, - Subject: subject, - To: [], - Cc: [], - Bcc: [], - Variables: {}, - TemplateID: templateId, - }; - - for (const email of toEmail) { - body.To!.push({ - Email: email, - }); - } - if (variables) { - for (const variable of variables) { - body.Variables![variable.name as string] = variable.value; - } - } - if (additionalFields.bccEmail) { - const bccEmail = (additionalFields.bccEmail as string).split(',') as string[]; - for (const email of bccEmail) { - body.Bcc!.push({ + for (const email of toEmail) { + body.To?.push({ Email: email, }); } - } - if (additionalFields.ccEmail) { - const ccEmail = (additionalFields.ccEmail as string).split(',') as string[]; - for (const email of ccEmail) { - body.Cc!.push({ - Email: email, - }); + if (variables) { + for (const variable of variables) { + body.Variables![variable.name as string] = variable.value; + } } + if (htmlBody) { + body.HTMLPart = htmlBody; + } + if (textBody) { + body.TextPart = textBody; + } + if (additionalFields.bccEmail) { + const bccEmail = (additionalFields.bccEmail as string).split(',') as string[]; + for (const email of bccEmail) { + body.Bcc!.push({ + Email: email, + }); + } + } + if (additionalFields.ccAddresses) { + const ccEmail = (additionalFields.ccAddresses as string).split(',') as string[]; + for (const email of ccEmail) { + body.Cc!.push({ + Email: email, + }); + } + } + if (additionalFields.trackOpens) { + body.TrackOpens = additionalFields.trackOpens as string; + } + if (additionalFields.replyTo) { + const replyTo = additionalFields.replyTo as string; + body['ReplyTo'] = { + Email: replyTo, + }; + } + if (additionalFields.trackClicks) { + body.TrackClicks = additionalFields.trackClicks as string; + } + if (additionalFields.fromName) { + body.From!.Name = additionalFields.fromName as string; + } + if (additionalFields.templateLanguage) { + body.TemplateLanguage = additionalFields.templateLanguage as boolean; + } + if (additionalFields.priority) { + body.Priority = additionalFields.priority as number; + } + responseData = await mailjetApiRequest.call(this, 'POST', '/v3.1/send', { Messages: [body] }); + responseData = responseData.Messages; + } - if (additionalFields.replyTo) { - const replyTo = additionalFields.replyTo as string; - body['ReplyTo'] = { - Email: replyTo, + //https://dev.mailjet.com/email/guides/send-api-v31/#use-a-template + if (operation === 'sendTemplate') { + const fromEmail = this.getNodeParameter('fromEmail', i) as string; + const templateId = parseInt(this.getNodeParameter('templateId', i) as string, 10); + const subject = this.getNodeParameter('subject', i) as string; + const variables = (this.getNodeParameter('variablesUi', i) as IDataObject).variablesValues as IDataObject[]; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const toEmail = (this.getNodeParameter('toEmail', i) as string).split(',') as string[]; + + const body: IMessage = { + From: { + Email: fromEmail, + }, + Subject: subject, + To: [], + Cc: [], + Bcc: [], + Variables: {}, + TemplateID: templateId, }; + + for (const email of toEmail) { + body.To!.push({ + Email: email, + }); + } + if (variables) { + for (const variable of variables) { + body.Variables![variable.name as string] = variable.value; + } + } + if (additionalFields.bccEmail) { + const bccEmail = (additionalFields.bccEmail as string).split(',') as string[]; + for (const email of bccEmail) { + body.Bcc!.push({ + Email: email, + }); + } + } + if (additionalFields.ccEmail) { + const ccEmail = (additionalFields.ccEmail as string).split(',') as string[]; + for (const email of ccEmail) { + body.Cc!.push({ + Email: email, + }); + } + } + if (additionalFields.replyTo) { + const replyTo = additionalFields.replyTo as string; + body['ReplyTo'] = { + Email: replyTo, + }; + } + if (additionalFields.trackOpens) { + body.TrackOpens = additionalFields.trackOpens as string; + } + if (additionalFields.trackClicks) { + body.TrackClicks = additionalFields.trackClicks as string; + } + if (additionalFields.fromName) { + body.From!.Name = additionalFields.fromName as string; + } + if (additionalFields.templateLanguage) { + body.TemplateLanguage = additionalFields.templateLanguage as boolean; + } + if (additionalFields.priority) { + body.Priority = additionalFields.priority as number; + } + responseData = await mailjetApiRequest.call(this, 'POST', '/v3.1/send', { Messages: [body] }); + responseData = responseData.Messages; } - if (additionalFields.trackOpens) { - body.TrackOpens = additionalFields.trackOpens as string; - } - if (additionalFields.trackClicks) { - body.TrackClicks = additionalFields.trackClicks as string; - } - if (additionalFields.fromName) { - body.From!.Name = additionalFields.fromName as string; - } - if (additionalFields.templateLanguage) { - body.TemplateLanguage = additionalFields.templateLanguage as boolean; - } - if (additionalFields.priority) { - body.Priority = additionalFields.priority as number; - } - responseData = await mailjetApiRequest.call(this, 'POST', '/v3.1/send', { Messages: [body] }); - responseData = responseData.Messages; } - } - if (resource === 'sms') { - //https://dev.mailjet.com/sms/reference/send-message#v4_post_sms-send - if (operation === 'send') { - const from = this.getNodeParameter('from', i) as string; - const to = this.getNodeParameter('to', i) as boolean; - const text = this.getNodeParameter('text', i) as string; - const body: IDataObject = { - From: from, - To: to, - Text: text, - }; - responseData = await mailjetApiRequest.call(this, 'POST', '/v4/sms-send', body); + if (resource === 'sms') { + //https://dev.mailjet.com/sms/reference/send-message#v4_post_sms-send + if (operation === 'send') { + const from = this.getNodeParameter('from', i) as string; + const to = this.getNodeParameter('to', i) as boolean; + const text = this.getNodeParameter('text', i) as string; + const body: IDataObject = { + From: from, + To: to, + Text: text, + }; + responseData = await mailjetApiRequest.call(this, 'POST', '/v4/sms-send', body); + } } - } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else { - returnData.push(responseData as IDataObject); + if (Array.isArray(responseData)) { + returnData.push.apply(returnData, responseData as IDataObject[]); + } else { + returnData.push(responseData as IDataObject); + } + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } } return [this.helpers.returnJsonArray(returnData)]; diff --git a/packages/nodes-base/nodes/Mandrill/Mandrill.node.ts b/packages/nodes-base/nodes/Mandrill/Mandrill.node.ts index 74a2a6fe27..f2a73cafe4 100644 --- a/packages/nodes-base/nodes/Mandrill/Mandrill.node.ts +++ b/packages/nodes-base/nodes/Mandrill/Mandrill.node.ts @@ -738,154 +738,162 @@ export class Mandrill implements INodeType { const operation = this.getNodeParameter('operation', 0) as string; for (let i = 0; i < items.length; i++) { - if (resource === 'message') { + try { + if (resource === 'message') { - const options = this.getNodeParameter('options', i) as Options; - const fromEmail = this.getNodeParameter('fromEmail', i) as string; - const toEmail = this.getNodeParameter('toEmail', i) as string; - const jsonActive = this.getNodeParameter('jsonParameters', i) as boolean; - const toEmailArray = getToEmailArray(toEmail); + const options = this.getNodeParameter('options', i) as Options; + const fromEmail = this.getNodeParameter('fromEmail', i) as string; + const toEmail = this.getNodeParameter('toEmail', i) as string; + const jsonActive = this.getNodeParameter('jsonParameters', i) as boolean; + const toEmailArray = getToEmailArray(toEmail); - const message: Message = { - html: (options.html) ? options.html : '', - text: (options.text) ? options.text : '', - subject: (options.subject) ? options.subject : '', - from_email: fromEmail, - to: toEmailArray, - important: (options.important) ? options.important : false, - track_opens: (options.trackOpens) ? options.trackOpens : false, - track_clicks: (options.trackClicks) ? options.trackClicks : false, - auto_text: (options.autoText) ? options.autoText : false, - auto_html: (options.autoHtml) ? options.autoHtml : false, - inline_css: (options.inlineCss) ? options.inlineCss : false, - url_strip_qs: (options.urlStripQs) ? options.urlStripQs : false, - preserve_recipients: (options.preserveRecipients) ? options.preserveRecipients : false, - view_content_link: (options.viewContentLink) ? options.viewContentLink : false, - async: (options.async) ? options.async : false, - google_analytics_campaign: (options.googleAnalyticsCampaign) ? options.googleAnalyticsCampaign : '', - ip_pool: (options.ipPool) ? options.ipPool : '', - bcc_address: (options.bccAddress) ? options.bccAddress : '', - tracking_domain: (options.trackingDomain) ? options.trackingDomain : '', - signing_domain: (options.signingDomain) ? options.signingDomain : '', - return_path_domain: (options.returnPathDomain) ? options.returnPathDomain : '', - }; + const message: Message = { + html: (options.html) ? options.html : '', + text: (options.text) ? options.text : '', + subject: (options.subject) ? options.subject : '', + from_email: fromEmail, + to: toEmailArray, + important: (options.important) ? options.important : false, + track_opens: (options.trackOpens) ? options.trackOpens : false, + track_clicks: (options.trackClicks) ? options.trackClicks : false, + auto_text: (options.autoText) ? options.autoText : false, + auto_html: (options.autoHtml) ? options.autoHtml : false, + inline_css: (options.inlineCss) ? options.inlineCss : false, + url_strip_qs: (options.urlStripQs) ? options.urlStripQs : false, + preserve_recipients: (options.preserveRecipients) ? options.preserveRecipients : false, + view_content_link: (options.viewContentLink) ? options.viewContentLink : false, + async: (options.async) ? options.async : false, + google_analytics_campaign: (options.googleAnalyticsCampaign) ? options.googleAnalyticsCampaign : '', + ip_pool: (options.ipPool) ? options.ipPool : '', + bcc_address: (options.bccAddress) ? options.bccAddress : '', + tracking_domain: (options.trackingDomain) ? options.trackingDomain : '', + signing_domain: (options.signingDomain) ? options.signingDomain : '', + return_path_domain: (options.returnPathDomain) ? options.returnPathDomain : '', + }; - if (options.googleAnalyticsDomains) { - message.google_analytics_domains = getGoogleAnalyticsDomainsArray(options.googleAnalyticsDomains); - } + if (options.googleAnalyticsDomains) { + message.google_analytics_domains = getGoogleAnalyticsDomainsArray(options.googleAnalyticsDomains); + } - if (options.tags) { - message.tags = getTags(options.tags); - } + if (options.tags) { + message.tags = getTags(options.tags); + } - if (options.fromName) { - message.from_name = options.fromName; - } + if (options.fromName) { + message.from_name = options.fromName; + } - if (options.subaccount) { - message.subaccount = options.subaccount; - } + if (options.subaccount) { + message.subaccount = options.subaccount; + } - const body: Body = { - template_content: [], - message, - }; + const body: Body = { + template_content: [], + message, + }; - if (options.sendAt) { - body.send_at = moment(options.sendAt).utc().format('YYYY-MM-DD HH:mm:ss'); - } + if (options.sendAt) { + body.send_at = moment(options.sendAt).utc().format('YYYY-MM-DD HH:mm:ss'); + } - if (jsonActive) { + if (jsonActive) { - body.message.headers = validateJSON(this.getNodeParameter('headersJson', i) as string); - body.message.metadata = validateJSON(this.getNodeParameter('metadataJson', i) as string); - body.message.global_merge_vars = validateJSON(this.getNodeParameter('mergeVarsJson', i) as string); - body.message.attachments = validateJSON(this.getNodeParameter('attachmentsJson', i) as string); + body.message.headers = validateJSON(this.getNodeParameter('headersJson', i) as string); + body.message.metadata = validateJSON(this.getNodeParameter('metadataJson', i) as string); + body.message.global_merge_vars = validateJSON(this.getNodeParameter('mergeVarsJson', i) as string); + body.message.attachments = validateJSON(this.getNodeParameter('attachmentsJson', i) as string); - } else { + } else { - const headersUi = this.getNodeParameter('headersUi', i) as IDataObject; - if (!_.isEmpty(headersUi)) { - // @ts-ignore - body.message.headers = _.map(headersUi.headersValues, (o) => { - const aux: IDataObject = {}; + const headersUi = this.getNodeParameter('headersUi', i) as IDataObject; + if (!_.isEmpty(headersUi)) { // @ts-ignore - aux[o.name] = o.value; - return aux; - }); - } - - const metadataUi = this.getNodeParameter('metadataUi', i) as IDataObject; - if (!_.isEmpty(metadataUi)) { - // @ts-ignore - body.message.metadata = _.map(metadataUi.metadataValues, (o: IDataObject) => { - const aux: IDataObject = {}; - aux[o.name as string] = o.value; - return aux; - }); - } - - const mergeVarsUi = this.getNodeParameter('mergeVarsUi', i) as IDataObject; - if (!_.isEmpty(mergeVarsUi)) { - // @ts-ignore - body.message.global_merge_vars = _.map(mergeVarsUi.mergeVarsValues, (o: IDataObject) => { - const aux: IDataObject = {}; - aux.name = o.name; - aux.content = o.content; - return aux; - }); - } - - const attachmentsUi = this.getNodeParameter('attachmentsUi', i) as IDataObject; - let attachmentsBinary: Attachments[] = [], attachmentsValues: Attachments[] = []; - if (!_.isEmpty(attachmentsUi)) { - - if (attachmentsUi.hasOwnProperty('attachmentsValues') - && !_.isEmpty(attachmentsUi.attachmentsValues)) { - // @ts-ignore - attachmentsValues = _.map(attachmentsUi.attachmentsValues, (o: IDataObject) => { + body.message.headers = _.map(headersUi.headersValues, (o) => { const aux: IDataObject = {}; // @ts-ignore - aux.name = o.name; - aux.content = o.content; - aux.type = o.type; + aux[o.name] = o.value; return aux; }); } - if (attachmentsUi.hasOwnProperty('attachmentsBinary') - && !_.isEmpty(attachmentsUi.attachmentsBinary) - && items[i].binary) { + const metadataUi = this.getNodeParameter('metadataUi', i) as IDataObject; + if (!_.isEmpty(metadataUi)) { // @ts-ignore - attachmentsBinary = _.map(attachmentsUi.attachmentsBinary, (o: IDataObject) => { - if (items[i].binary!.hasOwnProperty(o.property as string)) { - const aux: IDataObject = {}; - aux.name = items[i].binary![o.property as string].fileName || 'unknown'; - aux.content = items[i].binary![o.property as string].data; - aux.type = items[i].binary![o.property as string].mimeType; - return aux; - } + body.message.metadata = _.map(metadataUi.metadataValues, (o: IDataObject) => { + const aux: IDataObject = {}; + aux[o.name as string] = o.value; + return aux; }); } + + const mergeVarsUi = this.getNodeParameter('mergeVarsUi', i) as IDataObject; + if (!_.isEmpty(mergeVarsUi)) { + // @ts-ignore + body.message.global_merge_vars = _.map(mergeVarsUi.mergeVarsValues, (o: IDataObject) => { + const aux: IDataObject = {}; + aux.name = o.name; + aux.content = o.content; + return aux; + }); + } + + const attachmentsUi = this.getNodeParameter('attachmentsUi', i) as IDataObject; + let attachmentsBinary: Attachments[] = [], attachmentsValues: Attachments[] = []; + if (!_.isEmpty(attachmentsUi)) { + + if (attachmentsUi.hasOwnProperty('attachmentsValues') + && !_.isEmpty(attachmentsUi.attachmentsValues)) { + // @ts-ignore + attachmentsValues = _.map(attachmentsUi.attachmentsValues, (o: IDataObject) => { + const aux: IDataObject = {}; + // @ts-ignore + aux.name = o.name; + aux.content = o.content; + aux.type = o.type; + return aux; + }); + } + + if (attachmentsUi.hasOwnProperty('attachmentsBinary') + && !_.isEmpty(attachmentsUi.attachmentsBinary) + && items[i].binary) { + // @ts-ignore + attachmentsBinary = _.map(attachmentsUi.attachmentsBinary, (o: IDataObject) => { + if (items[i].binary!.hasOwnProperty(o.property as string)) { + const aux: IDataObject = {}; + aux.name = items[i].binary![o.property as string].fileName || 'unknown'; + aux.content = items[i].binary![o.property as string].data; + aux.type = items[i].binary![o.property as string].mimeType; + return aux; + } + }); + } + } + + body.message.attachments = attachmentsBinary.concat(attachmentsValues); } - body.message.attachments = attachmentsBinary.concat(attachmentsValues); - } + if (operation === 'sendTemplate') { + const template = this.getNodeParameter('template', i) as string; + body.template_name = template; + emailSentResponse = mandrillApiRequest.call(this, '/messages', 'POST', '/send-template', body); + } else if (operation === 'sendHtml') { + emailSentResponse = mandrillApiRequest.call(this, '/messages', 'POST', '/send', body); + } - if (operation === 'sendTemplate') { - const template = this.getNodeParameter('template', i) as string; - body.template_name = template; - emailSentResponse = mandrillApiRequest.call(this, '/messages', 'POST', '/send-template', body); - } else if (operation === 'sendHtml') { - emailSentResponse = mandrillApiRequest.call(this, '/messages', 'POST', '/send', body); + responseData = await emailSentResponse; } - - responseData = await emailSentResponse; - } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else { - returnData.push(responseData as IDataObject); + if (Array.isArray(responseData)) { + returnData.push.apply(returnData, responseData as IDataObject[]); + } else { + returnData.push(responseData as IDataObject); + } + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } } return [this.helpers.returnJsonArray(returnData)]; diff --git a/packages/nodes-base/nodes/Matrix/Matrix.node.ts b/packages/nodes-base/nodes/Matrix/Matrix.node.ts index e7e503d2da..e086a283eb 100644 --- a/packages/nodes-base/nodes/Matrix/Matrix.node.ts +++ b/packages/nodes-base/nodes/Matrix/Matrix.node.ts @@ -159,11 +159,19 @@ export class Matrix implements INodeType { const operation = this.getNodeParameter('operation', 0) as string; for (let i = 0; i < items.length; i++) { - const responseData = await handleMatrixCall.call(this, items[i], i, resource, operation); - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else { - returnData.push(responseData as IDataObject); + try { + const responseData = await handleMatrixCall.call(this, items[i], i, resource, operation); + if (Array.isArray(responseData)) { + returnData.push.apply(returnData, responseData as IDataObject[]); + } else { + returnData.push(responseData as IDataObject); + } + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } } diff --git a/packages/nodes-base/nodes/Mattermost/Mattermost.node.ts b/packages/nodes-base/nodes/Mattermost/Mattermost.node.ts index 3d06b20110..50531502ae 100644 --- a/packages/nodes-base/nodes/Mattermost/Mattermost.node.ts +++ b/packages/nodes-base/nodes/Mattermost/Mattermost.node.ts @@ -1961,433 +1961,441 @@ export class Mattermost implements INodeType { let qs: IDataObject; for (let i = 0; i < items.length; i++) { - let endpoint = ''; - body = {}; - qs = {}; + try { + let endpoint = ''; + body = {}; + qs = {}; - if (resource === 'channel') { - if (operation === 'create') { - // ---------------------------------- - // channel:create - // ---------------------------------- + if (resource === 'channel') { + if (operation === 'create') { + // ---------------------------------- + // channel:create + // ---------------------------------- - requestMethod = 'POST'; - endpoint = 'channels'; + requestMethod = 'POST'; + endpoint = 'channels'; - body.team_id = this.getNodeParameter('teamId', i) as string; - body.display_name = this.getNodeParameter('displayName', i) as string; - body.name = this.getNodeParameter('channel', i) as string; + body.team_id = this.getNodeParameter('teamId', i) as string; + body.display_name = this.getNodeParameter('displayName', i) as string; + body.name = this.getNodeParameter('channel', i) as string; - const type = this.getNodeParameter('type', i) as string; - body.type = type === 'public' ? 'O' : 'P'; + const type = this.getNodeParameter('type', i) as string; + body.type = type === 'public' ? 'O' : 'P'; - } else if (operation === 'delete') { - // ---------------------------------- - // channel:delete - // ---------------------------------- + } else if (operation === 'delete') { + // ---------------------------------- + // channel:delete + // ---------------------------------- - requestMethod = 'DELETE'; - const channelId = this.getNodeParameter('channelId', i) as string; - endpoint = `channels/${channelId}`; + requestMethod = 'DELETE'; + const channelId = this.getNodeParameter('channelId', i) as string; + endpoint = `channels/${channelId}`; - } else if (operation === 'members') { - // ---------------------------------- - // channel:members - // ---------------------------------- + } else if (operation === 'members') { + // ---------------------------------- + // channel:members + // ---------------------------------- - requestMethod = 'GET'; - const channelId = this.getNodeParameter('channelId', i) as string; - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - endpoint = `channels/${channelId}/members`; - if (returnAll === false) { - qs.per_page = this.getNodeParameter('limit', i) as number; + requestMethod = 'GET'; + const channelId = this.getNodeParameter('channelId', i) as string; + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + endpoint = `channels/${channelId}/members`; + if (returnAll === false) { + qs.per_page = this.getNodeParameter('limit', i) as number; + } + + } else if (operation === 'restore') { + // ---------------------------------- + // channel:restore + // ---------------------------------- + + requestMethod = 'POST'; + const channelId = this.getNodeParameter('channelId', i) as string; + endpoint = `channels/${channelId}/restore`; + + } else if (operation === 'addUser') { + // ---------------------------------- + // channel:addUser + // ---------------------------------- + + requestMethod = 'POST'; + + const channelId = this.getNodeParameter('channelId', i) as string; + body.user_id = this.getNodeParameter('userId', i) as string; + + endpoint = `channels/${channelId}/members`; + + } else if (operation === 'statistics') { + // ---------------------------------- + // channel:statistics + // ---------------------------------- + + requestMethod = 'GET'; + const channelId = this.getNodeParameter('channelId', i) as string; + endpoint = `channels/${channelId}/stats`; } + } else if (resource === 'message') { + if (operation === 'delete') { + // ---------------------------------- + // message:delete + // ---------------------------------- - } else if (operation === 'restore') { - // ---------------------------------- - // channel:restore - // ---------------------------------- + const postId = this.getNodeParameter('postId', i) as string; + requestMethod = 'DELETE'; + endpoint = `posts/${postId}`; + } else if (operation === 'post') { + // ---------------------------------- + // message:post + // ---------------------------------- - requestMethod = 'POST'; - const channelId = this.getNodeParameter('channelId', i) as string; - endpoint = `channels/${channelId}/restore`; + requestMethod = 'POST'; + endpoint = 'posts'; - } else if (operation === 'addUser') { - // ---------------------------------- - // channel:addUser - // ---------------------------------- + body.channel_id = this.getNodeParameter('channelId', i) as string; + body.message = this.getNodeParameter('message', i) as string; - requestMethod = 'POST'; + const attachments = this.getNodeParameter('attachments', i, []) as unknown as IAttachment[]; - const channelId = this.getNodeParameter('channelId', i) as string; - body.user_id = this.getNodeParameter('userId', i) as string; - - endpoint = `channels/${channelId}/members`; - - } else if (operation === 'statistics') { - // ---------------------------------- - // channel:statistics - // ---------------------------------- - - requestMethod = 'GET'; - const channelId = this.getNodeParameter('channelId', i) as string; - endpoint = `channels/${channelId}/stats`; - } - } else if (resource === 'message') { - if (operation === 'delete') { - // ---------------------------------- - // message:delete - // ---------------------------------- - - const postId = this.getNodeParameter('postId', i) as string; - requestMethod = 'DELETE'; - endpoint = `posts/${postId}`; - } else if (operation === 'post') { - // ---------------------------------- - // message:post - // ---------------------------------- - - requestMethod = 'POST'; - endpoint = 'posts'; - - body.channel_id = this.getNodeParameter('channelId', i) as string; - body.message = this.getNodeParameter('message', i) as string; - - const attachments = this.getNodeParameter('attachments', i, []) as unknown as IAttachment[]; - - // The node does save the fields data differently than the API - // expects so fix the data befre we send the request - for (const attachment of attachments) { - if (attachment.fields !== undefined) { - if (attachment.fields.item !== undefined) { - // Move the field-content up - // @ts-ignore - attachment.fields = attachment.fields.item; - } else { - // If it does not have any items set remove it - // @ts-ignore - delete attachment.fields; + // The node does save the fields data differently than the API + // expects so fix the data befre we send the request + for (const attachment of attachments) { + if (attachment.fields !== undefined) { + if (attachment.fields.item !== undefined) { + // Move the field-content up + // @ts-ignore + attachment.fields = attachment.fields.item; + } else { + // If it does not have any items set remove it + // @ts-ignore + delete attachment.fields; + } } } - } - for (const attachment of attachments) { - if (attachment.actions !== undefined) { - if (attachment.actions.item !== undefined) { - // Move the field-content up - // @ts-ignore - attachment.actions = attachment.actions.item; - } else { - // If it does not have any items set remove it - // @ts-ignore - delete attachment.actions; + for (const attachment of attachments) { + if (attachment.actions !== undefined) { + if (attachment.actions.item !== undefined) { + // Move the field-content up + // @ts-ignore + attachment.actions = attachment.actions.item; + } else { + // If it does not have any items set remove it + // @ts-ignore + delete attachment.actions; + } } } - } - for (const attachment of attachments) { - if (Array.isArray(attachment.actions)) { - for (const attaction of attachment.actions) { + for (const attachment of attachments) { + if (Array.isArray(attachment.actions)) { + for (const attaction of attachment.actions) { - if (attaction.type === 'button') { - delete attaction.type; - } - if (attaction.data_source === 'custom') { - delete attaction.data_source; - } - if (attaction.options) { - attaction.options = attaction.options.option; - } + if (attaction.type === 'button') { + delete attaction.type; + } + if (attaction.data_source === 'custom') { + delete attaction.data_source; + } + if (attaction.options) { + attaction.options = attaction.options.option; + } - if (attaction.integration.item !== undefined) { - attaction.integration = attaction.integration.item; - if (Array.isArray(attaction.integration.context.property)) { - const tmpcontex = {}; - for (const attactionintegprop of attaction.integration.context.property) { - Object.assign(tmpcontex, { [attactionintegprop.name]: attactionintegprop.value }); + if (attaction.integration.item !== undefined) { + attaction.integration = attaction.integration.item; + if (Array.isArray(attaction.integration.context.property)) { + const tmpcontex = {}; + for (const attactionintegprop of attaction.integration.context.property) { + Object.assign(tmpcontex, { [attactionintegprop.name]: attactionintegprop.value }); + } + delete attaction.integration.context; + attaction.integration.context = tmpcontex; } - delete attaction.integration.context; - attaction.integration.context = tmpcontex; } } } } + + body.props = { + attachments, + }; + + // Add all the other options to the request + const otherOptions = this.getNodeParameter('otherOptions', i) as IDataObject; + Object.assign(body, otherOptions); + + } else if (operation === 'postEphemeral') { + + // ---------------------------------- + // message:post (ephemeral) + // ---------------------------------- + + // https://api.mattermost.com/#tag/posts/paths/~1posts~1ephemeral/post + + body = { + user_id: this.getNodeParameter('userId', i), + post: { + channel_id: this.getNodeParameter('channelId', i), + message: this.getNodeParameter('message', i), + }, + } as IDataObject; + + requestMethod = 'POST'; + endpoint = 'posts/ephemeral'; + } - body.props = { - attachments, - }; - - // Add all the other options to the request - const otherOptions = this.getNodeParameter('otherOptions', i) as IDataObject; - Object.assign(body, otherOptions); - - } else if (operation === 'postEphemeral') { + } else if (resource === 'reaction') { // ---------------------------------- - // message:post (ephemeral) + // reaction:create // ---------------------------------- - // https://api.mattermost.com/#tag/posts/paths/~1posts~1ephemeral/post + // https://api.mattermost.com/#tag/reactions/paths/~1reactions/post - body = { - user_id: this.getNodeParameter('userId', i), - post: { - channel_id: this.getNodeParameter('channelId', i), - message: this.getNodeParameter('message', i), - }, - } as IDataObject; + if (operation === 'create') { - requestMethod = 'POST'; - endpoint = 'posts/ephemeral'; + body = { + user_id: this.getNodeParameter('userId', i), + post_id: this.getNodeParameter('postId', i), + emoji_name: (this.getNodeParameter('emojiName', i) as string).replace(/:/g, ''), + create_at: Date.now(), + } as { user_id: string; post_id: string; emoji_name: string; create_at: number }; - } + requestMethod = 'POST'; + endpoint = 'reactions'; - } else if (resource === 'reaction') { + } else if (operation === 'delete') { - // ---------------------------------- - // reaction:create - // ---------------------------------- + // ---------------------------------- + // reaction:delete + // ---------------------------------- - // https://api.mattermost.com/#tag/reactions/paths/~1reactions/post + // https://api.mattermost.com/#tag/reactions/paths/~1users~1{user_id}~1posts~1{post_id}~1reactions~1{emoji_name}/delete - if (operation === 'create') { + const userId = this.getNodeParameter('userId', i) as string; + const postId = this.getNodeParameter('postId', i) as string; + const emojiName = (this.getNodeParameter('emojiName', i) as string).replace(/:/g, ''); - body = { - user_id: this.getNodeParameter('userId', i), - post_id: this.getNodeParameter('postId', i), - emoji_name: (this.getNodeParameter('emojiName', i) as string).replace(/:/g, ''), - create_at: Date.now(), - } as { user_id: string; post_id: string; emoji_name: string; create_at: number }; + requestMethod = 'DELETE'; + endpoint = `users/${userId}/posts/${postId}/reactions/${emojiName}`; - requestMethod = 'POST'; - endpoint = 'reactions'; + } else if (operation === 'getAll') { - } else if (operation === 'delete') { + // ---------------------------------- + // reaction:getAll + // ---------------------------------- - // ---------------------------------- - // reaction:delete - // ---------------------------------- + // https://api.mattermost.com/#tag/reactions/paths/~1posts~1ids~1reactions/post - // https://api.mattermost.com/#tag/reactions/paths/~1users~1{user_id}~1posts~1{post_id}~1reactions~1{emoji_name}/delete + const postId = this.getNodeParameter('postId', i) as string; - const userId = this.getNodeParameter('userId', i) as string; - const postId = this.getNodeParameter('postId', i) as string; - const emojiName = (this.getNodeParameter('emojiName', i) as string).replace(/:/g, ''); + requestMethod = 'GET'; + endpoint = `posts/${postId}/reactions`; - requestMethod = 'DELETE'; - endpoint = `users/${userId}/posts/${postId}/reactions/${emojiName}`; - - } else if (operation === 'getAll') { - - // ---------------------------------- - // reaction:getAll - // ---------------------------------- - - // https://api.mattermost.com/#tag/reactions/paths/~1posts~1ids~1reactions/post - - const postId = this.getNodeParameter('postId', i) as string; - - requestMethod = 'GET'; - endpoint = `posts/${postId}/reactions`; - - qs.limit = this.getNodeParameter('limit', 0, 0) as number; - } - - } else if (resource === 'user') { - - if (operation === 'create') { - // ---------------------------------- - // user:create - // ---------------------------------- - - const username = this.getNodeParameter('username', i) as string; - - const authService = this.getNodeParameter('authService', i) as string; - - body.auth_service = authService; - - if (authService === 'email') { - body.email = this.getNodeParameter('email', i) as string; - body.password = this.getNodeParameter('password', i) as string; - } else { - body.auth_data = this.getNodeParameter('authData', i) as string; + qs.limit = this.getNodeParameter('limit', 0, 0) as number; } - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + } else if (resource === 'user') { - body.username = username; + if (operation === 'create') { + // ---------------------------------- + // user:create + // ---------------------------------- - Object.assign(body, additionalFields); + const username = this.getNodeParameter('username', i) as string; - if (body.notificationUi) { - body.notify_props = (body.notificationUi as IDataObject).notificationValues; - } + const authService = this.getNodeParameter('authService', i) as string; - requestMethod = 'POST'; - - endpoint = 'users'; - } - - // TODO: Remove the "deactive" again in the future. In here temporary - // to not break workflows for people which set the option before - // typo got fixed. JO 2020-01-17 - if (operation === 'deactive' || operation === 'desactive') { - // ---------------------------------- - // user:deactive - // ---------------------------------- - const userId = this.getNodeParameter('userId', i) as string; - requestMethod = 'DELETE'; - endpoint = `users/${userId}`; - } - - if (operation === 'getAll') { - // ---------------------------------- - // user:getAll - // ---------------------------------- - - requestMethod = 'GET'; - - returnAll = this.getNodeParameter('returnAll', i) as boolean; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - - if (additionalFields.inTeam) { - qs.in_team = additionalFields.inTeam; - } - - if (additionalFields.notInTeam) { - qs.not_in_team = additionalFields.notInTeam; - } - - if (additionalFields.inChannel) { - qs.in_channel = additionalFields.inChannel; - } - - if (additionalFields.notInChannel) { - qs.not_in_channel = additionalFields.notInChannel; - } - - if (additionalFields.sort) { - qs.sort = snakeCase(additionalFields.sort as string); - } - - const validRules = { - inTeam: ['last_activity_at', 'created_at', 'username'], - inChannel: ['status', 'username'], - }; - - if (additionalFields.sort) { - if (additionalFields.inTeam !== undefined || additionalFields.inChannel !== undefined) { - - if (additionalFields.inTeam !== undefined - && !validRules.inTeam.includes(snakeCase(additionalFields.sort as string))) { - throw new NodeOperationError(this.getNode(), `When In Team is set the only valid values for sorting are ${validRules.inTeam.join(',')}`); - } - if (additionalFields.inChannel !== undefined - && !validRules.inChannel.includes(snakeCase(additionalFields.sort as string))) { - throw new NodeOperationError(this.getNode(), `When In Channel is set the only valid values for sorting are ${validRules.inChannel.join(',')}`); - } - if (additionalFields.inChannel !== undefined - && additionalFields.inChannel === '' - && additionalFields.sort !== 'username') { - throw new NodeOperationError(this.getNode(), 'When sort is different than username In Channel must be set'); - } - - if (additionalFields.inTeam !== undefined - && additionalFields.inTeam === '' - && additionalFields.sort !== 'username') { - throw new NodeOperationError(this.getNode(), 'When sort is different than username In Team must be set'); - } + body.auth_service = authService; + if (authService === 'email') { + body.email = this.getNodeParameter('email', i) as string; + body.password = this.getNodeParameter('password', i) as string; } else { - throw new NodeOperationError(this.getNode(), `When sort is defined either 'in team' or 'in channel' must be defined`); + body.auth_data = this.getNodeParameter('authData', i) as string; } - } - if (additionalFields.sort === 'username') { - qs.sort = ''; - } + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - if (returnAll === false) { - qs.per_page = this.getNodeParameter('limit', i) as number; - } + body.username = username; - endpoint = `/users`; - } + Object.assign(body, additionalFields); - if (operation === 'getByEmail') { - // ---------------------------------- - // user:getByEmail - // ---------------------------------- - const email = this.getNodeParameter('email', i) as string; - requestMethod = 'GET'; - endpoint = `users/email/${email}`; - } - - if (operation === 'getById') { - // ---------------------------------- - // user:getById - // ---------------------------------- - userIds = (this.getNodeParameter('userIds', i) as string).split(',') as string[]; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - - if (additionalFields.since) { - qs.since = new Date(additionalFields.since as string).getTime(); - } - - requestMethod = 'POST'; - - endpoint = 'users/ids'; - - //@ts-ignore - body = userIds; - - } - - if (operation === 'invite') { - // ---------------------------------- - // user:invite - // ---------------------------------- - const teamId = this.getNodeParameter('teamId', i) as string; - - const emails = (this.getNodeParameter('emails', i) as string).split(','); - - //@ts-ignore - body = emails; - - requestMethod = 'POST'; - - endpoint = `teams/${teamId}/invite/email`; - } - } - else { - throw new NodeOperationError(this.getNode(), `The resource "${resource}" is not known!`); - } - - let responseData; - if (returnAll) { - responseData = await apiRequestAllItems.call(this, requestMethod, endpoint, body, qs); - } else { - responseData = await apiRequest.call(this, requestMethod, endpoint, body, qs); - if (qs.limit) { - responseData = responseData.slice(0, qs.limit); - } - if (resource === 'channel' && operation === 'members') { - const resolveData = this.getNodeParameter('resolveData', i) as boolean; - if (resolveData) { - const userIds: string[] = []; - for (const data of responseData) { - userIds.push(data.user_id); + if (body.notificationUi) { + body.notify_props = (body.notificationUi as IDataObject).notificationValues; } - if (userIds.length > 0) { - responseData = await apiRequest.call(this, 'POST', 'users/ids', userIds, qs); + + requestMethod = 'POST'; + + endpoint = 'users'; + } + + // TODO: Remove the "deactive" again in the future. In here temporary + // to not break workflows for people which set the option before + // typo got fixed. JO 2020-01-17 + if (operation === 'deactive' || operation === 'desactive') { + // ---------------------------------- + // user:deactive + // ---------------------------------- + const userId = this.getNodeParameter('userId', i) as string; + requestMethod = 'DELETE'; + endpoint = `users/${userId}`; + } + + if (operation === 'getAll') { + // ---------------------------------- + // user:getAll + // ---------------------------------- + + requestMethod = 'GET'; + + returnAll = this.getNodeParameter('returnAll', i) as boolean; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + + if (additionalFields.inTeam) { + qs.in_team = additionalFields.inTeam; + } + + if (additionalFields.notInTeam) { + qs.not_in_team = additionalFields.notInTeam; + } + + if (additionalFields.inChannel) { + qs.in_channel = additionalFields.inChannel; + } + + if (additionalFields.notInChannel) { + qs.not_in_channel = additionalFields.notInChannel; + } + + if (additionalFields.sort) { + qs.sort = snakeCase(additionalFields.sort as string); + } + + const validRules = { + inTeam: ['last_activity_at', 'created_at', 'username'], + inChannel: ['status', 'username'], + }; + + if (additionalFields.sort) { + if (additionalFields.inTeam !== undefined || additionalFields.inChannel !== undefined) { + + if (additionalFields.inTeam !== undefined + && !validRules.inTeam.includes(snakeCase(additionalFields.sort as string))) { + throw new NodeOperationError(this.getNode(), `When In Team is set the only valid values for sorting are ${validRules.inTeam.join(',')}`); + } + if (additionalFields.inChannel !== undefined + && !validRules.inChannel.includes(snakeCase(additionalFields.sort as string))) { + throw new NodeOperationError(this.getNode(), `When In Channel is set the only valid values for sorting are ${validRules.inChannel.join(',')}`); + } + if (additionalFields.inChannel !== undefined + && additionalFields.inChannel === '' + && additionalFields.sort !== 'username') { + throw new NodeOperationError(this.getNode(), 'When sort is different than username In Channel must be set'); + } + + if (additionalFields.inTeam !== undefined + && additionalFields.inTeam === '' + && additionalFields.sort !== 'username') { + throw new NodeOperationError(this.getNode(), 'When sort is different than username In Team must be set'); + } + + } else { + throw new NodeOperationError(this.getNode(), `When sort is defined either 'in team' or 'in channel' must be defined`); + } + } + + if (additionalFields.sort === 'username') { + qs.sort = ''; + } + + if (returnAll === false) { + qs.per_page = this.getNodeParameter('limit', i) as number; + } + + endpoint = `/users`; + } + + if (operation === 'getByEmail') { + // ---------------------------------- + // user:getByEmail + // ---------------------------------- + const email = this.getNodeParameter('email', i) as string; + requestMethod = 'GET'; + endpoint = `users/email/${email}`; + } + + if (operation === 'getById') { + // ---------------------------------- + // user:getById + // ---------------------------------- + userIds = (this.getNodeParameter('userIds', i) as string).split(',') as string[]; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + + if (additionalFields.since) { + qs.since = new Date(additionalFields.since as string).getTime(); + } + + requestMethod = 'POST'; + + endpoint = 'users/ids'; + + //@ts-ignore + body = userIds; + + } + + if (operation === 'invite') { + // ---------------------------------- + // user:invite + // ---------------------------------- + const teamId = this.getNodeParameter('teamId', i) as string; + + const emails = (this.getNodeParameter('emails', i) as string).split(','); + + //@ts-ignore + body = emails; + + requestMethod = 'POST'; + + endpoint = `teams/${teamId}/invite/email`; + } + } + else { + throw new NodeOperationError(this.getNode(), `The resource "${resource}" is not known!`); + } + + let responseData; + if (returnAll) { + responseData = await apiRequestAllItems.call(this, requestMethod, endpoint, body, qs); + } else { + responseData = await apiRequest.call(this, requestMethod, endpoint, body, qs); + if (qs.limit) { + responseData = responseData.slice(0, qs.limit); + } + if (resource === 'channel' && operation === 'members') { + const resolveData = this.getNodeParameter('resolveData', i) as boolean; + if (resolveData) { + const userIds: string[] = []; + for (const data of responseData) { + userIds.push(data.user_id); + } + if (userIds.length > 0) { + responseData = await apiRequest.call(this, 'POST', 'users/ids', userIds, qs); + } } } } - } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData); - } else { - returnData.push(responseData); + if (Array.isArray(responseData)) { + returnData.push.apply(returnData, responseData); + } else { + returnData.push(responseData); + } + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } } diff --git a/packages/nodes-base/nodes/Mautic/Mautic.node.ts b/packages/nodes-base/nodes/Mautic/Mautic.node.ts index 6296666049..fb79add534 100644 --- a/packages/nodes-base/nodes/Mautic/Mautic.node.ts +++ b/packages/nodes-base/nodes/Mautic/Mautic.node.ts @@ -234,386 +234,393 @@ export class Mautic implements INodeType { for (let i = 0; i < length; i++) { qs = {}; - - if (resource === 'company') { - //https://developer.mautic.org/#create-company - if (operation === 'create') { - const name = this.getNodeParameter('name', i) as string; - const simple = this.getNodeParameter('simple', i) as boolean; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const body: IDataObject = { - companyname: name, - }; - Object.assign(body, additionalFields); - responseData = await mauticApiRequest.call(this, 'POST', '/companies/new', body); - responseData = responseData.company; - if (simple === true) { - responseData = responseData.fields.all; - } - } - //https://developer.mautic.org/#edit-company - if (operation === 'update') { - const companyId = this.getNodeParameter('companyId', i) as string; - const simple = this.getNodeParameter('simple', i) as boolean; - const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; - const body: IDataObject = {}; - Object.assign(body, updateFields); - if (body.name) { - body.companyname = body.name; - delete body.name; - } - responseData = await mauticApiRequest.call(this, 'PATCH', `/companies/${companyId}/edit`, body); - responseData = responseData.company; - if (simple === true) { - responseData = responseData.fields.all; - } - } - //https://developer.mautic.org/#get-company - if (operation === 'get') { - const companyId = this.getNodeParameter('companyId', i) as string; - const simple = this.getNodeParameter('simple', i) as boolean; - responseData = await mauticApiRequest.call(this, 'GET', `/companies/${companyId}`); - responseData = responseData.company; - if (simple === true) { - responseData = responseData.fields.all; - } - } - //https://developer.mautic.org/#list-contact-companies - if (operation === 'getAll') { - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - const simple = this.getNodeParameter('simple', i) as boolean; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - qs = Object.assign(qs, additionalFields); - if (returnAll === true) { - responseData = await mauticApiRequestAllItems.call(this, 'companies', 'GET', '/companies', {}, qs); - } else { - qs.limit = this.getNodeParameter('limit', i) as number; - qs.start = 0; - responseData = await mauticApiRequest.call(this, 'GET', '/companies', {}, qs); - if (responseData.errors) { - throw new NodeApiError(this.getNode(), responseData); + try { + if (resource === 'company') { + //https://developer.mautic.org/#create-company + if (operation === 'create') { + const name = this.getNodeParameter('name', i) as string; + const simple = this.getNodeParameter('simple', i) as boolean; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const body: IDataObject = { + companyname: name, + }; + Object.assign(body, additionalFields); + responseData = await mauticApiRequest.call(this, 'POST', '/companies/new', body); + responseData = responseData.company; + if (simple === true) { + responseData = responseData.fields.all; } - responseData = responseData.companies; - responseData = Object.values(responseData); } - if (simple === true) { - //@ts-ignore - responseData = responseData.map(item => item.fields.all); + //https://developer.mautic.org/#edit-company + if (operation === 'update') { + const companyId = this.getNodeParameter('companyId', i) as string; + const simple = this.getNodeParameter('simple', i) as boolean; + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + const body: IDataObject = {}; + Object.assign(body, updateFields); + if (body.name) { + body.companyname = body.name; + delete body.name; + } + responseData = await mauticApiRequest.call(this, 'PATCH', `/companies/${companyId}/edit`, body); + responseData = responseData.company; + if (simple === true) { + responseData = responseData.fields.all; + } } - } - //https://developer.mautic.org/#delete-company - if (operation === 'delete') { - const simple = this.getNodeParameter('simple', i) as boolean; - const companyId = this.getNodeParameter('companyId', i) as string; - responseData = await mauticApiRequest.call(this, 'DELETE', `/companies/${companyId}/delete`); - responseData = responseData.company; - if (simple === true) { - responseData = responseData.fields.all; + //https://developer.mautic.org/#get-company + if (operation === 'get') { + const companyId = this.getNodeParameter('companyId', i) as string; + const simple = this.getNodeParameter('simple', i) as boolean; + responseData = await mauticApiRequest.call(this, 'GET', `/companies/${companyId}`); + responseData = responseData.company; + if (simple === true) { + responseData = responseData.fields.all; + } } - } - } - - if (resource === 'contact') { - //https://developer.mautic.org/?php#create-contact - if (operation === 'create') { - const options = this.getNodeParameter('options', i) as IDataObject; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const jsonActive = this.getNodeParameter('jsonParameters', i) as boolean; - let body: IDataObject = {}; - if (!jsonActive) { - body.email = this.getNodeParameter('email', i) as string; - body.firstname = this.getNodeParameter('firstName', i) as string; - body.lastname = this.getNodeParameter('lastName', i) as string; - body.company = this.getNodeParameter('company', i) as string; - body.position = this.getNodeParameter('position', i) as string; - body.title = this.getNodeParameter('title', i) as string; - } else { - const json = validateJSON(this.getNodeParameter('bodyJson', i) as string); - if (json !== undefined) { - body = { ...json }; + //https://developer.mautic.org/#list-contact-companies + if (operation === 'getAll') { + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + const simple = this.getNodeParameter('simple', i) as boolean; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + qs = Object.assign(qs, additionalFields); + if (returnAll === true) { + responseData = await mauticApiRequestAllItems.call(this, 'companies', 'GET', '/companies', {}, qs); } else { - throw new NodeOperationError(this.getNode(), 'Invalid JSON'); + qs.limit = this.getNodeParameter('limit', i) as number; + qs.start = 0; + responseData = await mauticApiRequest.call(this, 'GET', '/companies', {}, qs); + if (responseData.errors) { + throw new NodeApiError(this.getNode(), responseData); + } + responseData = responseData.companies; + responseData = Object.values(responseData); + } + if (simple === true) { + //@ts-ignore + responseData = responseData.map(item => item.fields.all); } } - if (additionalFields.ipAddress) { - body.ipAddress = additionalFields.ipAddress as string; - } - if (additionalFields.lastActive) { - body.lastActive = additionalFields.lastActive as string; - } - if (additionalFields.ownerId) { - body.ownerId = additionalFields.ownerId as string; - } - if (additionalFields.addressUi) { - const addressValues = (additionalFields.addressUi as IDataObject).addressValues as IDataObject; - if (addressValues) { - body.address1 = addressValues.address1 as string; - body.address2 = addressValues.address2 as string; - body.city = addressValues.city as string; - body.state = addressValues.state as string; - body.country = addressValues.country as string; - body.zipcode = addressValues.zipCode as string; + //https://developer.mautic.org/#delete-company + if (operation === 'delete') { + const simple = this.getNodeParameter('simple', i) as boolean; + const companyId = this.getNodeParameter('companyId', i) as string; + responseData = await mauticApiRequest.call(this, 'DELETE', `/companies/${companyId}/delete`); + responseData = responseData.company; + if (simple === true) { + responseData = responseData.fields.all; } } - if (additionalFields.socialMediaUi) { - const socialMediaValues = (additionalFields.socialMediaUi as IDataObject).socialMediaValues as IDataObject; - if (socialMediaValues) { - body.facebook = socialMediaValues.facebook as string; - body.foursquare = socialMediaValues.foursquare as string; - body.instagram = socialMediaValues.instagram as string; - body.linkedin = socialMediaValues.linkedIn as string; - body.skype = socialMediaValues.skype as string; - body.twitter = socialMediaValues.twitter as string; - } - } - if (additionalFields.customFieldsUi) { - const customFields = (additionalFields.customFieldsUi as IDataObject).customFieldValues as IDataObject[]; - if (customFields) { - const data = customFields.reduce((obj, value) => Object.assign(obj, { [`${value.fieldId}`]: value.fieldValue }), {}); - Object.assign(body, data); - } - } - if (additionalFields.b2bOrb2c) { - body.b2b_or_b2c = additionalFields.b2bOrb2c as string; - } - if (additionalFields.crmId) { - body.crm_id = additionalFields.crmId as string; - } - if (additionalFields.fax) { - body.fax = additionalFields.fax as string; - } - if (additionalFields.hasPurchased) { - body.haspurchased = additionalFields.hasPurchased as boolean; - } - if (additionalFields.mobile) { - body.mobile = additionalFields.mobile as string; - } - if (additionalFields.phone) { - body.phone = additionalFields.phone as string; - } - if (additionalFields.prospectOrCustomer) { - body.prospect_or_customer = additionalFields.prospectOrCustomer as string; - } - if (additionalFields.sandbox) { - body.sandbox = additionalFields.sandbox as boolean; - } - if (additionalFields.stage) { - body.stage = additionalFields.stage as string; - } - if (additionalFields.tags) { - body.tags = additionalFields.tags as string; - } - if (additionalFields.website) { - body.website = additionalFields.website as string; - } - responseData = await mauticApiRequest.call(this, 'POST', '/contacts/new', body); - responseData = [responseData.contact]; - if (options.rawData === false) { - responseData = responseData.map(item => item.fields.all); - } } - //https://developer.mautic.org/?php#edit-contact - if (operation === 'update') { - const options = this.getNodeParameter('options', i) as IDataObject; - const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; - const contactId = this.getNodeParameter('contactId', i) as string; - let body: IDataObject = {}; - if (updateFields.email) { - body.email = updateFields.email as string; - } - if (updateFields.firstName) { - body.firstname = updateFields.firstName as string; - } - if (updateFields.lastName) { - body.lastname = updateFields.lastName as string; - } - if (updateFields.company) { - body.company = updateFields.company as string; - } - if (updateFields.position) { - body.position = updateFields.position as string; - } - if (updateFields.title) { - body.title = updateFields.title as string; - } - if (updateFields.bodyJson) { - const json = validateJSON(updateFields.bodyJson as string); - if (json !== undefined) { - body = { ...json }; + + if (resource === 'contact') { + //https://developer.mautic.org/?php#create-contact + if (operation === 'create') { + const options = this.getNodeParameter('options', i) as IDataObject; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const jsonActive = this.getNodeParameter('jsonParameters', i) as boolean; + let body: IDataObject = {}; + if (!jsonActive) { + body.email = this.getNodeParameter('email', i) as string; + body.firstname = this.getNodeParameter('firstName', i) as string; + body.lastname = this.getNodeParameter('lastName', i) as string; + body.company = this.getNodeParameter('company', i) as string; + body.position = this.getNodeParameter('position', i) as string; + body.title = this.getNodeParameter('title', i) as string; } else { - throw new NodeOperationError(this.getNode(), 'Invalid JSON'); + const json = validateJSON(this.getNodeParameter('bodyJson', i) as string); + if (json !== undefined) { + body = { ...json }; + } else { + throw new NodeOperationError(this.getNode(), 'Invalid JSON'); + } + } + if (additionalFields.ipAddress) { + body.ipAddress = additionalFields.ipAddress as string; + } + if (additionalFields.lastActive) { + body.lastActive = additionalFields.lastActive as string; + } + if (additionalFields.ownerId) { + body.ownerId = additionalFields.ownerId as string; + } + if (additionalFields.addressUi) { + const addressValues = (additionalFields.addressUi as IDataObject).addressValues as IDataObject; + if (addressValues) { + body.address1 = addressValues.address1 as string; + body.address2 = addressValues.address2 as string; + body.city = addressValues.city as string; + body.state = addressValues.state as string; + body.country = addressValues.country as string; + body.zipcode = addressValues.zipCode as string; + } + } + if (additionalFields.socialMediaUi) { + const socialMediaValues = (additionalFields.socialMediaUi as IDataObject).socialMediaValues as IDataObject; + if (socialMediaValues) { + body.facebook = socialMediaValues.facebook as string; + body.foursquare = socialMediaValues.foursquare as string; + body.instagram = socialMediaValues.instagram as string; + body.linkedin = socialMediaValues.linkedIn as string; + body.skype = socialMediaValues.skype as string; + body.twitter = socialMediaValues.twitter as string; + } + } + if (additionalFields.customFieldsUi) { + const customFields = (additionalFields.customFieldsUi as IDataObject).customFieldValues as IDataObject[]; + if (customFields) { + const data = customFields.reduce((obj, value) => Object.assign(obj, { [`${value.fieldId}`]: value.fieldValue }), {}); + Object.assign(body, data); + } + } + if (additionalFields.b2bOrb2c) { + body.b2b_or_b2c = additionalFields.b2bOrb2c as string; + } + if (additionalFields.crmId) { + body.crm_id = additionalFields.crmId as string; + } + if (additionalFields.fax) { + body.fax = additionalFields.fax as string; + } + if (additionalFields.hasPurchased) { + body.haspurchased = additionalFields.hasPurchased as boolean; + } + if (additionalFields.mobile) { + body.mobile = additionalFields.mobile as string; + } + if (additionalFields.phone) { + body.phone = additionalFields.phone as string; + } + if (additionalFields.prospectOrCustomer) { + body.prospect_or_customer = additionalFields.prospectOrCustomer as string; + } + if (additionalFields.sandbox) { + body.sandbox = additionalFields.sandbox as boolean; + } + if (additionalFields.stage) { + body.stage = additionalFields.stage as string; + } + if (additionalFields.tags) { + body.tags = additionalFields.tags as string; + } + if (additionalFields.website) { + body.website = additionalFields.website as string; + } + responseData = await mauticApiRequest.call(this, 'POST', '/contacts/new', body); + responseData = [responseData.contact]; + if (options.rawData === false) { + responseData = responseData.map(item => item.fields.all); } } - if (updateFields.ipAddress) { - body.ipAddress = updateFields.ipAddress as string; - } - if (updateFields.lastActive) { - body.lastActive = updateFields.lastActive as string; - } - if (updateFields.ownerId) { - body.ownerId = updateFields.ownerId as string; - } - if (updateFields.addressUi) { - const addressValues = (updateFields.addressUi as IDataObject).addressValues as IDataObject; - if (addressValues) { - body.address1 = addressValues.address1 as string; - body.address2 = addressValues.address2 as string; - body.city = addressValues.city as string; - body.state = addressValues.state as string; - body.country = addressValues.country as string; - body.zipcode = addressValues.zipCode as string; + //https://developer.mautic.org/?php#edit-contact + if (operation === 'update') { + const options = this.getNodeParameter('options', i) as IDataObject; + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + const contactId = this.getNodeParameter('contactId', i) as string; + let body: IDataObject = {}; + if (updateFields.email) { + body.email = updateFields.email as string; + } + if (updateFields.firstName) { + body.firstname = updateFields.firstName as string; + } + if (updateFields.lastName) { + body.lastname = updateFields.lastName as string; + } + if (updateFields.company) { + body.company = updateFields.company as string; + } + if (updateFields.position) { + body.position = updateFields.position as string; + } + if (updateFields.title) { + body.title = updateFields.title as string; + } + if (updateFields.bodyJson) { + const json = validateJSON(updateFields.bodyJson as string); + if (json !== undefined) { + body = { ...json }; + } else { + throw new NodeOperationError(this.getNode(), 'Invalid JSON'); + } + } + if (updateFields.ipAddress) { + body.ipAddress = updateFields.ipAddress as string; + } + if (updateFields.lastActive) { + body.lastActive = updateFields.lastActive as string; + } + if (updateFields.ownerId) { + body.ownerId = updateFields.ownerId as string; + } + if (updateFields.addressUi) { + const addressValues = (updateFields.addressUi as IDataObject).addressValues as IDataObject; + if (addressValues) { + body.address1 = addressValues.address1 as string; + body.address2 = addressValues.address2 as string; + body.city = addressValues.city as string; + body.state = addressValues.state as string; + body.country = addressValues.country as string; + body.zipcode = addressValues.zipCode as string; + } + } + if (updateFields.socialMediaUi) { + const socialMediaValues = (updateFields.socialMediaUi as IDataObject).socialMediaValues as IDataObject; + if (socialMediaValues) { + body.facebook = socialMediaValues.facebook as string; + body.foursquare = socialMediaValues.foursquare as string; + body.instagram = socialMediaValues.instagram as string; + body.linkedin = socialMediaValues.linkedIn as string; + body.skype = socialMediaValues.skype as string; + body.twitter = socialMediaValues.twitter as string; + } + } + if (updateFields.customFieldsUi) { + const customFields = (updateFields.customFieldsUi as IDataObject).customFieldValues as IDataObject[]; + if (customFields) { + const data = customFields.reduce((obj, value) => Object.assign(obj, { [`${value.fieldId}`]: value.fieldValue }), {}); + Object.assign(body, data); + } + } + if (updateFields.b2bOrb2c) { + body.b2b_or_b2c = updateFields.b2bOrb2c as string; + } + if (updateFields.crmId) { + body.crm_id = updateFields.crmId as string; + } + if (updateFields.fax) { + body.fax = updateFields.fax as string; + } + if (updateFields.hasPurchased) { + body.haspurchased = updateFields.hasPurchased as boolean; + } + if (updateFields.mobile) { + body.mobile = updateFields.mobile as string; + } + if (updateFields.phone) { + body.phone = updateFields.phone as string; + } + if (updateFields.prospectOrCustomer) { + body.prospect_or_customer = updateFields.prospectOrCustomer as string; + } + if (updateFields.sandbox) { + body.sandbox = updateFields.sandbox as boolean; + } + if (updateFields.stage) { + body.stage = updateFields.stage as string; + } + if (updateFields.tags) { + body.tags = updateFields.tags as string; + } + if (updateFields.website) { + body.website = updateFields.website as string; + } + responseData = await mauticApiRequest.call(this, 'PATCH', `/contacts/${contactId}/edit`, body); + responseData = [responseData.contact]; + if (options.rawData === false) { + responseData = responseData.map(item => item.fields.all); } } - if (updateFields.socialMediaUi) { - const socialMediaValues = (updateFields.socialMediaUi as IDataObject).socialMediaValues as IDataObject; - if (socialMediaValues) { - body.facebook = socialMediaValues.facebook as string; - body.foursquare = socialMediaValues.foursquare as string; - body.instagram = socialMediaValues.instagram as string; - body.linkedin = socialMediaValues.linkedIn as string; - body.skype = socialMediaValues.skype as string; - body.twitter = socialMediaValues.twitter as string; + //https://developer.mautic.org/?php#get-contact + if (operation === 'get') { + const options = this.getNodeParameter('options', i) as IDataObject; + const contactId = this.getNodeParameter('contactId', i) as string; + responseData = await mauticApiRequest.call(this, 'GET', `/contacts/${contactId}`); + responseData = [responseData.contact]; + if (options.rawData === false) { + responseData = responseData.map(item => item.fields.all); } } - if (updateFields.customFieldsUi) { - const customFields = (updateFields.customFieldsUi as IDataObject).customFieldValues as IDataObject[]; - if (customFields) { - const data = customFields.reduce((obj, value) => Object.assign(obj, { [`${value.fieldId}`]: value.fieldValue }), {}); - Object.assign(body, data); + //https://developer.mautic.org/?php#list-contacts + if (operation === 'getAll') { + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + const options = this.getNodeParameter('options', i) as IDataObject; + qs = Object.assign(qs, options); + if (qs.orderBy) { + // For some reason does camelCase get used in the returned data + // but snake_case here. So convert it automatically to not confuse + // the users. + qs.orderBy = snakeCase(qs.orderBy as string); } - } - if (updateFields.b2bOrb2c) { - body.b2b_or_b2c = updateFields.b2bOrb2c as string; - } - if (updateFields.crmId) { - body.crm_id = updateFields.crmId as string; - } - if (updateFields.fax) { - body.fax = updateFields.fax as string; - } - if (updateFields.hasPurchased) { - body.haspurchased = updateFields.hasPurchased as boolean; - } - if (updateFields.mobile) { - body.mobile = updateFields.mobile as string; - } - if (updateFields.phone) { - body.phone = updateFields.phone as string; - } - if (updateFields.prospectOrCustomer) { - body.prospect_or_customer = updateFields.prospectOrCustomer as string; - } - if (updateFields.sandbox) { - body.sandbox = updateFields.sandbox as boolean; - } - if (updateFields.stage) { - body.stage = updateFields.stage as string; - } - if (updateFields.tags) { - body.tags = updateFields.tags as string; - } - if (updateFields.website) { - body.website = updateFields.website as string; - } - responseData = await mauticApiRequest.call(this, 'PATCH', `/contacts/${contactId}/edit`, body); - responseData = [responseData.contact]; - if (options.rawData === false) { - responseData = responseData.map(item => item.fields.all); - } - } - //https://developer.mautic.org/?php#get-contact - if (operation === 'get') { - const options = this.getNodeParameter('options', i) as IDataObject; - const contactId = this.getNodeParameter('contactId', i) as string; - responseData = await mauticApiRequest.call(this, 'GET', `/contacts/${contactId}`); - responseData = [responseData.contact]; - if (options.rawData === false) { - responseData = responseData.map(item => item.fields.all); - } - } - //https://developer.mautic.org/?php#list-contacts - if (operation === 'getAll') { - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - const options = this.getNodeParameter('options', i) as IDataObject; - qs = Object.assign(qs, options); - if (qs.orderBy) { - // For some reason does camelCase get used in the returned data - // but snake_case here. So convert it automatically to not confuse - // the users. - qs.orderBy = snakeCase(qs.orderBy as string); - } - if (returnAll === true) { - responseData = await mauticApiRequestAllItems.call(this, 'contacts', 'GET', '/contacts', {}, qs); - } else { - qs.limit = this.getNodeParameter('limit', i) as number; - qs.start = 0; - responseData = await mauticApiRequest.call(this, 'GET', '/contacts', {}, qs); - if (responseData.errors) { - throw new NodeApiError(this.getNode(), responseData); + if (returnAll === true) { + responseData = await mauticApiRequestAllItems.call(this, 'contacts', 'GET', '/contacts', {}, qs); + } else { + qs.limit = this.getNodeParameter('limit', i) as number; + qs.start = 0; + responseData = await mauticApiRequest.call(this, 'GET', '/contacts', {}, qs); + if (responseData.errors) { + throw new NodeApiError(this.getNode(), responseData); + } + responseData = responseData.contacts; + responseData = Object.values(responseData); + } + if (options.rawData === false) { + //@ts-ignore + responseData = responseData.map(item => item.fields.all); } - responseData = responseData.contacts; - responseData = Object.values(responseData); } - if (options.rawData === false) { - //@ts-ignore - responseData = responseData.map(item => item.fields.all); + //https://developer.mautic.org/?php#delete-contact + if (operation === 'delete') { + const options = this.getNodeParameter('options', i) as IDataObject; + const contactId = this.getNodeParameter('contactId', i) as string; + responseData = await mauticApiRequest.call(this, 'DELETE', `/contacts/${contactId}/delete`); + responseData = [responseData.contact]; + if (options.rawData === false) { + responseData = responseData.map(item => item.fields.all); + } } } - //https://developer.mautic.org/?php#delete-contact - if (operation === 'delete') { - const options = this.getNodeParameter('options', i) as IDataObject; - const contactId = this.getNodeParameter('contactId', i) as string; - responseData = await mauticApiRequest.call(this, 'DELETE', `/contacts/${contactId}/delete`); - responseData = [responseData.contact]; - if (options.rawData === false) { - responseData = responseData.map(item => item.fields.all); + + if (resource === 'contactSegment') { + //https://developer.mautic.org/?php#add-contact-to-a-segment + if (operation === 'add') { + const contactId = this.getNodeParameter('contactId', i) as string; + const segmentId = this.getNodeParameter('segmentId', i) as string; + responseData = await mauticApiRequest.call(this, 'POST', `/segments/${segmentId}/contact/${contactId}/add`); + } + //https://developer.mautic.org/#remove-contact-from-a-segment + if (operation === 'remove') { + const contactId = this.getNodeParameter('contactId', i) as string; + const segmentId = this.getNodeParameter('segmentId', i) as string; + responseData = await mauticApiRequest.call(this, 'POST', `/segments/${segmentId}/contact/${contactId}/remove`); } } - } - if (resource === 'contactSegment') { - //https://developer.mautic.org/?php#add-contact-to-a-segment - if (operation === 'add') { - const contactId = this.getNodeParameter('contactId', i) as string; - const segmentId = this.getNodeParameter('segmentId', i) as string; - responseData = await mauticApiRequest.call(this, 'POST', `/segments/${segmentId}/contact/${contactId}/add`); + if (resource === 'companyContact') { + //https://developer.mautic.org/#add-contact-to-a-company + if (operation === 'add') { + const contactId = this.getNodeParameter('contactId', i) as string; + const companyId = this.getNodeParameter('companyId', i) as string; + responseData = await mauticApiRequest.call(this, 'POST', `/companies/${companyId}/contact/${contactId}/add`, {}); + // responseData = responseData.company; + // if (simple === true) { + // responseData = responseData.fields.all; + // } + } + //https://developer.mautic.org/#remove-contact-from-a-company + if (operation === 'remove') { + const contactId = this.getNodeParameter('contactId', i) as string; + const companyId = this.getNodeParameter('companyId', i) as string; + responseData = await mauticApiRequest.call(this, 'POST', `/companies/${companyId}/contact/${contactId}/remove`, {}); + // responseData = responseData.company; + // if (simple === true) { + // responseData = responseData.fields.all; + // } + } } - //https://developer.mautic.org/#remove-contact-from-a-segment - if (operation === 'remove') { - const contactId = this.getNodeParameter('contactId', i) as string; - const segmentId = this.getNodeParameter('segmentId', i) as string; - responseData = await mauticApiRequest.call(this, 'POST', `/segments/${segmentId}/contact/${contactId}/remove`); - } - } - if (resource === 'companyContact') { - //https://developer.mautic.org/#add-contact-to-a-company - if (operation === 'add') { - const contactId = this.getNodeParameter('contactId', i) as string; - const companyId = this.getNodeParameter('companyId', i) as string; - responseData = await mauticApiRequest.call(this, 'POST', `/companies/${companyId}/contact/${contactId}/add`, {}); - // responseData = responseData.company; - // if (simple === true) { - // responseData = responseData.fields.all; - // } + if (Array.isArray(responseData)) { + returnData.push.apply(returnData, responseData as IDataObject[]); + } else { + returnData.push(responseData as IDataObject); } - //https://developer.mautic.org/#remove-contact-from-a-company - if (operation === 'remove') { - const contactId = this.getNodeParameter('contactId', i) as string; - const companyId = this.getNodeParameter('companyId', i) as string; - responseData = await mauticApiRequest.call(this, 'POST', `/companies/${companyId}/contact/${contactId}/remove`, {}); - // responseData = responseData.company; - // if (simple === true) { - // responseData = responseData.fields.all; - // } + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; } - } - - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else { - returnData.push(responseData as IDataObject); + throw error; } } diff --git a/packages/nodes-base/nodes/Medium/Medium.node.ts b/packages/nodes-base/nodes/Medium/Medium.node.ts index 372852c216..e23ea24776 100644 --- a/packages/nodes-base/nodes/Medium/Medium.node.ts +++ b/packages/nodes-base/nodes/Medium/Medium.node.ts @@ -449,128 +449,135 @@ export class Medium implements INodeType { for (let i = 0; i < items.length; i++) { qs = {}; + try { + resource = this.getNodeParameter('resource', i) as string; + operation = this.getNodeParameter('operation', i) as string; - resource = this.getNodeParameter('resource', i) as string; - operation = this.getNodeParameter('operation', i) as string; + if (resource === 'post') { + //https://github.com/Medium/medium-api-docs + if (operation === 'create') { + // ---------------------------------- + // post:create + // ---------------------------------- - if (resource === 'post') { - //https://github.com/Medium/medium-api-docs - if (operation === 'create') { - // ---------------------------------- - // post:create - // ---------------------------------- + const title = this.getNodeParameter('title', i) as string; + const contentFormat = this.getNodeParameter('contentFormat', i) as string; + const content = this.getNodeParameter('content', i) as string; + bodyRequest = { + tags: [], + title, + contentFormat, + content, - const title = this.getNodeParameter('title', i) as string; - const contentFormat = this.getNodeParameter('contentFormat', i) as string; - const content = this.getNodeParameter('content', i) as string; - bodyRequest = { - tags: [], - title, - contentFormat, - content, + }; - }; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + if (additionalFields.tags) { + const tags = additionalFields.tags as string; + bodyRequest.tags = tags.split(',').map(name => { + const returnValue = name.trim(); + if (returnValue.length > 25) { + throw new NodeOperationError(this.getNode(), `The tag "${returnValue}" is to long. Maximum lenght of a tag is 25 characters.`); + } + return returnValue; + }); - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - if (additionalFields.tags) { - const tags = additionalFields.tags as string; - bodyRequest.tags = tags.split(',').map(name => { - const returnValue = name.trim(); - if (returnValue.length > 25) { - throw new NodeOperationError(this.getNode(), `The tag "${returnValue}" is to long. Maximum lenght of a tag is 25 characters.`); + if ((bodyRequest.tags as string[]).length > 5) { + throw new NodeOperationError(this.getNode(), 'To many tags got used. Maximum 5 can be set.'); } - return returnValue; - }); + } - if ((bodyRequest.tags as string[]).length > 5) { - throw new NodeOperationError(this.getNode(), 'To many tags got used. Maximum 5 can be set.'); + if (additionalFields.canonicalUrl) { + bodyRequest.canonicalUrl = additionalFields.canonicalUrl as string; + } + if (additionalFields.publishStatus) { + bodyRequest.publishStatus = additionalFields.publishStatus as string; + } + if (additionalFields.license) { + bodyRequest.license = additionalFields.license as string; + } + if (additionalFields.notifyFollowers) { + bodyRequest.notifyFollowers = additionalFields.notifyFollowers as string; + } + + const underPublication = this.getNodeParameter('publication', i) as boolean; + + // if user wants to publish it under a specific publication + if (underPublication) { + const publicationId = this.getNodeParameter('publicationId', i) as number; + + responseData = await mediumApiRequest.call( + this, + 'POST', + `/publications/${publicationId}/posts`, + bodyRequest, + qs, + ); + } + else { + const responseAuthorId = await mediumApiRequest.call( + this, + 'GET', + '/me', + {}, + qs, + ); + + const authorId = responseAuthorId.data.id; + responseData = await mediumApiRequest.call( + this, + 'POST', + `/users/${authorId}/posts`, + bodyRequest, + qs, + ); + + responseData = responseData.data; } } + } + if (resource === 'publication') { + //https://github.com/Medium/medium-api-docs#32-publications + if (operation === 'getAll') { + // ---------------------------------- + // publication:getAll + // ---------------------------------- - if (additionalFields.canonicalUrl) { - bodyRequest.canonicalUrl = additionalFields.canonicalUrl as string; - } - if (additionalFields.publishStatus) { - bodyRequest.publishStatus = additionalFields.publishStatus as string; - } - if (additionalFields.license) { - bodyRequest.license = additionalFields.license as string; - } - if (additionalFields.notifyFollowers) { - bodyRequest.notifyFollowers = additionalFields.notifyFollowers as string; - } + const returnAll = this.getNodeParameter('returnAll', i) as string; - const underPublication = this.getNodeParameter('publication', i) as boolean; - - // if user wants to publish it under a specific publication - if (underPublication) { - const publicationId = this.getNodeParameter('publicationId', i) as number; - - responseData = await mediumApiRequest.call( - this, - 'POST', - `/publications/${publicationId}/posts`, - bodyRequest, - qs, - ); - } - else { - const responseAuthorId = await mediumApiRequest.call( + const user = await mediumApiRequest.call( this, 'GET', - '/me', - {}, - qs, + `/me`, ); - const authorId = responseAuthorId.data.id; + const userId = user.data.id; + //Get all publications of that user responseData = await mediumApiRequest.call( this, - 'POST', - `/users/${authorId}/posts`, - bodyRequest, - qs, + 'GET', + `/users/${userId}/publications`, ); responseData = responseData.data; + + if (!returnAll) { + const limit = this.getNodeParameter('limit', i) as number; + responseData = responseData.splice(0, limit); + } } } - } - if (resource === 'publication') { - //https://github.com/Medium/medium-api-docs#32-publications - if (operation === 'getAll') { - // ---------------------------------- - // publication:getAll - // ---------------------------------- - - const returnAll = this.getNodeParameter('returnAll', i) as string; - - const user = await mediumApiRequest.call( - this, - 'GET', - `/me`, - ); - - const userId = user.data.id; - //Get all publications of that user - responseData = await mediumApiRequest.call( - this, - 'GET', - `/users/${userId}/publications`, - ); - - responseData = responseData.data; - - if (!returnAll) { - 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 { + returnData.push(responseData as IDataObject); } - } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else { - returnData.push(responseData as IDataObject); + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } } return [this.helpers.returnJsonArray(returnData)]; diff --git a/packages/nodes-base/nodes/MessageBird/MessageBird.node.ts b/packages/nodes-base/nodes/MessageBird/MessageBird.node.ts index c6b767a6f9..bf5e94b507 100644 --- a/packages/nodes-base/nodes/MessageBird/MessageBird.node.ts +++ b/packages/nodes-base/nodes/MessageBird/MessageBird.node.ts @@ -314,93 +314,100 @@ export class MessageBird implements INodeType { for (let i = 0; i < items.length; i++) { qs = {}; + try { + resource = this.getNodeParameter('resource', i) as string; + operation = this.getNodeParameter('operation', i) as string; - resource = this.getNodeParameter('resource', i) as string; - operation = this.getNodeParameter('operation', i) as string; + if (resource === 'sms') { + //https://developers.messagebird.com/api/sms-messaging/#sms-api + if (operation === 'send') { + // ---------------------------------- + // sms:send + // ---------------------------------- - if (resource === 'sms') { - //https://developers.messagebird.com/api/sms-messaging/#sms-api - if (operation === 'send') { - // ---------------------------------- - // sms:send - // ---------------------------------- + requestMethod = 'POST'; + requestPath = '/messages'; + const originator = this.getNodeParameter('originator', i) as string; + const body = this.getNodeParameter('message', i) as string; - requestMethod = 'POST'; - requestPath = '/messages'; - const originator = this.getNodeParameter('originator', i) as string; - const body = this.getNodeParameter('message', i) as string; + bodyRequest = { + recipients: [], + originator, + body, + }; + const additionalFields = this.getNodeParameter( + 'additionalFields', + i, + ) as IDataObject; - bodyRequest = { - recipients: [], - originator, - body, - }; - const additionalFields = this.getNodeParameter( - 'additionalFields', - i, - ) as IDataObject; + if (additionalFields.groupIds) { + bodyRequest.groupIds = additionalFields.groupIds as string; + } + if (additionalFields.type) { + bodyRequest.type = additionalFields.type as string; + } + if (additionalFields.reference) { + bodyRequest.reference = additionalFields.reference as string; + } + if (additionalFields.reportUrl) { + bodyRequest.reportUrl = additionalFields.reportUrl as string; + } + if (additionalFields.validity) { + bodyRequest.validity = additionalFields.reportUrl as number; + } + if (additionalFields.gateway) { + bodyRequest.gateway = additionalFields.gateway as string; + } + if (additionalFields.typeDetails) { + bodyRequest.typeDetails = additionalFields.typeDetails as string; + } + if (additionalFields.datacoding) { + bodyRequest.datacoding = additionalFields.datacoding as string; + } + if (additionalFields.mclass) { + bodyRequest.mclass = additionalFields.mclass as number; + } + if (additionalFields.scheduledDatetime) { + bodyRequest.scheduledDatetime = additionalFields.scheduledDatetime as string; + } + if (additionalFields.createdDatetime) { + bodyRequest.createdDatetime = additionalFields.createdDatetime as string; + } - if (additionalFields.groupIds) { - bodyRequest.groupIds = additionalFields.groupIds as string; + const receivers = this.getNodeParameter('recipients', i) as string; + bodyRequest.recipients = receivers.split(',').map(item => { + + return parseInt(item, 10); + }); } - if (additionalFields.type) { - bodyRequest.type = additionalFields.type as string; - } - if (additionalFields.reference) { - bodyRequest.reference = additionalFields.reference as string; - } - if (additionalFields.reportUrl) { - bodyRequest.reportUrl = additionalFields.reportUrl as string; - } - if (additionalFields.validity) { - bodyRequest.validity = additionalFields.reportUrl as number; - } - if (additionalFields.gateway) { - bodyRequest.gateway = additionalFields.gateway as string; - } - if (additionalFields.typeDetails) { - bodyRequest.typeDetails = additionalFields.typeDetails as string; - } - if (additionalFields.datacoding) { - bodyRequest.datacoding = additionalFields.datacoding as string; - } - if (additionalFields.mclass) { - bodyRequest.mclass = additionalFields.mclass as number; - } - if (additionalFields.scheduledDatetime) { - bodyRequest.scheduledDatetime = additionalFields.scheduledDatetime as string; - } - if (additionalFields.createdDatetime) { - bodyRequest.createdDatetime = additionalFields.createdDatetime as string; + else { + throw new NodeOperationError(this.getNode(), `The operation "${operation}" is not known!`); } - const receivers = this.getNodeParameter('recipients', i) as string; - bodyRequest.recipients = receivers.split(',').map(item => { - - return parseInt(item, 10); - }); + } else if (resource === 'balance') { + requestMethod = 'GET'; + requestPath = '/balance'; } else { - throw new NodeOperationError(this.getNode(), `The operation "${operation}" is not known!`); + throw new NodeOperationError(this.getNode(), `The resource "${resource}" is not known!`); } - } else if (resource === 'balance') { - requestMethod = 'GET'; - requestPath = '/balance'; - } - else { - throw new NodeOperationError(this.getNode(), `The resource "${resource}" is not known!`); - } + const responseData = await messageBirdApiRequest.call( + this, + requestMethod, + requestPath, + bodyRequest, + qs, + ); - const responseData = await messageBirdApiRequest.call( - this, - requestMethod, - requestPath, - bodyRequest, - qs, - ); - - returnData.push(responseData as IDataObject); + returnData.push(responseData as IDataObject); + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; + } } return [this.helpers.returnJsonArray(returnData)]; diff --git a/packages/nodes-base/nodes/Microsoft/Excel/MicrosoftExcel.node.ts b/packages/nodes-base/nodes/Microsoft/Excel/MicrosoftExcel.node.ts index 22f11ec238..b17299b3c5 100644 --- a/packages/nodes-base/nodes/Microsoft/Excel/MicrosoftExcel.node.ts +++ b/packages/nodes-base/nodes/Microsoft/Excel/MicrosoftExcel.node.ts @@ -164,163 +164,195 @@ export class MicrosoftExcel implements INodeType { if (resource === 'table') { //https://docs.microsoft.com/en-us/graph/api/table-post-rows?view=graph-rest-1.0&tabs=http if (operation === 'addRow') { - // TODO: At some point it should be possible to use item dependent parameters. - // Is however important to then not make one separate request each. - const workbookId = this.getNodeParameter('workbook', 0) as string; - const worksheetId = this.getNodeParameter('worksheet', 0) as string; - const tableId = this.getNodeParameter('table', 0) as string; - const additionalFields = this.getNodeParameter('additionalFields', 0) as IDataObject; - const body: IDataObject = {}; + try { + // TODO: At some point it should be possible to use item dependent parameters. + // Is however important to then not make one separate request each. + const workbookId = this.getNodeParameter('workbook', 0) as string; + const worksheetId = this.getNodeParameter('worksheet', 0) as string; + const tableId = this.getNodeParameter('table', 0) as string; + const additionalFields = this.getNodeParameter('additionalFields', 0) as IDataObject; + const body: IDataObject = {}; - if (additionalFields.index) { - body.index = additionalFields.index as number; - } - - // Get table columns to eliminate any columns not needed on the input - responseData = await microsoftApiRequest.call(this, 'GET', `/drive/items/${workbookId}/workbook/worksheets/${worksheetId}/tables/${tableId}/columns`, {}, qs); - const columns = responseData.value.map((column: IDataObject) => (column.name)); - - const rows: any[][] = []; // tslint:disable-line:no-any - - // Bring the items into the correct format - for (const item of items) { - const row = []; - for (const column of columns) { - row.push(item.json[column]); + if (additionalFields.index) { + body.index = additionalFields.index as number; } - rows.push(row); - } - body.values = rows; - const { id } = await microsoftApiRequest.call(this, 'POST', `/drive/items/${workbookId}/workbook/createSession`, { persistChanges: true }); - responseData = await microsoftApiRequest.call(this, 'POST', `/drive/items/${workbookId}/workbook/worksheets/${worksheetId}/tables/${tableId}/rows/add`, body, {}, '', { 'workbook-session-id': id }); - await microsoftApiRequest.call(this, 'POST', `/drive/items/${workbookId}/workbook/closeSession`, {}, {}, '', { 'workbook-session-id': id }); + // Get table columns to eliminate any columns not needed on the input + responseData = await microsoftApiRequest.call(this, 'GET', `/drive/items/${workbookId}/workbook/worksheets/${worksheetId}/tables/${tableId}/columns`, {}, qs); + const columns = responseData.value.map((column: IDataObject) => (column.name)); - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else if (responseData !== undefined) { - returnData.push(responseData as IDataObject); - } - } - //https://docs.microsoft.com/en-us/graph/api/table-list-columns?view=graph-rest-1.0&tabs=http - if (operation === 'getColumns') { - for (let i = 0; i < length; i++) { - qs = {}; - const workbookId = this.getNodeParameter('workbook', i) as string; - const worksheetId = this.getNodeParameter('worksheet', i) as string; - const tableId = this.getNodeParameter('table', i) as string; - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - const rawData = this.getNodeParameter('rawData', i) as boolean; - if (rawData) { - const filters = this.getNodeParameter('filters', i) as IDataObject; - if (filters.fields) { - qs['$select'] = filters.fields; + const rows: any[][] = []; // tslint:disable-line:no-any + + // Bring the items into the correct format + for (const item of items) { + const row = []; + for (const column of columns) { + row.push(item.json[column]); } + rows.push(row); } - if (returnAll === true) { - responseData = await microsoftApiRequestAllItemsSkip.call(this, 'value', 'GET', `/drive/items/${workbookId}/workbook/worksheets/${worksheetId}/tables/${tableId}/columns`, {}, qs); - } else { - qs['$top'] = this.getNodeParameter('limit', i) as number; - responseData = await microsoftApiRequest.call(this, 'GET', `/drive/items/${workbookId}/workbook/worksheets/${worksheetId}/tables/${tableId}/columns`, {}, qs); - responseData = responseData.value; - } - if (!rawData) { - responseData = responseData.map((column: IDataObject) => ({ name: column.name })); - } else { - const dataProperty = this.getNodeParameter('dataProperty', i) as string; - responseData = { [dataProperty] : responseData }; - } + + body.values = rows; + const { id } = await microsoftApiRequest.call(this, 'POST', `/drive/items/${workbookId}/workbook/createSession`, { persistChanges: true }); + responseData = await microsoftApiRequest.call(this, 'POST', `/drive/items/${workbookId}/workbook/worksheets/${worksheetId}/tables/${tableId}/rows/add`, body, {}, '', { 'workbook-session-id': id }); + await microsoftApiRequest.call(this, 'POST', `/drive/items/${workbookId}/workbook/closeSession`, {}, {}, '', { 'workbook-session-id': id }); if (Array.isArray(responseData)) { returnData.push.apply(returnData, responseData as IDataObject[]); } else if (responseData !== undefined) { returnData.push(responseData as IDataObject); } + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + } else { + throw error; + } + } + } + //https://docs.microsoft.com/en-us/graph/api/table-list-columns?view=graph-rest-1.0&tabs=http + if (operation === 'getColumns') { + for (let i = 0; i < length; i++) { + try { + qs = {}; + const workbookId = this.getNodeParameter('workbook', i) as string; + const worksheetId = this.getNodeParameter('worksheet', i) as string; + const tableId = this.getNodeParameter('table', i) as string; + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + const rawData = this.getNodeParameter('rawData', i) as boolean; + if (rawData) { + const filters = this.getNodeParameter('filters', i) as IDataObject; + if (filters.fields) { + qs['$select'] = filters.fields; + } + } + if (returnAll === true) { + responseData = await microsoftApiRequestAllItemsSkip.call(this, 'value', 'GET', `/drive/items/${workbookId}/workbook/worksheets/${worksheetId}/tables/${tableId}/columns`, {}, qs); + } else { + qs['$top'] = this.getNodeParameter('limit', i) as number; + responseData = await microsoftApiRequest.call(this, 'GET', `/drive/items/${workbookId}/workbook/worksheets/${worksheetId}/tables/${tableId}/columns`, {}, qs); + responseData = responseData.value; + } + if (!rawData) { + responseData = responseData.map((column: IDataObject) => ({ name: column.name })); + } else { + const dataProperty = this.getNodeParameter('dataProperty', i) as string; + responseData = { [dataProperty] : responseData }; + } + + if (Array.isArray(responseData)) { + returnData.push.apply(returnData, responseData as IDataObject[]); + } else if (responseData !== undefined) { + returnData.push(responseData as IDataObject); + } + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; + } } } //https://docs.microsoft.com/en-us/graph/api/table-list-rows?view=graph-rest-1.0&tabs=http if (operation === 'getRows') { for (let i = 0; i < length; i++) { qs = {}; - const workbookId = this.getNodeParameter('workbook', i) as string; - const worksheetId = this.getNodeParameter('worksheet', i) as string; - const tableId = this.getNodeParameter('table', i) as string; - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - const rawData = this.getNodeParameter('rawData', i) as boolean; - if (rawData) { - const filters = this.getNodeParameter('filters', i) as IDataObject; - if (filters.fields) { - qs['$select'] = filters.fields; - } - } - if (returnAll === true) { - responseData = await microsoftApiRequestAllItemsSkip.call(this, 'value', 'GET', `/drive/items/${workbookId}/workbook/worksheets/${worksheetId}/tables/${tableId}/rows`, {}, qs); - } else { - const rowsQs = { ...qs }; - rowsQs['$top'] = this.getNodeParameter('limit', i) as number; - responseData = await microsoftApiRequest.call(this, 'GET', `/drive/items/${workbookId}/workbook/worksheets/${worksheetId}/tables/${tableId}/rows`, {}, rowsQs); - responseData = responseData.value; - } - if (!rawData) { - const columnsQs = { ...qs }; - columnsQs['$select'] = 'name'; - // TODO: That should probably be cached in the future - let columns = await microsoftApiRequestAllItemsSkip.call(this, 'value', 'GET', `/drive/items/${workbookId}/workbook/worksheets/${worksheetId}/tables/${tableId}/columns`, {}, columnsQs); - //@ts-ignore - columns = columns.map(column => column.name); - for (let i = 0; i < responseData.length; i++) { - const object: IDataObject = {}; - for (let y = 0; y < columns.length; y++) { - object[columns[y]] = responseData[i].values[0][y]; + try { + const workbookId = this.getNodeParameter('workbook', i) as string; + const worksheetId = this.getNodeParameter('worksheet', i) as string; + const tableId = this.getNodeParameter('table', i) as string; + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + const rawData = this.getNodeParameter('rawData', i) as boolean; + if (rawData) { + const filters = this.getNodeParameter('filters', i) as IDataObject; + if (filters.fields) { + qs['$select'] = filters.fields; } - returnData.push({ ...object }); } - } else { - const dataProperty = this.getNodeParameter('dataProperty', i) as string; - returnData.push({ [dataProperty]: responseData }); + if (returnAll === true) { + responseData = await microsoftApiRequestAllItemsSkip.call(this, 'value', 'GET', `/drive/items/${workbookId}/workbook/worksheets/${worksheetId}/tables/${tableId}/rows`, {}, qs); + } else { + const rowsQs = { ...qs }; + rowsQs['$top'] = this.getNodeParameter('limit', i) as number; + responseData = await microsoftApiRequest.call(this, 'GET', `/drive/items/${workbookId}/workbook/worksheets/${worksheetId}/tables/${tableId}/rows`, {}, rowsQs); + responseData = responseData.value; + } + if (!rawData) { + const columnsQs = { ...qs }; + columnsQs['$select'] = 'name'; + // TODO: That should probably be cached in the future + let columns = await microsoftApiRequestAllItemsSkip.call(this, 'value', 'GET', `/drive/items/${workbookId}/workbook/worksheets/${worksheetId}/tables/${tableId}/columns`, {}, columnsQs); + //@ts-ignore + columns = columns.map(column => column.name); + for (let i = 0; i < responseData.length; i++) { + const object: IDataObject = {}; + for (let y = 0; y < columns.length; y++) { + object[columns[y]] = responseData[i].values[0][y]; + } + returnData.push({ ...object }); + } + } else { + const dataProperty = this.getNodeParameter('dataProperty', i) as string; + returnData.push({ [dataProperty]: responseData }); + } + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } } } if (operation === 'lookup') { for (let i = 0; i < length; i++) { qs = {}; - const workbookId = this.getNodeParameter('workbook', i) as string; - const worksheetId = this.getNodeParameter('worksheet', i) as string; - const tableId = this.getNodeParameter('table', i) as string; - const lookupColumn = this.getNodeParameter('lookupColumn', i) as string; - const lookupValue = this.getNodeParameter('lookupValue', i) as string; - const options = this.getNodeParameter('options', i) as IDataObject; + try { + const workbookId = this.getNodeParameter('workbook', i) as string; + const worksheetId = this.getNodeParameter('worksheet', i) as string; + const tableId = this.getNodeParameter('table', i) as string; + const lookupColumn = this.getNodeParameter('lookupColumn', i) as string; + const lookupValue = this.getNodeParameter('lookupValue', i) as string; + const options = this.getNodeParameter('options', i) as IDataObject; - responseData = await microsoftApiRequestAllItemsSkip.call(this, 'value', 'GET', `/drive/items/${workbookId}/workbook/worksheets/${worksheetId}/tables/${tableId}/rows`, {}, {}); + responseData = await microsoftApiRequestAllItemsSkip.call(this, 'value', 'GET', `/drive/items/${workbookId}/workbook/worksheets/${worksheetId}/tables/${tableId}/rows`, {}, {}); - qs['$select'] = 'name'; - // TODO: That should probably be cached in the future - let columns = await microsoftApiRequestAllItemsSkip.call(this, 'value', 'GET', `/drive/items/${workbookId}/workbook/worksheets/${worksheetId}/tables/${tableId}/columns`, {}, qs); - columns = columns.map((column: IDataObject) => column.name); + qs['$select'] = 'name'; + // TODO: That should probably be cached in the future + let columns = await microsoftApiRequestAllItemsSkip.call(this, 'value', 'GET', `/drive/items/${workbookId}/workbook/worksheets/${worksheetId}/tables/${tableId}/columns`, {}, qs); + columns = columns.map((column: IDataObject) => column.name); - if (!columns.includes(lookupColumn)) { - throw new NodeApiError(this.getNode(), responseData, { message: `Column ${lookupColumn} does not exist on the table selected` }); - } - - result.length = 0; - for (let i = 0; i < responseData.length; i++) { - const object: IDataObject = {}; - for (let y = 0; y < columns.length; y++) { - object[columns[y]] = responseData[i].values[0][y]; + if (!columns.includes(lookupColumn)) { + throw new NodeApiError(this.getNode(), responseData, { message: `Column ${lookupColumn} does not exist on the table selected` }); } - result.push({ ...object }); - } - if (options.returnAllMatches) { - responseData = result.filter((data: IDataObject) => { - return (data[lookupColumn]?.toString() === lookupValue ); - }); - returnData.push.apply(returnData, responseData as IDataObject[]); - } else { - responseData = result.find((data: IDataObject) => { - return (data[lookupColumn]?.toString() === lookupValue ); - }); - returnData.push(responseData as IDataObject); + result.length = 0; + for (let i = 0; i < responseData.length; i++) { + const object: IDataObject = {}; + for (let y = 0; y < columns.length; y++) { + object[columns[y]] = responseData[i].values[0][y]; + } + result.push({ ...object }); + } + + if (options.returnAllMatches) { + responseData = result.filter((data: IDataObject) => { + return (data[lookupColumn]?.toString() === lookupValue ); + }); + returnData.push.apply(returnData, responseData as IDataObject[]); + } else { + responseData = result.find((data: IDataObject) => { + return (data[lookupColumn]?.toString() === lookupValue ); + }); + returnData.push(responseData as IDataObject); + } + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } } } @@ -328,92 +360,108 @@ export class MicrosoftExcel implements INodeType { if (resource === 'workbook') { for (let i = 0; i < length; i++) { qs = {}; - //https://docs.microsoft.com/en-us/graph/api/worksheetcollection-add?view=graph-rest-1.0&tabs=http - if (operation === 'addWorksheet') { - const workbookId = this.getNodeParameter('workbook', i) as string; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const body: IDataObject = {}; - if (additionalFields.name) { - body.name = additionalFields.name; + try { + //https://docs.microsoft.com/en-us/graph/api/worksheetcollection-add?view=graph-rest-1.0&tabs=http + if (operation === 'addWorksheet') { + const workbookId = this.getNodeParameter('workbook', i) as string; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const body: IDataObject = {}; + if (additionalFields.name) { + body.name = additionalFields.name; + } + const { id } = await microsoftApiRequest.call(this, 'POST', `/drive/items/${workbookId}/workbook/createSession`, { persistChanges: true }); + responseData = await microsoftApiRequest.call(this, 'POST', `/drive/items/${workbookId}/workbook/worksheets/add`, body, {}, '', { 'workbook-session-id': id }); + await microsoftApiRequest.call(this, 'POST', `/drive/items/${workbookId}/workbook/closeSession`, {}, {}, '', { 'workbook-session-id': id }); } - const { id } = await microsoftApiRequest.call(this, 'POST', `/drive/items/${workbookId}/workbook/createSession`, { persistChanges: true }); - responseData = await microsoftApiRequest.call(this, 'POST', `/drive/items/${workbookId}/workbook/worksheets/add`, body, {}, '', { 'workbook-session-id': id }); - await microsoftApiRequest.call(this, 'POST', `/drive/items/${workbookId}/workbook/closeSession`, {}, {}, '', { 'workbook-session-id': id }); - } - if (operation === 'getAll') { - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - const filters = this.getNodeParameter('filters', i) as IDataObject; - if (filters.fields) { - qs['$select'] = filters.fields; + if (operation === 'getAll') { + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + const filters = this.getNodeParameter('filters', i) as IDataObject; + if (filters.fields) { + qs['$select'] = filters.fields; + } + if (returnAll === true) { + responseData = await microsoftApiRequestAllItems.call(this, 'value', 'GET', `/drive/root/search(q='.xlsx')`, {}, qs); + } else { + qs['$top'] = this.getNodeParameter('limit', i) as number; + responseData = await microsoftApiRequest.call(this, 'GET', `/drive/root/search(q='.xlsx')`, {}, qs); + responseData = responseData.value; + } } - if (returnAll === true) { - responseData = await microsoftApiRequestAllItems.call(this, 'value', 'GET', `/drive/root/search(q='.xlsx')`, {}, qs); - } else { - qs['$top'] = this.getNodeParameter('limit', i) as number; - responseData = await microsoftApiRequest.call(this, 'GET', `/drive/root/search(q='.xlsx')`, {}, qs); - responseData = responseData.value; - } - } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else if (responseData !== undefined) { - returnData.push(responseData as IDataObject); + if (Array.isArray(responseData)) { + returnData.push.apply(returnData, responseData as IDataObject[]); + } else if (responseData !== undefined) { + returnData.push(responseData as IDataObject); + } + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } } } if (resource === 'worksheet') { for (let i = 0; i < length; i++) { qs = {}; - //https://docs.microsoft.com/en-us/graph/api/workbook-list-worksheets?view=graph-rest-1.0&tabs=http - if (operation === 'getAll') { - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - const workbookId = this.getNodeParameter('workbook', i) as string; - const filters = this.getNodeParameter('filters', i) as IDataObject; - if (filters.fields) { - qs['$select'] = filters.fields; - } - if (returnAll === true) { - responseData = await microsoftApiRequestAllItems.call(this, 'value', 'GET', `/drive/items/${workbookId}/workbook/worksheets`, {}, qs); - } else { - qs['$top'] = this.getNodeParameter('limit', i) as number; - responseData = await microsoftApiRequest.call(this, 'GET', `/drive/items/${workbookId}/workbook/worksheets`, {}, qs); - responseData = responseData.value; - } - } - //https://docs.microsoft.com/en-us/graph/api/worksheet-range?view=graph-rest-1.0&tabs=http - if (operation === 'getContent') { - const workbookId = this.getNodeParameter('workbook', i) as string; - const worksheetId = this.getNodeParameter('worksheet', i) as string; - const range = this.getNodeParameter('range', i) as string; - const rawData = this.getNodeParameter('rawData', i) as boolean; - if (rawData) { + try { + //https://docs.microsoft.com/en-us/graph/api/workbook-list-worksheets?view=graph-rest-1.0&tabs=http + if (operation === 'getAll') { + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + const workbookId = this.getNodeParameter('workbook', i) as string; const filters = this.getNodeParameter('filters', i) as IDataObject; if (filters.fields) { qs['$select'] = filters.fields; } - } - - responseData = await microsoftApiRequest.call(this, 'GET', `/drive/items/${workbookId}/workbook/worksheets/${worksheetId}/range(address='${range}')`, {}, qs); - - if (!rawData) { - const keyRow = this.getNodeParameter('keyRow', i) as number; - const dataStartRow = this.getNodeParameter('dataStartRow', i) as number; - if (responseData.values === null) { - throw new NodeApiError(this.getNode(), responseData, { message: 'Range did not return data' }); + if (returnAll === true) { + responseData = await microsoftApiRequestAllItems.call(this, 'value', 'GET', `/drive/items/${workbookId}/workbook/worksheets`, {}, qs); + } else { + qs['$top'] = this.getNodeParameter('limit', i) as number; + responseData = await microsoftApiRequest.call(this, 'GET', `/drive/items/${workbookId}/workbook/worksheets`, {}, qs); + responseData = responseData.value; } - const keyValues = responseData.values[keyRow]; - for (let i = dataStartRow; i < responseData.values.length; i++) { - const object: IDataObject = {}; - for (let y = 0; y < keyValues.length; y++) { - object[keyValues[y]] = responseData.values[i][y]; + } + //https://docs.microsoft.com/en-us/graph/api/worksheet-range?view=graph-rest-1.0&tabs=http + if (operation === 'getContent') { + const workbookId = this.getNodeParameter('workbook', i) as string; + const worksheetId = this.getNodeParameter('worksheet', i) as string; + const range = this.getNodeParameter('range', i) as string; + const rawData = this.getNodeParameter('rawData', i) as boolean; + if (rawData) { + const filters = this.getNodeParameter('filters', i) as IDataObject; + if (filters.fields) { + qs['$select'] = filters.fields; } - returnData.push({ ...object }); } - } else { - const dataProperty = this.getNodeParameter('dataProperty', i) as string; - returnData.push({ [dataProperty]: responseData }); + + responseData = await microsoftApiRequest.call(this, 'GET', `/drive/items/${workbookId}/workbook/worksheets/${worksheetId}/range(address='${range}')`, {}, qs); + + if (!rawData) { + const keyRow = this.getNodeParameter('keyRow', i) as number; + const dataStartRow = this.getNodeParameter('dataStartRow', i) as number; + if (responseData.values === null) { + throw new NodeApiError(this.getNode(), responseData, { message: 'Range did not return data' }); + } + const keyValues = responseData.values[keyRow]; + for (let i = dataStartRow; i < responseData.values.length; i++) { + const object: IDataObject = {}; + for (let y = 0; y < keyValues.length; y++) { + object[keyValues[y]] = responseData.values[i][y]; + } + returnData.push({ ...object }); + } + } else { + const dataProperty = this.getNodeParameter('dataProperty', i) as string; + returnData.push({ [dataProperty]: responseData }); + } } + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } } } diff --git a/packages/nodes-base/nodes/Microsoft/OneDrive/MicrosoftOneDrive.node.ts b/packages/nodes-base/nodes/Microsoft/OneDrive/MicrosoftOneDrive.node.ts index 65e374b343..052450eae9 100644 --- a/packages/nodes-base/nodes/Microsoft/OneDrive/MicrosoftOneDrive.node.ts +++ b/packages/nodes-base/nodes/Microsoft/OneDrive/MicrosoftOneDrive.node.ts @@ -83,177 +83,189 @@ export class MicrosoftOneDrive implements INodeType { 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 === 'file') { - //https://docs.microsoft.com/en-us/onedrive/developer/rest-api/api/driveitem_copy?view=odsp-graph-online - if (operation === 'copy') { - const fileId = this.getNodeParameter('fileId', i) as string; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const parentReference = this.getNodeParameter('parentReference', i) as IDataObject; - const body: IDataObject = {}; - if (parentReference) { - body.parentReference = { ...parentReference }; - } - if (additionalFields.name) { - body.name = additionalFields.name as string; - } - responseData = await microsoftApiRequest.call(this, 'POST', `/drive/items/${fileId}/copy`, body, {}, undefined, {}, { json: true, resolveWithFullResponse: true }); - responseData = { location : responseData.headers.location }; - returnData.push(responseData as IDataObject); - } - //https://docs.microsoft.com/en-us/onedrive/developer/rest-api/api/driveitem_delete?view=odsp-graph-online - if (operation === 'delete') { - const fileId = this.getNodeParameter('fileId', i) as string; - responseData = await microsoftApiRequest.call(this, 'DELETE', `/drive/items/${fileId}`); - responseData = { success: true }; - returnData.push(responseData as IDataObject); - } - //https://docs.microsoft.com/en-us/onedrive/developer/rest-api/api/driveitem_list_children?view=odsp-graph-online - if (operation === 'download') { - const fileId = this.getNodeParameter('fileId', i) as string; - const dataPropertyNameDownload = this.getNodeParameter('binaryPropertyName', i) as string; - responseData = await microsoftApiRequest.call(this, 'GET', `/drive/items/${fileId}`); - - const fileName = responseData.name; - - if (responseData.file === undefined) { - throw new NodeApiError(this.getNode(), responseData, { message: 'The ID you provided does not belong to a file.' }); - } - - let mimeType: string | undefined; - if (responseData.file.mimeType) { - mimeType = responseData.file.mimeType; - } - - responseData = await microsoftApiRequest.call(this, 'GET', `/drive/items/${fileId}/content`, {}, {}, undefined, {}, { encoding: null, resolveWithFullResponse: true }); - - const newItem: INodeExecutionData = { - json: items[i].json, - binary: {}, - }; - - if (mimeType === undefined && responseData.headers['content-type']) { - mimeType = responseData.headers['content-type']; - } - - if (items[i].binary !== undefined) { - // Create a shallow copy of the binary data so that the old - // data references which do not get changed still stay behind - // but the incoming data does not get changed. - Object.assign(newItem.binary, items[i].binary); - } - - items[i] = newItem; - - const data = Buffer.from(responseData.body); - - items[i].binary![dataPropertyNameDownload] = await this.helpers.prepareBinaryData(data as unknown as Buffer, fileName, mimeType); - } - //https://docs.microsoft.com/en-us/onedrive/developer/rest-api/api/driveitem_get?view=odsp-graph-online - if (operation === 'get') { - const fileId = this.getNodeParameter('fileId', i) as string; - responseData = await microsoftApiRequest.call(this, 'GET', `/drive/items/${fileId}`); - returnData.push(responseData as IDataObject); - } - //https://docs.microsoft.com/en-us/onedrive/developer/rest-api/api/driveitem_search?view=odsp-graph-online - if (operation === 'search') { - const query = this.getNodeParameter('query', i) as string; - responseData = await microsoftApiRequestAllItems.call(this, 'value', 'GET', `/drive/root/search(q='${query}')`); - responseData = responseData.filter((item: IDataObject) => item.file); - returnData.push.apply(returnData, responseData as IDataObject[]); - } - //https://docs.microsoft.com/en-us/onedrive/developer/rest-api/api/driveitem_createlink?view=odsp-graph-online - if (operation === 'share') { - const fileId = this.getNodeParameter('fileId', i) as string; - const type = this.getNodeParameter('type', i) as string; - const scope = this.getNodeParameter('scope', i) as string; - const body: IDataObject = { - type, - scope, - }; - responseData = await microsoftApiRequest.call(this, 'POST', `/drive/items/${fileId}/createLink`, body); - returnData.push(responseData); - } - //https://docs.microsoft.com/en-us/onedrive/developer/rest-api/api/driveitem_put_content?view=odsp-graph-online#example-upload-a-new-file - if (operation === 'upload') { - const parentId = this.getNodeParameter('parentId', i) as string; - const isBinaryData = this.getNodeParameter('binaryData', i) as boolean; - const fileName = this.getNodeParameter('fileName', i) as string; - - if (isBinaryData) { - const binaryPropertyName = this.getNodeParameter('binaryPropertyName', 0) as string; - - if (items[i].binary === undefined) { - throw new NodeOperationError(this.getNode(), 'No binary data exists on item!'); + try { + if (resource === 'file') { + //https://docs.microsoft.com/en-us/onedrive/developer/rest-api/api/driveitem_copy?view=odsp-graph-online + if (operation === 'copy') { + const fileId = this.getNodeParameter('fileId', i) as string; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const parentReference = this.getNodeParameter('parentReference', i) as IDataObject; + const body: IDataObject = {}; + if (parentReference) { + body.parentReference = { ...parentReference }; } - //@ts-ignore - if (items[i].binary[binaryPropertyName] === undefined) { - throw new NodeOperationError(this.getNode(), `No binary data property "${binaryPropertyName}" does not exists on item!`); + if (additionalFields.name) { + body.name = additionalFields.name as string; } - - const binaryData = (items[i].binary as IBinaryKeyData)[binaryPropertyName]; - - const body = Buffer.from(binaryData.data, BINARY_ENCODING); - responseData = await microsoftApiRequest.call(this, 'PUT', `/drive/items/${parentId}:/${fileName || binaryData.fileName}:/content`, body, {}, undefined, { 'Content-Type': binaryData.mimeType, 'Content-length': body.length }, {} ); - - returnData.push(JSON.parse(responseData) as IDataObject); - } else { - const body = this.getNodeParameter('fileContent', i) as string; - if (fileName === '') { - throw new NodeOperationError(this.getNode(), 'File name must be set!'); - } - responseData = await microsoftApiRequest.call(this, 'PUT', `/drive/items/${parentId}:/${fileName}:/content`, body , {}, undefined, { 'Content-Type': 'text/plain' } ); + responseData = await microsoftApiRequest.call(this, 'POST', `/drive/items/${fileId}/copy`, body, {}, undefined, {}, { json: true, resolveWithFullResponse: true }); + responseData = { location : responseData.headers.location }; returnData.push(responseData as IDataObject); } - } - } - if (resource === 'folder') { - //https://docs.microsoft.com/en-us/onedrive/developer/rest-api/api/driveitem_post_children?view=odsp-graph-online - if (operation === 'create') { - const name = this.getNodeParameter('name', i) as string; - const options = this.getNodeParameter('options', i) as IDataObject; - const body: IDataObject = { - name, - folder: {}, - }; - let endpoint = '/drive/root/children'; - if (options.parentFolderId) { - endpoint = `/drive/items/${options.parentFolderId}/children`; + //https://docs.microsoft.com/en-us/onedrive/developer/rest-api/api/driveitem_delete?view=odsp-graph-online + if (operation === 'delete') { + const fileId = this.getNodeParameter('fileId', i) as string; + responseData = await microsoftApiRequest.call(this, 'DELETE', `/drive/items/${fileId}`); + responseData = { success: true }; + returnData.push(responseData as IDataObject); + } + //https://docs.microsoft.com/en-us/onedrive/developer/rest-api/api/driveitem_list_children?view=odsp-graph-online + if (operation === 'download') { + const fileId = this.getNodeParameter('fileId', i) as string; + const dataPropertyNameDownload = this.getNodeParameter('binaryPropertyName', i) as string; + responseData = await microsoftApiRequest.call(this, 'GET', `/drive/items/${fileId}`); + + const fileName = responseData.name; + + if (responseData.file === undefined) { + throw new NodeApiError(this.getNode(), responseData, { message: 'The ID you provided does not belong to a file.' }); + } + + let mimeType: string | undefined; + if (responseData.file.mimeType) { + mimeType = responseData.file.mimeType; + } + + responseData = await microsoftApiRequest.call(this, 'GET', `/drive/items/${fileId}/content`, {}, {}, undefined, {}, { encoding: null, resolveWithFullResponse: true }); + + const newItem: INodeExecutionData = { + json: items[i].json, + binary: {}, + }; + + if (mimeType === undefined && responseData.headers['content-type']) { + mimeType = responseData.headers['content-type']; + } + + if (items[i].binary !== undefined) { + // Create a shallow copy of the binary data so that the old + // data references which do not get changed still stay behind + // but the incoming data does not get changed. + Object.assign(newItem.binary, items[i].binary); + } + + items[i] = newItem; + + const data = Buffer.from(responseData.body); + + items[i].binary![dataPropertyNameDownload] = await this.helpers.prepareBinaryData(data as unknown as Buffer, fileName, mimeType); + } + //https://docs.microsoft.com/en-us/onedrive/developer/rest-api/api/driveitem_get?view=odsp-graph-online + if (operation === 'get') { + const fileId = this.getNodeParameter('fileId', i) as string; + responseData = await microsoftApiRequest.call(this, 'GET', `/drive/items/${fileId}`); + returnData.push(responseData as IDataObject); + } + //https://docs.microsoft.com/en-us/onedrive/developer/rest-api/api/driveitem_search?view=odsp-graph-online + if (operation === 'search') { + const query = this.getNodeParameter('query', i) as string; + responseData = await microsoftApiRequestAllItems.call(this, 'value', 'GET', `/drive/root/search(q='${query}')`); + responseData = responseData.filter((item: IDataObject) => item.file); + returnData.push.apply(returnData, responseData as IDataObject[]); + } + //https://docs.microsoft.com/en-us/onedrive/developer/rest-api/api/driveitem_createlink?view=odsp-graph-online + if (operation === 'share') { + const fileId = this.getNodeParameter('fileId', i) as string; + const type = this.getNodeParameter('type', i) as string; + const scope = this.getNodeParameter('scope', i) as string; + const body: IDataObject = { + type, + scope, + }; + responseData = await microsoftApiRequest.call(this, 'POST', `/drive/items/${fileId}/createLink`, body); + returnData.push(responseData); + } + //https://docs.microsoft.com/en-us/onedrive/developer/rest-api/api/driveitem_put_content?view=odsp-graph-online#example-upload-a-new-file + if (operation === 'upload') { + const parentId = this.getNodeParameter('parentId', i) as string; + const isBinaryData = this.getNodeParameter('binaryData', i) as boolean; + const fileName = this.getNodeParameter('fileName', i) as string; + + if (isBinaryData) { + const binaryPropertyName = this.getNodeParameter('binaryPropertyName', 0) as string; + + if (items[i].binary === undefined) { + throw new NodeOperationError(this.getNode(), 'No binary data exists on item!'); + } + //@ts-ignore + if (items[i].binary[binaryPropertyName] === undefined) { + throw new NodeOperationError(this.getNode(), `No binary data property "${binaryPropertyName}" does not exists on item!`); + } + + const binaryData = (items[i].binary as IBinaryKeyData)[binaryPropertyName]; + + const body = Buffer.from(binaryData.data, BINARY_ENCODING); + responseData = await microsoftApiRequest.call(this, 'PUT', `/drive/items/${parentId}:/${fileName || binaryData.fileName}:/content`, body, {}, undefined, { 'Content-Type': binaryData.mimeType, 'Content-length': body.length }, {} ); + + returnData.push(JSON.parse(responseData) as IDataObject); + } else { + const body = this.getNodeParameter('fileContent', i) as string; + if (fileName === '') { + throw new NodeOperationError(this.getNode(), 'File name must be set!'); + } + responseData = await microsoftApiRequest.call(this, 'PUT', `/drive/items/${parentId}:/${fileName}:/content`, body , {}, undefined, { 'Content-Type': 'text/plain' } ); + returnData.push(responseData as IDataObject); + } } - responseData = await microsoftApiRequest.call(this, 'POST', endpoint, body); - returnData.push(responseData); } - //https://docs.microsoft.com/en-us/onedrive/developer/rest-api/api/driveitem_delete?view=odsp-graph-online - if (operation === 'delete') { - const folderId = this.getNodeParameter('folderId', i) as string; - responseData = await microsoftApiRequest.call(this, 'DELETE', `/drive/items/${folderId}`); - responseData = { success: true }; - returnData.push(responseData as IDataObject); + if (resource === 'folder') { + //https://docs.microsoft.com/en-us/onedrive/developer/rest-api/api/driveitem_post_children?view=odsp-graph-online + if (operation === 'create') { + const name = this.getNodeParameter('name', i) as string; + const options = this.getNodeParameter('options', i) as IDataObject; + const body: IDataObject = { + name, + folder: {}, + }; + let endpoint = '/drive/root/children'; + if (options.parentFolderId) { + endpoint = `/drive/items/${options.parentFolderId}/children`; + } + responseData = await microsoftApiRequest.call(this, 'POST', endpoint, body); + returnData.push(responseData); + } + //https://docs.microsoft.com/en-us/onedrive/developer/rest-api/api/driveitem_delete?view=odsp-graph-online + if (operation === 'delete') { + const folderId = this.getNodeParameter('folderId', i) as string; + responseData = await microsoftApiRequest.call(this, 'DELETE', `/drive/items/${folderId}`); + responseData = { success: true }; + returnData.push(responseData as IDataObject); + } + //https://docs.microsoft.com/en-us/onedrive/developer/rest-api/api/driveitem_list_children?view=odsp-graph-online + if (operation === 'getChildren') { + const folderId = this.getNodeParameter('folderId', i) as string; + responseData = await microsoftApiRequestAllItems.call(this, 'value', 'GET', `/drive/items/${folderId}/children`); + returnData.push.apply(returnData, responseData as IDataObject[]); + } + //https://docs.microsoft.com/en-us/onedrive/developer/rest-api/api/driveitem_search?view=odsp-graph-online + if (operation === 'search') { + const query = this.getNodeParameter('query', i) as string; + responseData = await microsoftApiRequestAllItems.call(this, 'value', 'GET', `/drive/root/search(q='${query}')`); + responseData = responseData.filter((item: IDataObject) => item.folder); + returnData.push.apply(returnData, responseData as IDataObject[]); + } + //https://docs.microsoft.com/en-us/onedrive/developer/rest-api/api/driveitem_createlink?view=odsp-graph-online + if (operation === 'share') { + const folderId = this.getNodeParameter('folderId', i) as string; + const type = this.getNodeParameter('type', i) as string; + const scope = this.getNodeParameter('scope', i) as string; + const body: IDataObject = { + type, + scope, + }; + responseData = await microsoftApiRequest.call(this, 'POST', `/drive/items/${folderId}/createLink`, body); + returnData.push(responseData); + } } - //https://docs.microsoft.com/en-us/onedrive/developer/rest-api/api/driveitem_list_children?view=odsp-graph-online - if (operation === 'getChildren') { - const folderId = this.getNodeParameter('folderId', i) as string; - responseData = await microsoftApiRequestAllItems.call(this, 'value', 'GET', `/drive/items/${folderId}/children`); - returnData.push.apply(returnData, responseData as IDataObject[]); - } - //https://docs.microsoft.com/en-us/onedrive/developer/rest-api/api/driveitem_search?view=odsp-graph-online - if (operation === 'search') { - const query = this.getNodeParameter('query', i) as string; - responseData = await microsoftApiRequestAllItems.call(this, 'value', 'GET', `/drive/root/search(q='${query}')`); - responseData = responseData.filter((item: IDataObject) => item.folder); - returnData.push.apply(returnData, responseData as IDataObject[]); - } - //https://docs.microsoft.com/en-us/onedrive/developer/rest-api/api/driveitem_createlink?view=odsp-graph-online - if (operation === 'share') { - const folderId = this.getNodeParameter('folderId', i) as string; - const type = this.getNodeParameter('type', i) as string; - const scope = this.getNodeParameter('scope', i) as string; - const body: IDataObject = { - type, - scope, - }; - responseData = await microsoftApiRequest.call(this, 'POST', `/drive/items/${folderId}/createLink`, body); - returnData.push(responseData); + } catch (error) { + if (this.continueOnFail()) { + if (resource === 'file' && operation === 'download') { + items[i].json = { error: error.message }; + } else { + returnData.push({ error: error.message }); + } + continue; } + throw error; } } if (resource === 'file' && operation === 'download') { diff --git a/packages/nodes-base/nodes/Microsoft/Outlook/MicrosoftOutlook.node.ts b/packages/nodes-base/nodes/Microsoft/Outlook/MicrosoftOutlook.node.ts index 1373ee6f41..86cf504b15 100644 --- a/packages/nodes-base/nodes/Microsoft/Outlook/MicrosoftOutlook.node.ts +++ b/packages/nodes-base/nodes/Microsoft/Outlook/MicrosoftOutlook.node.ts @@ -153,69 +153,93 @@ export class MicrosoftOutlook implements INodeType { if (['draft', 'message'].includes(resource)) { if (operation === 'delete') { for (let i = 0; i < length; i++) { - const messageId = this.getNodeParameter('messageId', i) as string; - responseData = await microsoftApiRequest.call( - this, - 'DELETE', - `/messages/${messageId}`, - ); + try { + const messageId = this.getNodeParameter('messageId', i) as string; + responseData = await microsoftApiRequest.call( + this, + 'DELETE', + `/messages/${messageId}`, + ); - returnData.push({ success: true }); + returnData.push({ success: true }); + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; + } } } if (operation === 'get') { for (let i = 0; i < length; i++) { - const messageId = this.getNodeParameter('messageId', i) as string; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + try { + const messageId = this.getNodeParameter('messageId', i) as string; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - if (additionalFields.fields) { - qs['$select'] = additionalFields.fields; - } + if (additionalFields.fields) { + qs['$select'] = additionalFields.fields; + } - if (additionalFields.filter) { - qs['$filter'] = additionalFields.filter; - } + if (additionalFields.filter) { + qs['$filter'] = additionalFields.filter; + } - responseData = await microsoftApiRequest.call( - this, - 'GET', - `/messages/${messageId}`, - undefined, - qs, - ); + responseData = await microsoftApiRequest.call( + this, + 'GET', + `/messages/${messageId}`, + undefined, + qs, + ); - if (additionalFields.dataPropertyAttachmentsPrefixName) { - const prefix = additionalFields.dataPropertyAttachmentsPrefixName as string; - const data = await downloadAttachments.call(this, responseData, prefix); - returnData.push.apply(returnData, data as unknown as IDataObject[]); - } else { - returnData.push(responseData); - } + if (additionalFields.dataPropertyAttachmentsPrefixName) { + const prefix = additionalFields.dataPropertyAttachmentsPrefixName as string; + const data = await downloadAttachments.call(this, responseData, prefix); + returnData.push.apply(returnData, data as unknown as IDataObject[]); + } else { + returnData.push(responseData); + } - if (additionalFields.dataPropertyAttachmentsPrefixName) { - return [returnData as INodeExecutionData[]]; + if (additionalFields.dataPropertyAttachmentsPrefixName) { + return [returnData as INodeExecutionData[]]; + } + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } } } if (operation === 'update') { for (let i = 0; i < length; i++) { - const messageId = this.getNodeParameter('messageId', i) as string; + try { + const messageId = this.getNodeParameter('messageId', i) as string; - const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; - // Create message from optional fields - const body: IDataObject = createMessage(updateFields); + // Create message from optional fields + const body: IDataObject = createMessage(updateFields); - responseData = await microsoftApiRequest.call( - this, - 'PATCH', - `/messages/${messageId}`, - body, - {}, - ); - returnData.push(responseData); + responseData = await microsoftApiRequest.call( + this, + 'PATCH', + `/messages/${messageId}`, + body, + {}, + ); + returnData.push(responseData); + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; + } } } } @@ -224,80 +248,95 @@ export class MicrosoftOutlook implements INodeType { if (operation === 'create') { for (let i = 0; i < length; i++) { + try { + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const subject = this.getNodeParameter('subject', i) as string; - const subject = this.getNodeParameter('subject', i) as string; + const bodyContent = this.getNodeParameter('bodyContent', i, '') as string; - const bodyContent = this.getNodeParameter('bodyContent', i, '') as string; + additionalFields.subject = subject; - additionalFields.subject = subject; + additionalFields.bodyContent = bodyContent || ' '; - additionalFields.bodyContent = bodyContent || ' '; + // Create message object from optional fields + const body: IDataObject = createMessage(additionalFields); - // Create message object from optional fields - const body: IDataObject = createMessage(additionalFields); + if (additionalFields.attachments) { + const attachments = (additionalFields.attachments as IDataObject).attachments as IDataObject[]; - if (additionalFields.attachments) { - const attachments = (additionalFields.attachments as IDataObject).attachments as IDataObject[]; + // // Handle attachments + body['attachments'] = attachments.map(attachment => { + const binaryPropertyName = attachment.binaryPropertyName as string; - // // Handle attachments - body['attachments'] = attachments.map(attachment => { - const binaryPropertyName = attachment.binaryPropertyName as string; + if (items[i].binary === undefined) { + throw new NodeOperationError(this.getNode(), 'No binary data exists on item!'); + } + //@ts-ignore + if (items[i].binary[binaryPropertyName] === undefined) { + throw new NodeOperationError(this.getNode(), `No binary data property "${binaryPropertyName}" does not exists on item!`); + } - if (items[i].binary === undefined) { - throw new NodeOperationError(this.getNode(), 'No binary data exists on item!'); - } - //@ts-ignore - if (items[i].binary[binaryPropertyName] === undefined) { - throw new NodeOperationError(this.getNode(), `No binary data property "${binaryPropertyName}" does not exists on item!`); - } + const binaryData = (items[i].binary as IBinaryKeyData)[binaryPropertyName]; + return { + '@odata.type': '#microsoft.graph.fileAttachment', + name: binaryData.fileName, + contentBytes: binaryData.data, + }; + }); + } - const binaryData = (items[i].binary as IBinaryKeyData)[binaryPropertyName]; - return { - '@odata.type': '#microsoft.graph.fileAttachment', - name: binaryData.fileName, - contentBytes: binaryData.data, - }; - }); + responseData = await microsoftApiRequest.call( + this, + 'POST', + `/messages`, + body, + {}, + ); + + returnData.push(responseData); + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } - - responseData = await microsoftApiRequest.call( - this, - 'POST', - `/messages`, - body, - {}, - ); - - returnData.push(responseData); } } if (operation === 'send') { for (let i = 0; i < length; i++) { - const messageId = this.getNodeParameter('messageId', i); - const additionalFields = this.getNodeParameter('additionalFields', i, {}) as IDataObject; + try { + const messageId = this.getNodeParameter('messageId', i); + const additionalFields = this.getNodeParameter('additionalFields', i, {}) as IDataObject; - if (additionalFields && additionalFields.recipients) { - const recipients = ((additionalFields.recipients as string).split(',') as string[]).filter(email => !!email); - if (recipients.length !== 0) { - await microsoftApiRequest.call( - this, - 'PATCH', - `/messages/${messageId}`, - { toRecipients: recipients.map((recipient: string) => makeRecipient(recipient)) }, - ); + if (additionalFields && additionalFields.recipients) { + const recipients = ((additionalFields.recipients as string).split(',') as string[]).filter(email => !!email); + if (recipients.length !== 0) { + await microsoftApiRequest.call( + this, + 'PATCH', + `/messages/${messageId}`, + { toRecipients: recipients.map((recipient: string) => makeRecipient(recipient)) }, + ); + } } + + responseData = await microsoftApiRequest.call( + this, + 'POST', + `/messages/${messageId}/send`, + ); + + returnData.push({ success: true }); + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } - - responseData = await microsoftApiRequest.call( - this, - 'POST', - `/messages/${messageId}/send`, - ); - - returnData.push({ success: true }); } } } @@ -306,162 +345,186 @@ export class MicrosoftOutlook implements INodeType { if (operation === 'reply') { for (let i = 0; i < length; i++) { - const messageId = this.getNodeParameter('messageId', i) as string; - const replyType = this.getNodeParameter('replyType', i) as string; - const comment = this.getNodeParameter('comment', i) as string; - const send = this.getNodeParameter('send', i, false) as boolean; - const additionalFields = this.getNodeParameter('additionalFields', i, {}) as IDataObject; + try { + const messageId = this.getNodeParameter('messageId', i) as string; + const replyType = this.getNodeParameter('replyType', i) as string; + const comment = this.getNodeParameter('comment', i) as string; + const send = this.getNodeParameter('send', i, false) as boolean; + const additionalFields = this.getNodeParameter('additionalFields', i, {}) as IDataObject; - const body: IDataObject = {}; + const body: IDataObject = {}; - let action = 'createReply'; - if (replyType === 'replyAll') { - body.comment = comment; - action = 'createReplyAll'; - } else { - body.comment = comment; - body.message = {}; - Object.assign(body.message, createMessage(additionalFields)); - //@ts-ignore - delete body.message.attachments; - } - - responseData = await microsoftApiRequest.call( - this, - 'POST', - `/messages/${messageId}/${action}`, - body, - ); - - if (additionalFields.attachments) { - const attachments = (additionalFields.attachments as IDataObject).attachments as IDataObject[]; - // // Handle attachments - const data = attachments.map(attachment => { - const binaryPropertyName = attachment.binaryPropertyName as string; - - if (items[i].binary === undefined) { - throw new NodeOperationError(this.getNode(), 'No binary data exists on item!'); - } + let action = 'createReply'; + if (replyType === 'replyAll') { + body.comment = comment; + action = 'createReplyAll'; + } else { + body.comment = comment; + body.message = {}; + Object.assign(body.message, createMessage(additionalFields)); //@ts-ignore - if (items[i].binary[binaryPropertyName] === undefined) { - throw new NodeOperationError(this.getNode(), `No binary data property "${binaryPropertyName}" does not exists on item!`); + delete body.message.attachments; + } + + responseData = await microsoftApiRequest.call( + this, + 'POST', + `/messages/${messageId}/${action}`, + body, + ); + + if (additionalFields.attachments) { + const attachments = (additionalFields.attachments as IDataObject).attachments as IDataObject[]; + // // Handle attachments + const data = attachments.map(attachment => { + const binaryPropertyName = attachment.binaryPropertyName as string; + + if (items[i].binary === undefined) { + throw new NodeOperationError(this.getNode(), 'No binary data exists on item!'); + } + //@ts-ignore + if (items[i].binary[binaryPropertyName] === undefined) { + throw new NodeOperationError(this.getNode(), `No binary data property "${binaryPropertyName}" does not exists on item!`); + } + + const binaryData = (items[i].binary as IBinaryKeyData)[binaryPropertyName]; + return { + '@odata.type': '#microsoft.graph.fileAttachment', + name: binaryData.fileName, + contentBytes: binaryData.data, + }; + }); + + for (const attachment of data) { + await microsoftApiRequest.call( + this, + 'POST', + `/messages/${responseData.id}/attachments`, + attachment, + {}, + ); } + } - const binaryData = (items[i].binary as IBinaryKeyData)[binaryPropertyName]; - return { - '@odata.type': '#microsoft.graph.fileAttachment', - name: binaryData.fileName, - contentBytes: binaryData.data, - }; - }); - - for (const attachment of data) { + if (send === true) { await microsoftApiRequest.call( this, 'POST', - `/messages/${responseData.id}/attachments`, - attachment, - {}, + `/messages/${responseData.id}/send`, ); } - } - if (send === true) { - await microsoftApiRequest.call( - this, - 'POST', - `/messages/${responseData.id}/send`, - ); + returnData.push(responseData); + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } - - returnData.push(responseData); } } if (operation === 'getMime') { for (let i = 0; i < length; i++) { - const messageId = this.getNodeParameter('messageId', i) as string; - const dataPropertyNameDownload = this.getNodeParameter('binaryPropertyName', i) as string; - const response = await microsoftApiRequest.call( - this, - 'GET', - `/messages/${messageId}/$value`, - undefined, - {}, - undefined, - {}, - { encoding: null, resolveWithFullResponse: true }, - ); + try { + const messageId = this.getNodeParameter('messageId', i) as string; + const dataPropertyNameDownload = this.getNodeParameter('binaryPropertyName', i) as string; + const response = await microsoftApiRequest.call( + this, + 'GET', + `/messages/${messageId}/$value`, + undefined, + {}, + undefined, + {}, + { encoding: null, resolveWithFullResponse: true }, + ); - let mimeType: string | undefined; - if (response.headers['content-type']) { - mimeType = response.headers['content-type']; + let mimeType: string | undefined; + if (response.headers['content-type']) { + mimeType = response.headers['content-type']; + } + + const newItem: INodeExecutionData = { + json: items[i].json, + binary: {}, + }; + + if (items[i].binary !== undefined) { + // Create a shallow copy of the binary data so that the old + // data references which do not get changed still stay behind + // but the incoming data does not get changed. + Object.assign(newItem.binary, items[i].binary); + } + + items[i] = newItem; + + + const fileName = `${messageId}.eml`; + const data = Buffer.from(response.body as string, 'utf8'); + items[i].binary![dataPropertyNameDownload] = await this.helpers.prepareBinaryData(data as unknown as Buffer, fileName, mimeType); + } catch (error) { + if (this.continueOnFail()) { + items[i].json = { error: error.message }; + continue; + } + throw error; } - - const newItem: INodeExecutionData = { - json: items[i].json, - binary: {}, - }; - - if (items[i].binary !== undefined) { - // Create a shallow copy of the binary data so that the old - // data references which do not get changed still stay behind - // but the incoming data does not get changed. - Object.assign(newItem.binary, items[i].binary); - } - - items[i] = newItem; - - - const fileName = `${messageId}.eml`; - const data = Buffer.from(response.body as string, 'utf8'); - items[i].binary![dataPropertyNameDownload] = await this.helpers.prepareBinaryData(data as unknown as Buffer, fileName, mimeType); } } if (operation === 'getAll') { let additionalFields: IDataObject = {}; for (let i = 0; i < length; i++) { - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + try { + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - if (additionalFields.fields) { - qs['$select'] = additionalFields.fields; - } + if (additionalFields.fields) { + qs['$select'] = additionalFields.fields; + } - if (additionalFields.filter) { - qs['$filter'] = additionalFields.filter; - } + if (additionalFields.filter) { + qs['$filter'] = additionalFields.filter; + } - const endpoint = '/messages'; + const endpoint = '/messages'; - if (returnAll === true) { - responseData = await microsoftApiRequestAllItems.call( - this, - 'value', - 'GET', - endpoint, - undefined, - qs, - ); - } else { - qs['$top'] = this.getNodeParameter('limit', i) as number; - responseData = await microsoftApiRequest.call( - this, - 'GET', - endpoint, - undefined, - qs, - ); - responseData = responseData.value; - } + if (returnAll === true) { + responseData = await microsoftApiRequestAllItems.call( + this, + 'value', + 'GET', + endpoint, + undefined, + qs, + ); + } else { + qs['$top'] = this.getNodeParameter('limit', i) as number; + responseData = await microsoftApiRequest.call( + this, + 'GET', + endpoint, + undefined, + qs, + ); + responseData = responseData.value; + } - if (additionalFields.dataPropertyAttachmentsPrefixName) { - const prefix = additionalFields.dataPropertyAttachmentsPrefixName as string; - const data = await downloadAttachments.call(this, responseData, prefix); - returnData.push.apply(returnData, data as unknown as IDataObject[]); - } else { - returnData.push.apply(returnData, responseData); + if (additionalFields.dataPropertyAttachmentsPrefixName) { + const prefix = additionalFields.dataPropertyAttachmentsPrefixName as string; + const data = await downloadAttachments.call(this, responseData, prefix); + returnData.push.apply(returnData, data as unknown as IDataObject[]); + } else { + returnData.push.apply(returnData, responseData); + } + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } } @@ -472,81 +535,97 @@ export class MicrosoftOutlook implements INodeType { if (operation === 'move') { for (let i = 0; i < length; i++) { - const messageId = this.getNodeParameter('messageId', i) as string; - const destinationId = this.getNodeParameter('folderId', i) as string; - const body: IDataObject = { - destinationId, - }; + try { + const messageId = this.getNodeParameter('messageId', i) as string; + const destinationId = this.getNodeParameter('folderId', i) as string; + const body: IDataObject = { + destinationId, + }; - responseData = await microsoftApiRequest.call( - this, - 'POST', - `/messages/${messageId}/move`, - body, - ); - returnData.push({ success: true }); + responseData = await microsoftApiRequest.call( + this, + 'POST', + `/messages/${messageId}/move`, + body, + ); + returnData.push({ success: true }); + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; + } } } if (operation === 'send') { for (let i = 0; i < length; i++) { - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + try { + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const toRecipients = this.getNodeParameter('toRecipients', i) as string; + const toRecipients = this.getNodeParameter('toRecipients', i) as string; - const subject = this.getNodeParameter('subject', i) as string; + const subject = this.getNodeParameter('subject', i) as string; - const bodyContent = this.getNodeParameter('bodyContent', i, '') as string; + const bodyContent = this.getNodeParameter('bodyContent', i, '') as string; - additionalFields.subject = subject; + additionalFields.subject = subject; - additionalFields.bodyContent = bodyContent || ' '; + additionalFields.bodyContent = bodyContent || ' '; - additionalFields.toRecipients = toRecipients; + additionalFields.toRecipients = toRecipients; - const saveToSentItems = additionalFields.saveToSentItems === undefined ? true : additionalFields.saveToSentItems; - delete additionalFields.saveToSentItems; + const saveToSentItems = additionalFields.saveToSentItems === undefined ? true : additionalFields.saveToSentItems; + delete additionalFields.saveToSentItems; - // Create message object from optional fields - const message: IDataObject = createMessage(additionalFields); + // Create message object from optional fields + const message: IDataObject = createMessage(additionalFields); - if (additionalFields.attachments) { - const attachments = (additionalFields.attachments as IDataObject).attachments as IDataObject[]; + if (additionalFields.attachments) { + const attachments = (additionalFields.attachments as IDataObject).attachments as IDataObject[]; - // // Handle attachments - message['attachments'] = attachments.map(attachment => { - const binaryPropertyName = attachment.binaryPropertyName as string; + // // Handle attachments + message['attachments'] = attachments.map(attachment => { + const binaryPropertyName = attachment.binaryPropertyName as string; - if (items[i].binary === undefined) { - throw new NodeOperationError(this.getNode(), 'No binary data exists on item!'); - } - //@ts-ignore - if (items[i].binary[binaryPropertyName] === undefined) { - throw new NodeOperationError(this.getNode(), `No binary data property "${binaryPropertyName}" does not exists on item!`); - } + if (items[i].binary === undefined) { + throw new NodeOperationError(this.getNode(), 'No binary data exists on item!'); + } + //@ts-ignore + if (items[i].binary[binaryPropertyName] === undefined) { + throw new NodeOperationError(this.getNode(), `No binary data property "${binaryPropertyName}" does not exists on item!`); + } - const binaryData = (items[i].binary as IBinaryKeyData)[binaryPropertyName]; - return { - '@odata.type': '#microsoft.graph.fileAttachment', - name: binaryData.fileName, - contentBytes: binaryData.data, - }; - }); + const binaryData = (items[i].binary as IBinaryKeyData)[binaryPropertyName]; + return { + '@odata.type': '#microsoft.graph.fileAttachment', + name: binaryData.fileName, + contentBytes: binaryData.data, + }; + }); + } + + const body: IDataObject = { + message, + saveToSentItems, + }; + + responseData = await microsoftApiRequest.call( + this, + 'POST', + `/sendMail`, + body, + {}, + ); + returnData.push({ success: true }); + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } - - const body: IDataObject = { - message, - saveToSentItems, - }; - - responseData = await microsoftApiRequest.call( - this, - 'POST', - `/sendMail`, - body, - {}, - ); - returnData.push({ success: true }); } } @@ -555,201 +634,233 @@ export class MicrosoftOutlook implements INodeType { if (resource === 'messageAttachment') { if (operation === 'add') { for (let i = 0; i < length; i++) { - const messageId = this.getNodeParameter('messageId', i) as string; - const binaryPropertyName = this.getNodeParameter('binaryPropertyName', 0) as string; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + try { + const messageId = this.getNodeParameter('messageId', i) as string; + const binaryPropertyName = this.getNodeParameter('binaryPropertyName', 0) as string; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - if (items[i].binary === undefined) { - throw new NodeOperationError(this.getNode(), 'No binary data exists on item!'); - } - //@ts-ignore - if (items[i].binary[binaryPropertyName] === undefined) { - throw new NodeOperationError(this.getNode(), `No binary data property "${binaryPropertyName}" does not exists on item!`); - } + if (items[i].binary === undefined) { + throw new NodeOperationError(this.getNode(), 'No binary data exists on item!'); + } + //@ts-ignore + if (items[i].binary[binaryPropertyName] === undefined) { + throw new NodeOperationError(this.getNode(), `No binary data property "${binaryPropertyName}" does not exists on item!`); + } - const binaryData = (items[i].binary as IBinaryKeyData)[binaryPropertyName]; - const dataBuffer = Buffer.from(binaryData.data, 'base64'); + const binaryData = (items[i].binary as IBinaryKeyData)[binaryPropertyName]; + const dataBuffer = Buffer.from(binaryData.data, 'base64'); - const fileName = additionalFields.fileName === undefined ? binaryData.fileName : additionalFields.fileName; + const fileName = additionalFields.fileName === undefined ? binaryData.fileName : additionalFields.fileName; - if (!fileName) { - throw new NodeOperationError(this.getNode(), 'File name is not set. It has either to be set via "Additional Fields" or has to be set on the binary property!'); - } + if (!fileName) { + throw new NodeOperationError(this.getNode(), 'File name is not set. It has either to be set via "Additional Fields" or has to be set on the binary property!'); + } - // Check if the file is over 3MB big - if (dataBuffer.length > 3e6) { - // Maximum chunk size is 4MB - const chunkSize = 4e6; - const body: IDataObject = { - AttachmentItem: { - attachmentType: 'file', + // Check if the file is over 3MB big + if (dataBuffer.length > 3e6) { + // Maximum chunk size is 4MB + const chunkSize = 4e6; + const body: IDataObject = { + AttachmentItem: { + attachmentType: 'file', + name: fileName, + size: dataBuffer.length, + }, + }; + + // Create upload session + responseData = await microsoftApiRequest.call( + this, + 'POST', + `/messages/${messageId}/attachments/createUploadSession`, + body, + ); + const uploadUrl = responseData.uploadUrl; + + if (uploadUrl === undefined) { + throw new NodeApiError(this.getNode(), responseData, { message: 'Failed to get upload session' }); + } + + for (let bytesUploaded = 0; bytesUploaded < dataBuffer.length; bytesUploaded += chunkSize) { + // Upload the file chunk by chunk + const nextChunk = Math.min(bytesUploaded + chunkSize, dataBuffer.length); + const contentRange = `bytes ${bytesUploaded}-${nextChunk - 1}/${dataBuffer.length}`; + + const data = dataBuffer.subarray(bytesUploaded, nextChunk); + + responseData = await this.helpers.request( + uploadUrl, + { + method: 'PUT', + headers: { + 'Content-Type': 'application/octet-stream', + 'Content-Length': data.length, + 'Content-Range': contentRange, + }, + body: data, + }); + } + } else { + const body: IDataObject = { + '@odata.type': '#microsoft.graph.fileAttachment', name: fileName, - size: dataBuffer.length, - }, - }; + contentBytes: binaryData.data, + }; - // Create upload session - responseData = await microsoftApiRequest.call( - this, - 'POST', - `/messages/${messageId}/attachments/createUploadSession`, - body, - ); - const uploadUrl = responseData.uploadUrl; - - if (uploadUrl === undefined) { - throw new NodeApiError(this.getNode(), responseData, { message: 'Failed to get upload session' }); + responseData = await microsoftApiRequest.call( + this, + 'POST', + `/messages/${messageId}/attachments`, + body, + {}, + ); } - - for (let bytesUploaded = 0; bytesUploaded < dataBuffer.length; bytesUploaded += chunkSize) { - // Upload the file chunk by chunk - const nextChunk = Math.min(bytesUploaded + chunkSize, dataBuffer.length); - const contentRange = `bytes ${bytesUploaded}-${nextChunk - 1}/${dataBuffer.length}`; - - const data = dataBuffer.subarray(bytesUploaded, nextChunk); - - responseData = await this.helpers.request( - uploadUrl, - { - method: 'PUT', - headers: { - 'Content-Type': 'application/octet-stream', - 'Content-Length': data.length, - 'Content-Range': contentRange, - }, - body: data, - }); + returnData.push({ success: true }); + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; } - } else { - const body: IDataObject = { - '@odata.type': '#microsoft.graph.fileAttachment', - name: fileName, - contentBytes: binaryData.data, - }; - - responseData = await microsoftApiRequest.call( - this, - 'POST', - `/messages/${messageId}/attachments`, - body, - {}, - ); + throw error; } - returnData.push({ success: true }); } } if (operation === 'download') { for (let i = 0; i < length; i++) { - const messageId = this.getNodeParameter('messageId', i) as string; - const attachmentId = this.getNodeParameter('attachmentId', i) as string; - const dataPropertyNameDownload = this.getNodeParameter('binaryPropertyName', i) as string; + try { + const messageId = this.getNodeParameter('messageId', i) as string; + const attachmentId = this.getNodeParameter('attachmentId', i) as string; + const dataPropertyNameDownload = this.getNodeParameter('binaryPropertyName', i) as string; - // Get attachment details first - const attachmentDetails = await microsoftApiRequest.call( - this, - 'GET', - `/messages/${messageId}/attachments/${attachmentId}`, - undefined, - { '$select': 'id,name,contentType' }, - ); + // Get attachment details first + const attachmentDetails = await microsoftApiRequest.call( + this, + 'GET', + `/messages/${messageId}/attachments/${attachmentId}`, + undefined, + { '$select': 'id,name,contentType' }, + ); - let mimeType: string | undefined; - if (attachmentDetails.contentType) { - mimeType = attachmentDetails.contentType; + let mimeType: string | undefined; + if (attachmentDetails.contentType) { + mimeType = attachmentDetails.contentType; + } + const fileName = attachmentDetails.name; + + const response = await microsoftApiRequest.call( + this, + 'GET', + `/messages/${messageId}/attachments/${attachmentId}/$value`, + undefined, + {}, + undefined, + {}, + { encoding: null, resolveWithFullResponse: true }, + ); + + const newItem: INodeExecutionData = { + json: items[i].json, + binary: {}, + }; + + if (items[i].binary !== undefined) { + // Create a shallow copy of the binary data so that the old + // data references which do not get changed still stay behind + // but the incoming data does not get changed. + Object.assign(newItem.binary, items[i].binary); + } + + items[i] = newItem; + const data = Buffer.from(response.body as string, 'utf8'); + items[i].binary![dataPropertyNameDownload] = await this.helpers.prepareBinaryData(data as unknown as Buffer, fileName, mimeType); + } catch (error) { + if (this.continueOnFail()) { + items[i].json = { error: error.message }; + continue; + } + throw error; } - const fileName = attachmentDetails.name; - - const response = await microsoftApiRequest.call( - this, - 'GET', - `/messages/${messageId}/attachments/${attachmentId}/$value`, - undefined, - {}, - undefined, - {}, - { encoding: null, resolveWithFullResponse: true }, - ); - - const newItem: INodeExecutionData = { - json: items[i].json, - binary: {}, - }; - - if (items[i].binary !== undefined) { - // Create a shallow copy of the binary data so that the old - // data references which do not get changed still stay behind - // but the incoming data does not get changed. - Object.assign(newItem.binary, items[i].binary); - } - - items[i] = newItem; - const data = Buffer.from(response.body as string, 'utf8'); - items[i].binary![dataPropertyNameDownload] = await this.helpers.prepareBinaryData(data as unknown as Buffer, fileName, mimeType); } } if (operation === 'get') { for (let i = 0; i < length; i++) { - const messageId = this.getNodeParameter('messageId', i) as string; - const attachmentId = this.getNodeParameter('attachmentId', i) as string; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + try { + const messageId = this.getNodeParameter('messageId', i) as string; + const attachmentId = this.getNodeParameter('attachmentId', i) as string; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - // Have sane defaults so we don't fetch attachment data in this operation - qs['$select'] = 'id,lastModifiedDateTime,name,contentType,size,isInline'; - if (additionalFields.fields) { - qs['$select'] = additionalFields.fields; + // Have sane defaults so we don't fetch attachment data in this operation + qs['$select'] = 'id,lastModifiedDateTime,name,contentType,size,isInline'; + if (additionalFields.fields) { + qs['$select'] = additionalFields.fields; + } + + responseData = await microsoftApiRequest.call( + this, + 'GET', + `/messages/${messageId}/attachments/${attachmentId}`, + undefined, + qs, + ); + returnData.push(responseData); + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } - - responseData = await microsoftApiRequest.call( - this, - 'GET', - `/messages/${messageId}/attachments/${attachmentId}`, - undefined, - qs, - ); - returnData.push(responseData); } } if (operation === 'getAll') { for (let i = 0; i < length; i++) { - const messageId = this.getNodeParameter('messageId', i) as string; - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + try { + const messageId = this.getNodeParameter('messageId', i) as string; + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - // Have sane defaults so we don't fetch attachment data in this operation - qs['$select'] = 'id,lastModifiedDateTime,name,contentType,size,isInline'; - if (additionalFields.fields) { - qs['$select'] = additionalFields.fields; - } + // Have sane defaults so we don't fetch attachment data in this operation + qs['$select'] = 'id,lastModifiedDateTime,name,contentType,size,isInline'; + if (additionalFields.fields) { + qs['$select'] = additionalFields.fields; + } - if (additionalFields.filter) { - qs['$filter'] = additionalFields.filter; - } + if (additionalFields.filter) { + qs['$filter'] = additionalFields.filter; + } - const endpoint = `/messages/${messageId}/attachments`; - if (returnAll === true) { - responseData = await microsoftApiRequestAllItems.call( - this, - 'value', - 'GET', - endpoint, - undefined, - qs, - ); - } else { - qs['$top'] = this.getNodeParameter('limit', i) as number; - responseData = await microsoftApiRequest.call( - this, - 'GET', - endpoint, - undefined, - qs, - ); - responseData = responseData.value; + const endpoint = `/messages/${messageId}/attachments`; + if (returnAll === true) { + responseData = await microsoftApiRequestAllItems.call( + this, + 'value', + 'GET', + endpoint, + undefined, + qs, + ); + } else { + qs['$top'] = this.getNodeParameter('limit', i) as number; + responseData = await microsoftApiRequest.call( + this, + 'GET', + endpoint, + undefined, + qs, + ); + responseData = responseData.value; + } + returnData.push.apply(returnData, responseData as IDataObject[]); + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } - returnData.push.apply(returnData, responseData as IDataObject[]); } } } @@ -757,204 +868,260 @@ export class MicrosoftOutlook implements INodeType { if (resource === 'folder') { if (operation === 'create') { for (let i = 0; i < length; i++) { - const displayName = this.getNodeParameter('displayName', i) as string; - const folderType = this.getNodeParameter('folderType', i) as string; - const body: IDataObject = { - displayName, - }; + try { + const displayName = this.getNodeParameter('displayName', i) as string; + const folderType = this.getNodeParameter('folderType', i) as string; + const body: IDataObject = { + displayName, + }; - let endpoint = '/mailFolders'; + let endpoint = '/mailFolders'; - if (folderType === 'searchFolder') { - endpoint = '/mailFolders/searchfolders/childFolders'; - const includeNestedFolders = this.getNodeParameter('includeNestedFolders', i); - const sourceFolderIds = this.getNodeParameter('sourceFolderIds', i); - const filterQuery = this.getNodeParameter('filterQuery', i); - Object.assign(body, { - '@odata.type': 'microsoft.graph.mailSearchFolder', - includeNestedFolders, - sourceFolderIds, - filterQuery, - }); + if (folderType === 'searchFolder') { + endpoint = '/mailFolders/searchfolders/childFolders'; + const includeNestedFolders = this.getNodeParameter('includeNestedFolders', i); + const sourceFolderIds = this.getNodeParameter('sourceFolderIds', i); + const filterQuery = this.getNodeParameter('filterQuery', i); + Object.assign(body, { + '@odata.type': 'microsoft.graph.mailSearchFolder', + includeNestedFolders, + sourceFolderIds, + filterQuery, + }); + } + + responseData = await microsoftApiRequest.call( + this, + 'POST', + endpoint, + body, + ); + returnData.push(responseData); + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } - - responseData = await microsoftApiRequest.call( - this, - 'POST', - endpoint, - body, - ); - returnData.push(responseData); } } if (operation === 'delete') { for (let i = 0; i < length; i++) { - const folderId = this.getNodeParameter('folderId', i) as string; - responseData = await microsoftApiRequest.call( - this, - 'DELETE', - `/mailFolders/${folderId}`, - ); - returnData.push({ success: true }); + try { + const folderId = this.getNodeParameter('folderId', i) as string; + responseData = await microsoftApiRequest.call( + this, + 'DELETE', + `/mailFolders/${folderId}`, + ); + returnData.push({ success: true }); + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; + } } } if (operation === 'get') { for (let i = 0; i < length; i++) { - const folderId = this.getNodeParameter('folderId', i) as string; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + try { + const folderId = this.getNodeParameter('folderId', i) as string; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - if (additionalFields.fields) { - qs['$select'] = additionalFields.fields; - } + if (additionalFields.fields) { + qs['$select'] = additionalFields.fields; + } - if (additionalFields.filter) { - qs['$filter'] = additionalFields.filter; + if (additionalFields.filter) { + qs['$filter'] = additionalFields.filter; + } + responseData = await microsoftApiRequest.call( + this, + 'GET', + `/mailFolders/${folderId}`, + {}, + qs, + ); + returnData.push(responseData); + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } - responseData = await microsoftApiRequest.call( - this, - 'GET', - `/mailFolders/${folderId}`, - {}, - qs, - ); - returnData.push(responseData); } } if (operation === 'getAll') { for (let i = 0; i < length; i++) { - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + try { + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - if (additionalFields.fields) { - qs['$select'] = additionalFields.fields; - } + if (additionalFields.fields) { + qs['$select'] = additionalFields.fields; + } - if (additionalFields.filter) { - qs['$filter'] = additionalFields.filter; - } + if (additionalFields.filter) { + qs['$filter'] = additionalFields.filter; + } - if (returnAll === true) { - responseData = await microsoftApiRequestAllItems.call( - this, - 'value', - 'GET', - '/mailFolders', - {}, - qs, - ); - } else { - qs['$top'] = this.getNodeParameter('limit', i) as number; - responseData = await microsoftApiRequest.call( - this, - 'GET', - '/mailFolders', - {}, - qs, - ); - responseData = responseData.value; + if (returnAll === true) { + responseData = await microsoftApiRequestAllItems.call( + this, + 'value', + 'GET', + '/mailFolders', + {}, + qs, + ); + } else { + qs['$top'] = this.getNodeParameter('limit', i) as number; + responseData = await microsoftApiRequest.call( + this, + 'GET', + '/mailFolders', + {}, + qs, + ); + responseData = responseData.value; + } + returnData.push.apply(returnData, responseData as IDataObject[]); + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } - returnData.push.apply(returnData, responseData as IDataObject[]); } } if (operation === 'getChildren') { for (let i = 0; i < length; i++) { - const folderId = this.getNodeParameter('folderId', i) as string; - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + try { + const folderId = this.getNodeParameter('folderId', i) as string; + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - if (additionalFields.fields) { - qs['$select'] = additionalFields.fields; - } + if (additionalFields.fields) { + qs['$select'] = additionalFields.fields; + } - if (additionalFields.filter) { - qs['$filter'] = additionalFields.filter; - } + if (additionalFields.filter) { + qs['$filter'] = additionalFields.filter; + } - if (returnAll) { - responseData = await microsoftApiRequestAllItems.call( - this, - 'value', - 'GET', - `/mailFolders/${folderId}/childFolders`, - qs, - ); - } else { - qs['$top'] = this.getNodeParameter('limit', i) as number; - responseData = await microsoftApiRequest.call( - this, - 'GET', - `/mailFolders/${folderId}/childFolders`, - undefined, - qs, - ); - responseData = responseData.value; + if (returnAll) { + responseData = await microsoftApiRequestAllItems.call( + this, + 'value', + 'GET', + `/mailFolders/${folderId}/childFolders`, + qs, + ); + } else { + qs['$top'] = this.getNodeParameter('limit', i) as number; + responseData = await microsoftApiRequest.call( + this, + 'GET', + `/mailFolders/${folderId}/childFolders`, + undefined, + qs, + ); + responseData = responseData.value; + } + returnData.push.apply(returnData, responseData as IDataObject[]); + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } - returnData.push.apply(returnData, responseData as IDataObject[]); } } if (operation === 'update') { for (let i = 0; i < length; i++) { - const folderId = this.getNodeParameter('folderId', i) as string; - const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + try { + const folderId = this.getNodeParameter('folderId', i) as string; + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; - const body: IDataObject = { - ...updateFields, - }; + const body: IDataObject = { + ...updateFields, + }; - responseData = await microsoftApiRequest.call( - this, - 'PATCH', - `/mailFolders/${folderId}`, - body, - ); - returnData.push(responseData); + responseData = await microsoftApiRequest.call( + this, + 'PATCH', + `/mailFolders/${folderId}`, + body, + ); + returnData.push(responseData); + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; + } } } } if (resource === 'folderMessage') { for (let i = 0; i < length; i++) { - if (operation === 'getAll') { - const folderId = this.getNodeParameter('folderId', i) as string; - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + try { + if (operation === 'getAll') { + const folderId = this.getNodeParameter('folderId', i) as string; + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - if (additionalFields.fields) { - qs['$select'] = additionalFields.fields; - } + if (additionalFields.fields) { + qs['$select'] = additionalFields.fields; + } - if (additionalFields.filter) { - qs['$filter'] = additionalFields.filter; - } + if (additionalFields.filter) { + qs['$filter'] = additionalFields.filter; + } - const endpoint = `/mailFolders/${folderId}/messages`; - if (returnAll) { - responseData = await microsoftApiRequestAllItems.call( - this, - 'value', - 'GET', - endpoint, - qs, - ); + const endpoint = `/mailFolders/${folderId}/messages`; + if (returnAll) { + responseData = await microsoftApiRequestAllItems.call( + this, + 'value', + 'GET', + endpoint, + qs, + ); + } + else { + qs['$top'] = this.getNodeParameter('limit', i) as number; + responseData = await microsoftApiRequest.call( + this, + 'GET', + endpoint, + undefined, + qs, + ); + responseData = responseData.value; + } + returnData.push.apply(returnData, responseData as IDataObject[]); } - else { - qs['$top'] = this.getNodeParameter('limit', i) as number; - responseData = await microsoftApiRequest.call( - this, - 'GET', - endpoint, - undefined, - qs, - ); - responseData = responseData.value; + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } - returnData.push.apply(returnData, responseData as IDataObject[]); - } } } diff --git a/packages/nodes-base/nodes/Microsoft/Teams/MicrosoftTeams.node.ts b/packages/nodes-base/nodes/Microsoft/Teams/MicrosoftTeams.node.ts index c6dfb2665a..b131163128 100644 --- a/packages/nodes-base/nodes/Microsoft/Teams/MicrosoftTeams.node.ts +++ b/packages/nodes-base/nodes/Microsoft/Teams/MicrosoftTeams.node.ts @@ -202,188 +202,196 @@ export class MicrosoftTeams implements INodeType { 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 === 'channel') { - //https://docs.microsoft.com/en-us/graph/api/channel-post?view=graph-rest-beta&tabs=http - if (operation === 'create') { - const teamId = this.getNodeParameter('teamId', i) as string; - const name = this.getNodeParameter('name', i) as string; - const options = this.getNodeParameter('options', i) as IDataObject; - const body: IDataObject = { - displayName: name, - }; - if (options.description) { - body.description = options.description as string; + try { + if (resource === 'channel') { + //https://docs.microsoft.com/en-us/graph/api/channel-post?view=graph-rest-beta&tabs=http + if (operation === 'create') { + const teamId = this.getNodeParameter('teamId', i) as string; + const name = this.getNodeParameter('name', i) as string; + const options = this.getNodeParameter('options', i) as IDataObject; + const body: IDataObject = { + displayName: name, + }; + if (options.description) { + body.description = options.description as string; + } + if (options.type) { + body.membershipType = options.type as string; + } + responseData = await microsoftApiRequest.call(this, 'POST', `/v1.0/teams/${teamId}/channels`, body); } - if (options.type) { - body.membershipType = options.type as string; + //https://docs.microsoft.com/en-us/graph/api/channel-delete?view=graph-rest-beta&tabs=http + if (operation === 'delete') { + const teamId = this.getNodeParameter('teamId', i) as string; + const channelId = this.getNodeParameter('channelId', i) as string; + responseData = await microsoftApiRequest.call(this, 'DELETE', `/v1.0/teams/${teamId}/channels/${channelId}`); + responseData = { success: true }; } - responseData = await microsoftApiRequest.call(this, 'POST', `/v1.0/teams/${teamId}/channels`, body); - } - //https://docs.microsoft.com/en-us/graph/api/channel-delete?view=graph-rest-beta&tabs=http - if (operation === 'delete') { - const teamId = this.getNodeParameter('teamId', i) as string; - const channelId = this.getNodeParameter('channelId', i) as string; - responseData = await microsoftApiRequest.call(this, 'DELETE', `/v1.0/teams/${teamId}/channels/${channelId}`); - responseData = { success: true }; - } - //https://docs.microsoft.com/en-us/graph/api/channel-get?view=graph-rest-beta&tabs=http - if (operation === 'get') { - const teamId = this.getNodeParameter('teamId', i) as string; - const channelId = this.getNodeParameter('channelId', i) as string; - responseData = await microsoftApiRequest.call(this, 'GET', `/v1.0/teams/${teamId}/channels/${channelId}`); - } - //https://docs.microsoft.com/en-us/graph/api/channel-list?view=graph-rest-beta&tabs=http - if (operation === 'getAll') { - const teamId = this.getNodeParameter('teamId', i) as string; - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - if (returnAll) { - responseData = await microsoftApiRequestAllItems.call(this, 'value', 'GET', `/v1.0/teams/${teamId}/channels`); - } else { - qs.limit = this.getNodeParameter('limit', i) as number; - responseData = await microsoftApiRequestAllItems.call(this, 'value', 'GET', `/v1.0/teams/${teamId}/channels`, {}); - responseData = responseData.splice(0, qs.limit); + //https://docs.microsoft.com/en-us/graph/api/channel-get?view=graph-rest-beta&tabs=http + if (operation === 'get') { + const teamId = this.getNodeParameter('teamId', i) as string; + const channelId = this.getNodeParameter('channelId', i) as string; + responseData = await microsoftApiRequest.call(this, 'GET', `/v1.0/teams/${teamId}/channels/${channelId}`); + } + //https://docs.microsoft.com/en-us/graph/api/channel-list?view=graph-rest-beta&tabs=http + if (operation === 'getAll') { + const teamId = this.getNodeParameter('teamId', i) as string; + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + if (returnAll) { + responseData = await microsoftApiRequestAllItems.call(this, 'value', 'GET', `/v1.0/teams/${teamId}/channels`); + } else { + qs.limit = this.getNodeParameter('limit', i) as number; + responseData = await microsoftApiRequestAllItems.call(this, 'value', 'GET', `/v1.0/teams/${teamId}/channels`, {}); + responseData = responseData.splice(0, qs.limit); + } + } + //https://docs.microsoft.com/en-us/graph/api/channel-patch?view=graph-rest-beta&tabs=http + if (operation === 'update') { + const teamId = this.getNodeParameter('teamId', i) as string; + const channelId = this.getNodeParameter('channelId', i) as string; + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + const body: IDataObject = {}; + if (updateFields.name) { + body.displayName = updateFields.name as string; + } + if (updateFields.description) { + body.description = updateFields.description as string; + } + responseData = await microsoftApiRequest.call(this, 'PATCH', `/v1.0/teams/${teamId}/channels/${channelId}`, body); + responseData = { success: true }; } } - //https://docs.microsoft.com/en-us/graph/api/channel-patch?view=graph-rest-beta&tabs=http - if (operation === 'update') { - const teamId = this.getNodeParameter('teamId', i) as string; - const channelId = this.getNodeParameter('channelId', i) as string; - const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; - const body: IDataObject = {}; - if (updateFields.name) { - body.displayName = updateFields.name as string; - } - if (updateFields.description) { - body.description = updateFields.description as string; - } - responseData = await microsoftApiRequest.call(this, 'PATCH', `/v1.0/teams/${teamId}/channels/${channelId}`, body); - responseData = { success: true }; - } - } - if (resource === 'channelMessage') { - //https://docs.microsoft.com/en-us/graph/api/channel-post-messages?view=graph-rest-beta&tabs=http - //https://docs.microsoft.com/en-us/graph/api/channel-post-messagereply?view=graph-rest-beta&tabs=http - if (operation === 'create') { - const teamId = this.getNodeParameter('teamId', i) as string; - const channelId = this.getNodeParameter('channelId', i) as string; - const messageType = this.getNodeParameter('messageType', i) as string; - const message = this.getNodeParameter('message', i) as string; - const options = this.getNodeParameter('options', i) as IDataObject; + if (resource === 'channelMessage') { + //https://docs.microsoft.com/en-us/graph/api/channel-post-messages?view=graph-rest-beta&tabs=http + //https://docs.microsoft.com/en-us/graph/api/channel-post-messagereply?view=graph-rest-beta&tabs=http + if (operation === 'create') { + const teamId = this.getNodeParameter('teamId', i) as string; + const channelId = this.getNodeParameter('channelId', i) as string; + const messageType = this.getNodeParameter('messageType', i) as string; + const message = this.getNodeParameter('message', i) as string; + const options = this.getNodeParameter('options', i) as IDataObject; - const body: IDataObject = { - body: { - contentType: messageType, - content: message, - }, - }; - - if (options.makeReply) { - const replyToId = options.makeReply as string; - responseData = await microsoftApiRequest.call(this, 'POST', `/beta/teams/${teamId}/channels/${channelId}/messages/${replyToId}/replies`, body); - } else { - responseData = await microsoftApiRequest.call(this, 'POST', `/beta/teams/${teamId}/channels/${channelId}/messages`, body); - } - } - //https://docs.microsoft.com/en-us/graph/api/channel-list-messages?view=graph-rest-beta&tabs=http - if (operation === 'getAll') { - const teamId = this.getNodeParameter('teamId', i) as string; - const channelId = this.getNodeParameter('channelId', i) as string; - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - if (returnAll) { - responseData = await microsoftApiRequestAllItems.call(this, 'value', 'GET', `/beta/teams/${teamId}/channels/${channelId}/messages`); - } else { - qs.limit = this.getNodeParameter('limit', i) as number; - responseData = await microsoftApiRequestAllItems.call(this, 'value', 'GET', `/beta/teams/${teamId}/channels/${channelId}/messages`, {}); - responseData = responseData.splice(0, qs.limit); - } - } - } - if (resource === 'task') { - //https://docs.microsoft.com/en-us/graph/api/planner-post-tasks?view=graph-rest-1.0&tabs=http - if (operation === 'create') { - const planId = this.getNodeParameter('planId', i) as string; - const bucketId = this.getNodeParameter('bucketId', i) as string; - const title = this.getNodeParameter('title', i) as string; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const body: IDataObject = { - planId, - bucketId, - title, - }; - Object.assign(body, additionalFields); - - if (body.assignedTo) { - body.assignments = { - [body.assignedTo as string]: { - '@odata.type': 'microsoft.graph.plannerAssignment', - 'orderHint': ' !', + const body: IDataObject = { + body: { + contentType: messageType, + content: message, }, }; - delete body.assignedTo; - } - if (Array.isArray(body.labels)) { - body.appliedCategories = (body.labels as string[]).map((label) => ({ [label]: true })); + if (options.makeReply) { + const replyToId = options.makeReply as string; + responseData = await microsoftApiRequest.call(this, 'POST', `/beta/teams/${teamId}/channels/${channelId}/messages/${replyToId}/replies`, body); + } else { + responseData = await microsoftApiRequest.call(this, 'POST', `/beta/teams/${teamId}/channels/${channelId}/messages`, body); + } } - - responseData = await microsoftApiRequest.call(this, 'POST', `/v1.0/planner/tasks`, body); - } - //https://docs.microsoft.com/en-us/graph/api/plannertask-delete?view=graph-rest-1.0&tabs=http - if (operation === 'delete') { - const taskId = this.getNodeParameter('taskId', i) as string; - const task = await microsoftApiRequest.call(this, 'GET', `/v1.0/planner/tasks/${taskId}`); - responseData = await microsoftApiRequest.call(this, 'DELETE', `/v1.0/planner/tasks/${taskId}`, {}, {}, undefined, { 'If-Match': task['@odata.etag'] }); - responseData = { success: true }; - } - //https://docs.microsoft.com/en-us/graph/api/plannertask-get?view=graph-rest-1.0&tabs=http - if (operation === 'get') { - const taskId = this.getNodeParameter('taskId', i) as string; - responseData = await microsoftApiRequest.call(this, 'GET', `/v1.0/planner/tasks/${taskId}`); - } - //https://docs.microsoft.com/en-us/graph/api/planneruser-list-tasks?view=graph-rest-1.0&tabs=http - if (operation === 'getAll') { - const memberId = this.getNodeParameter('memberId', i) as string; - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - if (returnAll) { - responseData = await microsoftApiRequestAllItems.call(this, 'value', 'GET', `/v1.0/users/${memberId}/planner/tasks`); - } else { - qs.limit = this.getNodeParameter('limit', i) as number; - responseData = await microsoftApiRequestAllItems.call(this, 'value', 'GET', `/v1.0/users/${memberId}/planner/tasks`, {}); - responseData = responseData.splice(0, qs.limit); + //https://docs.microsoft.com/en-us/graph/api/channel-list-messages?view=graph-rest-beta&tabs=http + if (operation === 'getAll') { + const teamId = this.getNodeParameter('teamId', i) as string; + const channelId = this.getNodeParameter('channelId', i) as string; + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + if (returnAll) { + responseData = await microsoftApiRequestAllItems.call(this, 'value', 'GET', `/beta/teams/${teamId}/channels/${channelId}/messages`); + } else { + qs.limit = this.getNodeParameter('limit', i) as number; + responseData = await microsoftApiRequestAllItems.call(this, 'value', 'GET', `/beta/teams/${teamId}/channels/${channelId}/messages`, {}); + responseData = responseData.splice(0, qs.limit); + } } } - //https://docs.microsoft.com/en-us/graph/api/plannertask-update?view=graph-rest-1.0&tabs=http - if (operation === 'update') { - const taskId = this.getNodeParameter('taskId', i) as string; - const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; - const body: IDataObject = {}; - Object.assign(body, updateFields); - - if (body.assignedTo) { - body.assignments = { - [body.assignedTo as string]: { - '@odata.type': 'microsoft.graph.plannerAssignment', - 'orderHint': ' !', - }, + if (resource === 'task') { + //https://docs.microsoft.com/en-us/graph/api/planner-post-tasks?view=graph-rest-1.0&tabs=http + if (operation === 'create') { + const planId = this.getNodeParameter('planId', i) as string; + const bucketId = this.getNodeParameter('bucketId', i) as string; + const title = this.getNodeParameter('title', i) as string; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const body: IDataObject = { + planId, + bucketId, + title, }; - delete body.assignedTo; + Object.assign(body, additionalFields); + + if (body.assignedTo) { + body.assignments = { + [body.assignedTo as string]: { + '@odata.type': 'microsoft.graph.plannerAssignment', + 'orderHint': ' !', + }, + }; + delete body.assignedTo; + } + + if (Array.isArray(body.labels)) { + body.appliedCategories = (body.labels as string[]).map((label) => ({ [label]: true })); + } + + responseData = await microsoftApiRequest.call(this, 'POST', `/v1.0/planner/tasks`, body); } - - if (Array.isArray(body.labels)) { - body.appliedCategories = (body.labels as string[]).map((label) => ({ [label]: true })); + //https://docs.microsoft.com/en-us/graph/api/plannertask-delete?view=graph-rest-1.0&tabs=http + if (operation === 'delete') { + const taskId = this.getNodeParameter('taskId', i) as string; + const task = await microsoftApiRequest.call(this, 'GET', `/v1.0/planner/tasks/${taskId}`); + responseData = await microsoftApiRequest.call(this, 'DELETE', `/v1.0/planner/tasks/${taskId}`, {}, {}, undefined, { 'If-Match': task['@odata.etag'] }); + responseData = { success: true }; } + //https://docs.microsoft.com/en-us/graph/api/plannertask-get?view=graph-rest-1.0&tabs=http + if (operation === 'get') { + const taskId = this.getNodeParameter('taskId', i) as string; + responseData = await microsoftApiRequest.call(this, 'GET', `/v1.0/planner/tasks/${taskId}`); + } + //https://docs.microsoft.com/en-us/graph/api/planneruser-list-tasks?view=graph-rest-1.0&tabs=http + if (operation === 'getAll') { + const memberId = this.getNodeParameter('memberId', i) as string; + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + if (returnAll) { + responseData = await microsoftApiRequestAllItems.call(this, 'value', 'GET', `/v1.0/users/${memberId}/planner/tasks`); + } else { + qs.limit = this.getNodeParameter('limit', i) as number; + responseData = await microsoftApiRequestAllItems.call(this, 'value', 'GET', `/v1.0/users/${memberId}/planner/tasks`, {}); + responseData = responseData.splice(0, qs.limit); + } + } + //https://docs.microsoft.com/en-us/graph/api/plannertask-update?view=graph-rest-1.0&tabs=http + if (operation === 'update') { + const taskId = this.getNodeParameter('taskId', i) as string; + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + const body: IDataObject = {}; + Object.assign(body, updateFields); - const task = await microsoftApiRequest.call(this, 'GET', `/v1.0/planner/tasks/${taskId}`); + if (body.assignedTo) { + body.assignments = { + [body.assignedTo as string]: { + '@odata.type': 'microsoft.graph.plannerAssignment', + 'orderHint': ' !', + }, + }; + delete body.assignedTo; + } - responseData = await microsoftApiRequest.call(this, 'PATCH', `/v1.0/planner/tasks/${taskId}`, body, {}, undefined, { 'If-Match': task['@odata.etag'] }); + if (Array.isArray(body.labels)) { + body.appliedCategories = (body.labels as string[]).map((label) => ({ [label]: true })); + } - responseData = { success: true }; + const task = await microsoftApiRequest.call(this, 'GET', `/v1.0/planner/tasks/${taskId}`); + + responseData = await microsoftApiRequest.call(this, 'PATCH', `/v1.0/planner/tasks/${taskId}`, body, {}, undefined, { 'If-Match': task['@odata.etag'] }); + + responseData = { success: true }; + } } - } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else { - returnData.push(responseData as IDataObject); + if (Array.isArray(responseData)) { + returnData.push.apply(returnData, responseData as IDataObject[]); + } else { + returnData.push(responseData as IDataObject); + } + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } } return [this.helpers.returnJsonArray(returnData)]; diff --git a/packages/nodes-base/nodes/Mindee/Mindee.node.ts b/packages/nodes-base/nodes/Mindee/Mindee.node.ts index 53c3046d30..2b23ee27ff 100644 --- a/packages/nodes-base/nodes/Mindee/Mindee.node.ts +++ b/packages/nodes-base/nodes/Mindee/Mindee.node.ts @@ -126,96 +126,103 @@ export class Mindee implements INodeType { const resource = this.getNodeParameter('resource', 0) as string; const operation = this.getNodeParameter('operation', 0) as string; for (let i = 0; i < length; i++) { + try { + if (resource === 'receipt') { + if (operation === 'predict') { + const binaryPropertyName = this.getNodeParameter('binaryPropertyName', i) as string; - if (resource === 'receipt') { - if (operation === 'predict') { - const binaryPropertyName = this.getNodeParameter('binaryPropertyName', i) as string; + const rawData = this.getNodeParameter('rawData', i) as boolean; - const rawData = this.getNodeParameter('rawData', i) as boolean; + if (items[i].binary === undefined) { + throw new NodeOperationError(this.getNode(), 'No binary data exists on item!'); + } - if (items[i].binary === undefined) { - throw new NodeOperationError(this.getNode(), 'No binary data exists on item!'); - } + const item = items[i].binary as IBinaryKeyData; - const item = items[i].binary as IBinaryKeyData; + const binaryData = item[binaryPropertyName] as IBinaryData; - const binaryData = item[binaryPropertyName] as IBinaryData; + if (binaryData === undefined) { + throw new NodeOperationError(this.getNode(), `No binary data property "${binaryPropertyName}" does not exists on item!`); + } - if (binaryData === undefined) { - throw new NodeOperationError(this.getNode(), `No binary data property "${binaryPropertyName}" does not exists on item!`); - } - - responseData = await mindeeApiRequest.call( - this, - 'POST', - `/expense_receipts/v2/predict`, - {}, - {}, - { - formData: { - file: { - value: Buffer.from(binaryData.data, BINARY_ENCODING), - options: { - filename: binaryData.fileName, + responseData = await mindeeApiRequest.call( + this, + 'POST', + `/expense_receipts/v2/predict`, + {}, + {}, + { + formData: { + file: { + value: Buffer.from(binaryData.data, BINARY_ENCODING), + options: { + filename: binaryData.fileName, + }, }, }, }, - }, - ); + ); - if (rawData === false) { - responseData = cleanData(responseData.predictions); + if (rawData === false) { + responseData = cleanData(responseData.predictions); + } } } - } - if (resource === 'invoice') { - if (operation === 'predict') { - const binaryPropertyName = this.getNodeParameter('binaryPropertyName', i) as string; + if (resource === 'invoice') { + if (operation === 'predict') { + const binaryPropertyName = this.getNodeParameter('binaryPropertyName', i) as string; - const rawData = this.getNodeParameter('rawData', i) as boolean; + const rawData = this.getNodeParameter('rawData', i) as boolean; - if (items[i].binary === undefined) { - throw new NodeOperationError(this.getNode(), 'No binary data exists on item!'); - } + if (items[i].binary === undefined) { + throw new NodeOperationError(this.getNode(), 'No binary data exists on item!'); + } - const item = items[i].binary as IBinaryKeyData; + const item = items[i].binary as IBinaryKeyData; - const binaryData = item[binaryPropertyName] as IBinaryData; + const binaryData = item[binaryPropertyName] as IBinaryData; - if (binaryData === undefined) { - throw new NodeOperationError(this.getNode(), `No binary data property "${binaryPropertyName}" does not exists on item!`); - } + if (binaryData === undefined) { + throw new NodeOperationError(this.getNode(), `No binary data property "${binaryPropertyName}" does not exists on item!`); + } - responseData = await mindeeApiRequest.call( - this, - 'POST', - `/invoices/v1/predict`, - {}, - {}, - { - formData: { - file: { - value: Buffer.from(binaryData.data, BINARY_ENCODING), - options: { - filename: binaryData.fileName, + responseData = await mindeeApiRequest.call( + this, + 'POST', + `/invoices/v1/predict`, + {}, + {}, + { + formData: { + file: { + value: Buffer.from(binaryData.data, BINARY_ENCODING), + options: { + filename: binaryData.fileName, + }, }, }, }, - }, - ); + ); - if (rawData === false) { - responseData = cleanData(responseData.predictions); + if (rawData === false) { + responseData = cleanData(responseData.predictions); + } } } + if (Array.isArray(responseData)) { + returnData.push.apply(returnData, responseData as IDataObject[]); + } else if (responseData !== undefined) { + returnData.push(responseData as IDataObject); + } + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else if (responseData !== undefined) { - returnData.push(responseData as IDataObject); - } return [this.helpers.returnJsonArray(returnData)]; } } diff --git a/packages/nodes-base/nodes/Mocean/Mocean.node.ts b/packages/nodes-base/nodes/Mocean/Mocean.node.ts index ae2f87ba43..0c7206f633 100644 --- a/packages/nodes-base/nodes/Mocean/Mocean.node.ts +++ b/packages/nodes-base/nodes/Mocean/Mocean.node.ts @@ -195,45 +195,52 @@ export class Mocean implements INodeType { for (let itemIndex = 0; itemIndex < items.length; itemIndex++) { body = {}; qs = {}; + try { + resource = this.getNodeParameter('resource', itemIndex, '') as string; + operation = this.getNodeParameter('operation',itemIndex,'') as string; + text = this.getNodeParameter('message', itemIndex, '') as string; + requesetMethod = 'POST'; + body['mocean-from'] = this.getNodeParameter('from', itemIndex, '') as string; + body['mocean-to'] = this.getNodeParameter('to', itemIndex, '') as string; - resource = this.getNodeParameter('resource', itemIndex, '') as string; - operation = this.getNodeParameter('operation',itemIndex,'') as string; - text = this.getNodeParameter('message', itemIndex, '') as string; - requesetMethod = 'POST'; - body['mocean-from'] = this.getNodeParameter('from', itemIndex, '') as string; - body['mocean-to'] = this.getNodeParameter('to', itemIndex, '') as string; + if (resource === 'voice') { + const language: string = this.getNodeParameter('language', itemIndex) as string; + const command = [ + { + action: 'say', + language, + text, + }, + ]; - if (resource === 'voice') { - const language: string = this.getNodeParameter('language', itemIndex) as string; - const command = [ - { - action: 'say', - language, - text, - }, - ]; - - dataKey = 'voice'; - body['mocean-command'] = JSON.stringify(command); - endpoint = '/rest/2/voice/dial'; - } else if(resource === 'sms') { - dataKey = 'messages'; - body['mocean-text'] = text; - endpoint = '/rest/2/sms'; - } else { - throw new NodeOperationError(this.getNode(), `Unknown resource ${resource}`); - } - - if (operation === 'send') { - const responseData = await moceanApiRequest.call(this,requesetMethod,endpoint,body,qs); - - for (const item of responseData[dataKey] as IDataObject[]) { - item.type = resource; - returnData.push(item); + dataKey = 'voice'; + body['mocean-command'] = JSON.stringify(command); + endpoint = '/rest/2/voice/dial'; + } else if(resource === 'sms') { + dataKey = 'messages'; + body['mocean-text'] = text; + endpoint = '/rest/2/sms'; + } else { + throw new NodeOperationError(this.getNode(), `Unknown resource ${resource}`); } - } else { - throw new NodeOperationError(this.getNode(), `Unknown operation ${operation}`); + if (operation === 'send') { + const responseData = await moceanApiRequest.call(this,requesetMethod,endpoint,body,qs); + + for (const item of responseData[dataKey] as IDataObject[]) { + item.type = resource; + returnData.push(item); + } + + } else { + throw new NodeOperationError(this.getNode(), `Unknown operation ${operation}`); + } + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } } diff --git a/packages/nodes-base/nodes/MondayCom/MondayCom.node.ts b/packages/nodes-base/nodes/MondayCom/MondayCom.node.ts index 0fa5568888..b8f00b2115 100644 --- a/packages/nodes-base/nodes/MondayCom/MondayCom.node.ts +++ b/packages/nodes-base/nodes/MondayCom/MondayCom.node.ts @@ -262,500 +262,508 @@ export class MondayCom implements INodeType { 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 === 'board') { - if (operation === 'archive') { - const boardId = parseInt(this.getNodeParameter('boardId', i) as string, 10); + try { + if (resource === 'board') { + if (operation === 'archive') { + const boardId = parseInt(this.getNodeParameter('boardId', i) as string, 10); - const body: IGraphqlBody = { - query: - `mutation ($id: Int!) { - archive_board (board_id: $id) { - id - } - }`, - variables: { - id: boardId, - }, - }; + const body: IGraphqlBody = { + query: + `mutation ($id: Int!) { + archive_board (board_id: $id) { + id + } + }`, + variables: { + id: boardId, + }, + }; - responseData = await mondayComApiRequest.call(this, body); - responseData = responseData.data.archive_board; - } - if (operation === 'create') { - const name = this.getNodeParameter('name', i) as string; - const kind = this.getNodeParameter('kind', i) as string; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - - const body: IGraphqlBody = { - query: - `mutation ($name: String!, $kind: BoardKind!, $templateId: Int) { - create_board (board_name: $name, board_kind: $kind, template_id: $templateId) { - id - } - }`, - variables: { - name, - kind, - }, - }; - - if (additionalFields.templateId) { - body.variables.templateId = additionalFields.templateId as number; + responseData = await mondayComApiRequest.call(this, body); + responseData = responseData.data.archive_board; } + if (operation === 'create') { + const name = this.getNodeParameter('name', i) as string; + const kind = this.getNodeParameter('kind', i) as string; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - responseData = await mondayComApiRequest.call(this, body); - responseData = responseData.data.create_board; - } - if (operation === 'get') { - const boardId = parseInt(this.getNodeParameter('boardId', i) as string, 10); - - const body: IGraphqlBody = { - query: - `query ($id: [Int]) { - boards (ids: $id){ - id - name - description - state - board_folder_id - board_kind - owner() { + const body: IGraphqlBody = { + query: + `mutation ($name: String!, $kind: BoardKind!, $templateId: Int) { + create_board (board_name: $name, board_kind: $kind, template_id: $templateId) { id } - } - }`, - variables: { - id: boardId, - }, - }; + }`, + variables: { + name, + kind, + }, + }; - responseData = await mondayComApiRequest.call(this, body); - responseData = responseData.data.boards; - } - if (operation === 'getAll') { - const returnAll = this.getNodeParameter('returnAll', i) as boolean; + if (additionalFields.templateId) { + body.variables.templateId = additionalFields.templateId as number; + } - const body: IGraphqlBody = { - query: - `query ($page: Int, $limit: Int) { - boards (page: $page, limit: $limit){ - id - name - description - state - board_folder_id - board_kind - owner() { + responseData = await mondayComApiRequest.call(this, body); + responseData = responseData.data.create_board; + } + if (operation === 'get') { + const boardId = parseInt(this.getNodeParameter('boardId', i) as string, 10); + + const body: IGraphqlBody = { + query: + `query ($id: [Int]) { + boards (ids: $id){ id + name + description + state + board_folder_id + board_kind + owner() { + id + } } - } - }`, - variables: { - page: 1, - }, - }; + }`, + variables: { + id: boardId, + }, + }; - if (returnAll === true) { - responseData = await mondayComApiRequestAllItems.call(this, 'data.boards', body); - } else { - body.variables.limit = this.getNodeParameter('limit', i) as number; responseData = await mondayComApiRequest.call(this, body); responseData = responseData.data.boards; } - } - } - if (resource === 'boardColumn') { - if (operation === 'create') { - const boardId = parseInt(this.getNodeParameter('boardId', i) as string, 10); - const title = this.getNodeParameter('title', i) as string; - const columnType = this.getNodeParameter('columnType', i) as string; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + if (operation === 'getAll') { + const returnAll = this.getNodeParameter('returnAll', i) as boolean; - const body: IGraphqlBody = { - query: - `mutation ($boardId: Int!, $title: String!, $columnType: ColumnType, $defaults: JSON ) { - create_column (board_id: $boardId, title: $title, column_type: $columnType, defaults: $defaults) { - id - } - }`, - variables: { - boardId, - title, - columnType: snakeCase(columnType), - }, - }; + const body: IGraphqlBody = { + query: + `query ($page: Int, $limit: Int) { + boards (page: $page, limit: $limit){ + id + name + description + state + board_folder_id + board_kind + owner() { + id + } + } + }`, + variables: { + page: 1, + }, + }; - if (additionalFields.defaults) { - try { - JSON.parse(additionalFields.defaults as string); - } catch (error) { - throw new NodeOperationError(this.getNode(), 'Defauls must be a valid JSON'); + if (returnAll === true) { + responseData = await mondayComApiRequestAllItems.call(this, 'data.boards', body); + } else { + body.variables.limit = this.getNodeParameter('limit', i) as number; + responseData = await mondayComApiRequest.call(this, body); + responseData = responseData.data.boards; } - body.variables.defaults = JSON.stringify(JSON.parse(additionalFields.defaults as string)); } - - responseData = await mondayComApiRequest.call(this, body); - responseData = responseData.data.create_column; } - if (operation === 'getAll') { - const boardId = parseInt(this.getNodeParameter('boardId', i) as string, 10); + if (resource === 'boardColumn') { + if (operation === 'create') { + const boardId = parseInt(this.getNodeParameter('boardId', i) as string, 10); + const title = this.getNodeParameter('title', i) as string; + const columnType = this.getNodeParameter('columnType', i) as string; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const body: IGraphqlBody = { - query: - `query ($boardId: [Int]) { - boards (ids: $boardId){ - columns() { + const body: IGraphqlBody = { + query: + `mutation ($boardId: Int!, $title: String!, $columnType: ColumnType, $defaults: JSON ) { + create_column (board_id: $boardId, title: $title, column_type: $columnType, defaults: $defaults) { id - title - type - settings_str - archived } - } - }`, - variables: { - page: 1, - boardId, - }, - }; + }`, + variables: { + boardId, + title, + columnType: snakeCase(columnType), + }, + }; - responseData = await mondayComApiRequest.call(this, body); - responseData = responseData.data.boards[0].columns; + if (additionalFields.defaults) { + try { + JSON.parse(additionalFields.defaults as string); + } catch (error) { + throw new NodeOperationError(this.getNode(), 'Defauls must be a valid JSON'); + } + body.variables.defaults = JSON.stringify(JSON.parse(additionalFields.defaults as string)); + } + + responseData = await mondayComApiRequest.call(this, body); + responseData = responseData.data.create_column; + } + if (operation === 'getAll') { + const boardId = parseInt(this.getNodeParameter('boardId', i) as string, 10); + + const body: IGraphqlBody = { + query: + `query ($boardId: [Int]) { + boards (ids: $boardId){ + columns() { + id + title + type + settings_str + archived + } + } + }`, + variables: { + page: 1, + boardId, + }, + }; + + responseData = await mondayComApiRequest.call(this, body); + responseData = responseData.data.boards[0].columns; + } } - } - if (resource === 'boardGroup') { - if (operation === 'create') { - const boardId = parseInt(this.getNodeParameter('boardId', i) as string, 10); - const name = this.getNodeParameter('name', i) as string; + if (resource === 'boardGroup') { + if (operation === 'create') { + const boardId = parseInt(this.getNodeParameter('boardId', i) as string, 10); + const name = this.getNodeParameter('name', i) as string; - const body: IGraphqlBody = { - query: - `mutation ($boardId: Int!, $groupName: String!) { - create_group (board_id: $boardId, group_name: $groupName) { - id - } - }`, - variables: { - boardId, - groupName: name, - }, - }; - - responseData = await mondayComApiRequest.call(this, body); - responseData = responseData.data.create_group; - } - if (operation === 'delete') { - const boardId = parseInt(this.getNodeParameter('boardId', i) as string, 10); - const groupId = this.getNodeParameter('groupId', i) as string; - - const body: IGraphqlBody = { - query: - `mutation ($boardId: Int!, $groupId: String!) { - delete_group (board_id: $boardId, group_id: $groupId) { - id - } - }`, - variables: { - boardId, - groupId, - }, - }; - - responseData = await mondayComApiRequest.call(this, body); - responseData = responseData.data.delete_group; - } - if (operation === 'getAll') { - const boardId = parseInt(this.getNodeParameter('boardId', i) as string, 10); - - const body: IGraphqlBody = { - query: - `query ($boardId: [Int]) { - boards (ids: $boardId, ){ - id - groups() { + const body: IGraphqlBody = { + query: + `mutation ($boardId: Int!, $groupName: String!) { + create_group (board_id: $boardId, group_name: $groupName) { id - title - color - position - archived } - } - }`, - variables: { - boardId, - }, - }; + }`, + variables: { + boardId, + groupName: name, + }, + }; - responseData = await mondayComApiRequest.call(this, body); - responseData = responseData.data.boards[0].groups; - } - } - if (resource === 'boardItem') { - if (operation === 'addUpdate') { - const itemId = parseInt((this.getNodeParameter('itemId', i) as string), 10); - const value = this.getNodeParameter('value', i) as string; - - const body: IGraphqlBody = { - query: - `mutation ($itemId: Int!, $value: String!) { - create_update (item_id: $itemId, body: $value) { - id - } - }`, - variables: { - itemId, - value, - }, - }; - - responseData = await mondayComApiRequest.call(this, body); - responseData = responseData.data.create_update; - } - if (operation === 'changeColumnValue') { - const boardId = parseInt(this.getNodeParameter('boardId', i) as string, 10); - const itemId = parseInt((this.getNodeParameter('itemId', i) as string), 10); - const columnId = this.getNodeParameter('columnId', i) as string; - const value = this.getNodeParameter('value', i) as string; - - const body: IGraphqlBody = { - query: - `mutation ($boardId: Int!, $itemId: Int!, $columnId: String!, $value: JSON!) { - change_column_value (board_id: $boardId, item_id: $itemId, column_id: $columnId, value: $value) { - id - } - }`, - variables: { - boardId, - itemId, - columnId, - }, - }; - - try { - JSON.parse(value); - } catch (error) { - throw new NodeOperationError(this.getNode(), 'Custom Values must be a valid JSON'); + responseData = await mondayComApiRequest.call(this, body); + responseData = responseData.data.create_group; } - body.variables.value = JSON.stringify(JSON.parse(value)); + if (operation === 'delete') { + const boardId = parseInt(this.getNodeParameter('boardId', i) as string, 10); + const groupId = this.getNodeParameter('groupId', i) as string; - responseData = await mondayComApiRequest.call(this, body); - responseData = responseData.data.change_column_value; - } - if (operation === 'changeMultipleColumnValues') { - const boardId = parseInt(this.getNodeParameter('boardId', i) as string, 10); - const itemId = parseInt((this.getNodeParameter('itemId', i) as string), 10); - const columnValues = this.getNodeParameter('columnValues', i) as string; + const body: IGraphqlBody = { + query: + `mutation ($boardId: Int!, $groupId: String!) { + delete_group (board_id: $boardId, group_id: $groupId) { + id + } + }`, + variables: { + boardId, + groupId, + }, + }; - const body: IGraphqlBody = { - query: - `mutation ($boardId: Int!, $itemId: Int!, $columnValues: JSON!) { - change_multiple_column_values (board_id: $boardId, item_id: $itemId, column_values: $columnValues) { - id - } - }`, - variables: { - boardId, - itemId, - }, - }; - - try { - JSON.parse(columnValues); - } catch (error) { - throw new NodeOperationError(this.getNode(), 'Custom Values must be a valid JSON'); + responseData = await mondayComApiRequest.call(this, body); + responseData = responseData.data.delete_group; } - body.variables.columnValues = JSON.stringify(JSON.parse(columnValues)); + if (operation === 'getAll') { + const boardId = parseInt(this.getNodeParameter('boardId', i) as string, 10); - responseData = await mondayComApiRequest.call(this, body); - responseData = responseData.data.change_multiple_column_values; + const body: IGraphqlBody = { + query: + `query ($boardId: [Int]) { + boards (ids: $boardId, ){ + id + groups() { + id + title + color + position + archived + } + } + }`, + variables: { + boardId, + }, + }; + + responseData = await mondayComApiRequest.call(this, body); + responseData = responseData.data.boards[0].groups; + } } - if (operation === 'create') { - const boardId = parseInt(this.getNodeParameter('boardId', i) as string, 10); - const groupId = this.getNodeParameter('groupId', i) as string; - const itemName = this.getNodeParameter('name', i) as string; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + if (resource === 'boardItem') { + if (operation === 'addUpdate') { + const itemId = parseInt((this.getNodeParameter('itemId', i) as string), 10); + const value = this.getNodeParameter('value', i) as string; - const body: IGraphqlBody = { - query: - `mutation ($boardId: Int!, $groupId: String!, $itemName: String!, $columnValues: JSON) { - create_item (board_id: $boardId, group_id: $groupId, item_name: $itemName, column_values: $columnValues) { - id - } - }`, - variables: { - boardId, - groupId, - itemName, - }, - }; + const body: IGraphqlBody = { + query: + `mutation ($itemId: Int!, $value: String!) { + create_update (item_id: $itemId, body: $value) { + id + } + }`, + variables: { + itemId, + value, + }, + }; + + responseData = await mondayComApiRequest.call(this, body); + responseData = responseData.data.create_update; + } + if (operation === 'changeColumnValue') { + const boardId = parseInt(this.getNodeParameter('boardId', i) as string, 10); + const itemId = parseInt((this.getNodeParameter('itemId', i) as string), 10); + const columnId = this.getNodeParameter('columnId', i) as string; + const value = this.getNodeParameter('value', i) as string; + + const body: IGraphqlBody = { + query: + `mutation ($boardId: Int!, $itemId: Int!, $columnId: String!, $value: JSON!) { + change_column_value (board_id: $boardId, item_id: $itemId, column_id: $columnId, value: $value) { + id + } + }`, + variables: { + boardId, + itemId, + columnId, + }, + }; - if (additionalFields.columnValues) { try { - JSON.parse(additionalFields.columnValues as string); + JSON.parse(value); } catch (error) { throw new NodeOperationError(this.getNode(), 'Custom Values must be a valid JSON'); } - body.variables.columnValues = JSON.stringify(JSON.parse(additionalFields.columnValues as string)); - } + body.variables.value = JSON.stringify(JSON.parse(value)); - responseData = await mondayComApiRequest.call(this, body); - responseData = responseData.data.create_item; - } - if (operation === 'delete') { - const itemId = parseInt((this.getNodeParameter('itemId', i) as string), 10); - - const body: IGraphqlBody = { - query: - `mutation ($itemId: Int!) { - delete_item (item_id: $itemId) { - id - } - }`, - variables: { - itemId, - }, - }; - responseData = await mondayComApiRequest.call(this, body); - responseData = responseData.data.delete_item; - } - if (operation === 'get') { - const itemIds = ((this.getNodeParameter('itemId', i) as string).split(',') as string[]).map((n) => parseInt(n, 10)); - - const body: IGraphqlBody = { - query: - `query ($itemId: [Int!]){ - items (ids: $itemId) { - id - name - created_at - state - column_values() { - id - text - title - type - value - additional_info - } - } - }`, - variables: { - itemId: itemIds, - }, - }; - responseData = await mondayComApiRequest.call(this, body); - responseData = responseData.data.items; - } - if (operation === 'getAll') { - const boardId = parseInt(this.getNodeParameter('boardId', i) as string, 10); - const groupId = this.getNodeParameter('groupId', i) as string; - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - - const body: IGraphqlBody = { - query: - `query ($boardId: [Int], $groupId: [String], $page: Int, $limit: Int) { - boards (ids: $boardId) { - groups (ids: $groupId) { - id - items(limit: $limit, page: $page) { - id - name - created_at - state - column_values() { - id - text - title - type - value - additional_info - } - } - } - } - }`, - variables: { - boardId, - groupId, - }, - }; - - if (returnAll) { - responseData = await mondayComApiRequestAllItems.call(this, 'data.boards[0].groups[0].items', body); - } else { - body.variables.limit = this.getNodeParameter('limit', i) as number; responseData = await mondayComApiRequest.call(this, body); - responseData = responseData.data.boards[0].groups[0].items; + responseData = responseData.data.change_column_value; } + if (operation === 'changeMultipleColumnValues') { + const boardId = parseInt(this.getNodeParameter('boardId', i) as string, 10); + const itemId = parseInt((this.getNodeParameter('itemId', i) as string), 10); + const columnValues = this.getNodeParameter('columnValues', i) as string; - } - if (operation === 'getByColumnValue') { - const boardId = parseInt(this.getNodeParameter('boardId', i) as string, 10); - const columnId = this.getNodeParameter('columnId', i) as string; - const columnValue = this.getNodeParameter('columnValue', i) as string; - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - - const body: IGraphqlBody = { - query: - `query ($boardId: Int!, $columnId: String!, $columnValue: String!, $page: Int, $limit: Int ){ - items_by_column_values (board_id: $boardId, column_id: $columnId, column_value: $columnValue, page: $page, limit: $limit) { - id - name - created_at - state - board { + const body: IGraphqlBody = { + query: + `mutation ($boardId: Int!, $itemId: Int!, $columnValues: JSON!) { + change_multiple_column_values (board_id: $boardId, item_id: $itemId, column_values: $columnValues) { id } - column_values() { - id - text - title - type - value - additional_info - } - } - }`, - variables: { - boardId, - columnId, - columnValue, - }, - }; + }`, + variables: { + boardId, + itemId, + }, + }; + + try { + JSON.parse(columnValues); + } catch (error) { + throw new NodeOperationError(this.getNode(), 'Custom Values must be a valid JSON'); + } + body.variables.columnValues = JSON.stringify(JSON.parse(columnValues)); - if (returnAll) { - responseData = await mondayComApiRequestAllItems.call(this, 'data.items_by_column_values', body); - } else { - body.variables.limit = this.getNodeParameter('limit', i) as number; responseData = await mondayComApiRequest.call(this, body); - responseData = responseData.data.items_by_column_values; + responseData = responseData.data.change_multiple_column_values; + } + if (operation === 'create') { + const boardId = parseInt(this.getNodeParameter('boardId', i) as string, 10); + const groupId = this.getNodeParameter('groupId', i) as string; + const itemName = this.getNodeParameter('name', i) as string; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + + const body: IGraphqlBody = { + query: + `mutation ($boardId: Int!, $groupId: String!, $itemName: String!, $columnValues: JSON) { + create_item (board_id: $boardId, group_id: $groupId, item_name: $itemName, column_values: $columnValues) { + id + } + }`, + variables: { + boardId, + groupId, + itemName, + }, + }; + + if (additionalFields.columnValues) { + try { + JSON.parse(additionalFields.columnValues as string); + } catch (error) { + throw new NodeOperationError(this.getNode(), 'Custom Values must be a valid JSON'); + } + body.variables.columnValues = JSON.stringify(JSON.parse(additionalFields.columnValues as string)); + } + + responseData = await mondayComApiRequest.call(this, body); + responseData = responseData.data.create_item; + } + if (operation === 'delete') { + const itemId = parseInt((this.getNodeParameter('itemId', i) as string), 10); + + const body: IGraphqlBody = { + query: + `mutation ($itemId: Int!) { + delete_item (item_id: $itemId) { + id + } + }`, + variables: { + itemId, + }, + }; + responseData = await mondayComApiRequest.call(this, body); + responseData = responseData.data.delete_item; + } + if (operation === 'get') { + const itemIds = ((this.getNodeParameter('itemId', i) as string).split(',') as string[]).map((n) => parseInt(n, 10)); + + const body: IGraphqlBody = { + query: + `query ($itemId: [Int!]){ + items (ids: $itemId) { + id + name + created_at + state + column_values() { + id + text + title + type + value + additional_info + } + } + }`, + variables: { + itemId: itemIds, + }, + }; + responseData = await mondayComApiRequest.call(this, body); + responseData = responseData.data.items; + } + if (operation === 'getAll') { + const boardId = parseInt(this.getNodeParameter('boardId', i) as string, 10); + const groupId = this.getNodeParameter('groupId', i) as string; + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + + const body: IGraphqlBody = { + query: + `query ($boardId: [Int], $groupId: [String], $page: Int, $limit: Int) { + boards (ids: $boardId) { + groups (ids: $groupId) { + id + items(limit: $limit, page: $page) { + id + name + created_at + state + column_values() { + id + text + title + type + value + additional_info + } + } + } + } + }`, + variables: { + boardId, + groupId, + }, + }; + + if (returnAll) { + responseData = await mondayComApiRequestAllItems.call(this, 'data.boards[0].groups[0].items', body); + } else { + body.variables.limit = this.getNodeParameter('limit', i) as number; + responseData = await mondayComApiRequest.call(this, body); + responseData = responseData.data.boards[0].groups[0].items; + } + + } + if (operation === 'getByColumnValue') { + const boardId = parseInt(this.getNodeParameter('boardId', i) as string, 10); + const columnId = this.getNodeParameter('columnId', i) as string; + const columnValue = this.getNodeParameter('columnValue', i) as string; + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + + const body: IGraphqlBody = { + query: + `query ($boardId: Int!, $columnId: String!, $columnValue: String!, $page: Int, $limit: Int ){ + items_by_column_values (board_id: $boardId, column_id: $columnId, column_value: $columnValue, page: $page, limit: $limit) { + id + name + created_at + state + board { + id + } + column_values() { + id + text + title + type + value + additional_info + } + } + }`, + variables: { + boardId, + columnId, + columnValue, + }, + }; + + if (returnAll) { + responseData = await mondayComApiRequestAllItems.call(this, 'data.items_by_column_values', body); + } else { + body.variables.limit = this.getNodeParameter('limit', i) as number; + responseData = await mondayComApiRequest.call(this, body); + responseData = responseData.data.items_by_column_values; + } + } + if (operation === 'move') { + const groupId = this.getNodeParameter('groupId', i) as string; + const itemId = parseInt(this.getNodeParameter('itemId', i) as string, 10); + + const body: IGraphqlBody = { + query: + `mutation ($groupId: String!, $itemId: Int!) { + move_item_to_group (group_id: $groupId, item_id: $itemId) { + id + } + }`, + variables: { + groupId, + itemId, + }, + }; + + responseData = await mondayComApiRequest.call(this, body); + responseData = responseData.data.move_item_to_group; } } - if (operation === 'move') { - const groupId = this.getNodeParameter('groupId', i) as string; - const itemId = parseInt(this.getNodeParameter('itemId', i) as string, 10); - - const body: IGraphqlBody = { - query: - `mutation ($groupId: String!, $itemId: Int!) { - move_item_to_group (group_id: $groupId, item_id: $itemId) { - id - } - }`, - variables: { - groupId, - itemId, - }, - }; - - responseData = await mondayComApiRequest.call(this, body); - responseData = responseData.data.move_item_to_group; + if (Array.isArray(responseData)) { + returnData.push.apply(returnData, responseData as IDataObject[]); + } else { + returnData.push(responseData as IDataObject); } - } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else { - returnData.push(responseData as IDataObject); + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } } return [this.helpers.returnJsonArray(returnData)]; diff --git a/packages/nodes-base/nodes/MongoDb/MongoDb.node.ts b/packages/nodes-base/nodes/MongoDb/MongoDb.node.ts index ed42fb80af..2e83cf3be2 100644 --- a/packages/nodes-base/nodes/MongoDb/MongoDb.node.ts +++ b/packages/nodes-base/nodes/MongoDb/MongoDb.node.ts @@ -51,67 +51,90 @@ export class MongoDb implements INodeType { // delete // ---------------------------------- - const { deletedCount } = await mdb - .collection(this.getNodeParameter('collection', 0) as string) - .deleteMany(JSON.parse(this.getNodeParameter('query', 0) as string)); + try { + const { deletedCount } = await mdb + .collection(this.getNodeParameter('collection', 0) as string) + .deleteMany(JSON.parse(this.getNodeParameter('query', 0) as string)); - returnItems = this.helpers.returnJsonArray([{ deletedCount }]); + returnItems = this.helpers.returnJsonArray([{ deletedCount }]); + } catch (error) { + if (this.continueOnFail()) { + returnItems = this.helpers.returnJsonArray({ error: error.message }); + } else { + throw error; + } + } } else if (operation === 'find') { // ---------------------------------- // find // ---------------------------------- - let query = mdb - .collection(this.getNodeParameter('collection', 0) as string) - .find(JSON.parse(this.getNodeParameter('query', 0) as string)); + try { + let query = mdb + .collection(this.getNodeParameter('collection', 0) as string) + .find(JSON.parse(this.getNodeParameter('query', 0) as string)); - const options = this.getNodeParameter('options', 0) as IDataObject; - const limit = options.limit as number; - const skip = options.skip as number; - const sort = options.sort && JSON.parse(options.sort as string); - if (skip > 0) { - query = query.skip(skip); - } - if (limit > 0) { - query = query.limit(limit); - } - if (sort && Object.keys(sort).length !== 0 && sort.constructor === Object) { - query = query.sort(sort); - } - const queryResult = await query.toArray(); + const options = this.getNodeParameter('options', 0) as IDataObject; + const limit = options.limit as number; + const skip = options.skip as number; + const sort = options.sort && JSON.parse(options.sort as string); + if (skip > 0) { + query = query.skip(skip); + } + if (limit > 0) { + query = query.limit(limit); + } + if (sort && Object.keys(sort).length !== 0 && sort.constructor === Object) { + query = query.sort(sort); + } + const queryResult = await query.toArray(); - returnItems = this.helpers.returnJsonArray(queryResult as IDataObject[]); + returnItems = this.helpers.returnJsonArray(queryResult as IDataObject[]); + } catch (error) { + if (this.continueOnFail()) { + returnItems = this.helpers.returnJsonArray({ error: error.message } ); + } else { + throw error; + } + } } else if (operation === 'insert') { // ---------------------------------- // insert // ---------------------------------- + try { + // Prepare the data to insert and copy it to be returned + const fields = (this.getNodeParameter('fields', 0) as string) + .split(',') + .map(f => f.trim()) + .filter(f => !!f); - // Prepare the data to insert and copy it to be returned - const fields = (this.getNodeParameter('fields', 0) as string) - .split(',') - .map(f => f.trim()) - .filter(f => !!f); + const options = this.getNodeParameter('options', 0) as IDataObject; + const insertItems = getItemCopy(items, fields); - const options = this.getNodeParameter('options', 0) as IDataObject; - const insertItems = getItemCopy(items, fields); + if (options.dateFields) { + handleDateFields(insertItems, options.dateFields as string); + } - if (options.dateFields) { - handleDateFields(insertItems, options.dateFields as string); - } + const { insertedIds } = await mdb + .collection(this.getNodeParameter('collection', 0) as string) + .insertMany(insertItems); - const { insertedIds } = await mdb - .collection(this.getNodeParameter('collection', 0) as string) - .insertMany(insertItems); - - // Add the id to the data - for (const i of Object.keys(insertedIds)) { - returnItems.push({ - json: { - ...insertItems[parseInt(i, 10)], - id: insertedIds[parseInt(i, 10)] as string, - }, - }); + // Add the id to the data + for (const i of Object.keys(insertedIds)) { + returnItems.push({ + json: { + ...insertItems[parseInt(i, 10)], + id: insertedIds[parseInt(i, 10)] as string, + }, + }); + } + } catch (error) { + if (this.continueOnFail()) { + returnItems = this.helpers.returnJsonArray({ error: error.message }); + } else { + throw error; + } } } else if (operation === 'update') { // ---------------------------------- @@ -143,23 +166,35 @@ export class MongoDb implements INodeType { } for (const item of updateItems) { - if (item[updateKey] === undefined) { - continue; - } + try { + if (item[updateKey] === undefined) { + continue; + } - const filter: { [key: string]: string | ObjectID } = {}; - filter[updateKey] = item[updateKey] as string; - if (updateKey === '_id') { - filter[updateKey] = new ObjectID(filter[updateKey]); - delete item['_id']; + const filter: { [key: string]: string | ObjectID } = {}; + filter[updateKey] = item[updateKey] as string; + if (updateKey === '_id') { + filter[updateKey] = new ObjectID(filter[updateKey]); + delete item['_id']; + } + await mdb + .collection(this.getNodeParameter('collection', 0) as string) + .updateOne(filter, { $set: item }, updateOptions); + } catch (error) { + if (this.continueOnFail()) { + item.json = { error: error.message }; + continue; + } + throw error; } - await mdb - .collection(this.getNodeParameter('collection', 0) as string) - .updateOne(filter, { $set: item }, updateOptions); } returnItems = this.helpers.returnJsonArray(updateItems as IDataObject[]); } else { - throw new NodeOperationError(this.getNode(), `The operation "${operation}" is not supported!`); + if (this.continueOnFail()) { + returnItems = this.helpers.returnJsonArray({ json: { error: `The operation "${operation}" is not supported!` } }); + } else { + throw new NodeOperationError(this.getNode(), `The operation "${operation}" is not supported!`); + } } client.close(); diff --git a/packages/nodes-base/nodes/MySql/MySql.node.ts b/packages/nodes-base/nodes/MySql/MySql.node.ts index 20eebf52de..9c8f386de7 100644 --- a/packages/nodes-base/nodes/MySql/MySql.node.ts +++ b/packages/nodes-base/nodes/MySql/MySql.node.ts @@ -252,70 +252,101 @@ export class MySql implements INodeType { // executeQuery // ---------------------------------- - const queryQueue = items.map((item, index) => { - const rawQuery = this.getNodeParameter('query', index) as string; + try { + const queryQueue = items.map((item, index) => { + const rawQuery = this.getNodeParameter('query', index) as string; - return connection.query(rawQuery); - }); + return connection.query(rawQuery); + }); - const queryResult = (await Promise.all(queryQueue) as mysql2.OkPacket[][]).reduce((collection, result) => { - const [rows, fields] = result; + const queryResult = (await Promise.all(queryQueue) as mysql2.OkPacket[][]).reduce((collection, result) => { + const [rows, fields] = result; - if (Array.isArray(rows)) { - return collection.concat(rows); + if (Array.isArray(rows)) { + return collection.concat(rows); + } + + collection.push(rows); + + return collection; + }, []); + + returnItems = this.helpers.returnJsonArray(queryResult as unknown as IDataObject[]); + + } catch (error) { + if (this.continueOnFail()) { + returnItems = this.helpers.returnJsonArray({ error: error.message }); + } else { + await connection.end(); + throw error; } - - collection.push(rows); - - return collection; - }, []); - - returnItems = this.helpers.returnJsonArray(queryResult as unknown as IDataObject[]); - + } } else if (operation === 'insert') { // ---------------------------------- // insert // ---------------------------------- - const table = this.getNodeParameter('table', 0) as string; - const columnString = this.getNodeParameter('columns', 0) as string; - const columns = columnString.split(',').map(column => column.trim()); - const insertItems = copyInputItems(items, columns); - const insertPlaceholder = `(${columns.map(column => '?').join(',')})`; - const options = this.getNodeParameter('options', 0) as IDataObject; - const insertIgnore = options.ignore as boolean; - const insertPriority = options.priority as string; - - const insertSQL = `INSERT ${insertPriority || ''} ${insertIgnore ? 'IGNORE' : ''} INTO ${table}(${columnString}) VALUES ${items.map(item => insertPlaceholder).join(',')};`; - const queryItems = insertItems.reduce((collection, item) => collection.concat(Object.values(item as any)), []); // tslint:disable-line:no-any - - const queryResult = await connection.query(insertSQL, queryItems); - - returnItems = this.helpers.returnJsonArray(queryResult[0] as unknown as IDataObject); + try { + const table = this.getNodeParameter('table', 0) as string; + const columnString = this.getNodeParameter('columns', 0) as string; + const columns = columnString.split(',').map(column => column.trim()); + const insertItems = copyInputItems(items, columns); + const insertPlaceholder = `(${columns.map(column => '?').join(',')})`; + const options = this.getNodeParameter('options', 0) as IDataObject; + const insertIgnore = options.ignore as boolean; + const insertPriority = options.priority as string; + + const insertSQL = `INSERT ${insertPriority || ''} ${insertIgnore ? 'IGNORE' : ''} INTO ${table}(${columnString}) VALUES ${items.map(item => insertPlaceholder).join(',')};`; + const queryItems = insertItems.reduce((collection, item) => collection.concat(Object.values(item as any)), []); // tslint:disable-line:no-any + + const queryResult = await connection.query(insertSQL, queryItems); + + returnItems = this.helpers.returnJsonArray(queryResult[0] as unknown as IDataObject); + } catch (error) { + if (this.continueOnFail()) { + returnItems = this.helpers.returnJsonArray({ error: error.message }); + } else { + await connection.end(); + throw error; + } + } } else if (operation === 'update') { // ---------------------------------- // update // ---------------------------------- - const table = this.getNodeParameter('table', 0) as string; - const updateKey = this.getNodeParameter('updateKey', 0) as string; - const columnString = this.getNodeParameter('columns', 0) as string; - const columns = columnString.split(',').map(column => column.trim()); + try { + const table = this.getNodeParameter('table', 0) as string; + const updateKey = this.getNodeParameter('updateKey', 0) as string; + const columnString = this.getNodeParameter('columns', 0) as string; + const columns = columnString.split(',').map(column => column.trim()); - if (!columns.includes(updateKey)) { - columns.unshift(updateKey); + if (!columns.includes(updateKey)) { + columns.unshift(updateKey); + } + + const updateItems = copyInputItems(items, columns); + const updateSQL = `UPDATE ${table} SET ${columns.map(column => `${column} = ?`).join(',')} WHERE ${updateKey} = ?;`; + const queryQueue = updateItems.map((item) => connection.query(updateSQL, Object.values(item).concat(item[updateKey]))); + const queryResult = await Promise.all(queryQueue); + returnItems = this.helpers.returnJsonArray(queryResult.map(result => result[0]) as unknown as IDataObject[]); + + } catch (error) { + if (this.continueOnFail()) { + returnItems = this.helpers.returnJsonArray({ error: error.message }); + } else { + await connection.end(); + throw error; + } } - - const updateItems = copyInputItems(items, columns); - const updateSQL = `UPDATE ${table} SET ${columns.map(column => `${column} = ?`).join(',')} WHERE ${updateKey} = ?;`; - const queryQueue = updateItems.map((item) => connection.query(updateSQL, Object.values(item).concat(item[updateKey]))); - const queryResult = await Promise.all(queryQueue); - returnItems = this.helpers.returnJsonArray(queryResult.map(result => result[0]) as unknown as IDataObject[]); - } else { - await connection.end(); - throw new NodeOperationError(this.getNode(), `The operation "${operation}" is not supported!`); + if (this.continueOnFail()) { + returnItems = this.helpers.returnJsonArray({ error: `The operation "${operation}" is not supported!` }); + } else { + await connection.end(); + throw new NodeOperationError(this.getNode(), `The operation "${operation}" is not supported!`); + } } await connection.end(); diff --git a/packages/nodes-base/nodes/Nasa/Nasa.node.ts b/packages/nodes-base/nodes/Nasa/Nasa.node.ts index 6a3d249e82..f880c8d803 100644 --- a/packages/nodes-base/nodes/Nasa/Nasa.node.ts +++ b/packages/nodes-base/nodes/Nasa/Nasa.node.ts @@ -933,295 +933,309 @@ export class Nasa implements INodeType { for (let i = 0; i < items.length; i++) { - let endpoint = ''; - let includeCloseApproachData = false; - - // additionalFields are brought up here to prevent repetition on most endpoints. - // The few endpoints like asteroidNeoBrowse that do not have additionalFields - // trigger an error in getNodeParameter dealt with in the catch block. - let additionalFields; try { - additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - } catch (error) { - additionalFields = {} as IDataObject; - } + let endpoint = ''; + let includeCloseApproachData = false; - if (resource === 'astronomyPictureOfTheDay') { - - if (operation === 'get') { - - endpoint = '/planetary/apod'; - - qs.date = moment(additionalFields.date as string).format('YYYY-MM-DD') || moment().format('YYYY-MM-DD'); - - } - } - if (resource === 'asteroidNeoFeed') { - - if (operation === 'get') { - - endpoint = '/neo/rest/v1/feed'; - - propertyName = 'near_earth_objects'; - - // The range defaults to the current date to reduce the number of results. - const currentDate = moment().format('YYYY-MM-DD'); - qs.start_date = moment(additionalFields.startDate as string).format('YYYY-MM-DD') || currentDate; - qs.end_date = moment(additionalFields.endDate as string).format('YYYY-MM-DD') || currentDate; - - } - } - if (resource === 'asteroidNeoLookup') { - - if (operation === 'get') { - - const asteroidId = this.getNodeParameter('asteroidId', i) as IDataObject; - - includeCloseApproachData = additionalFields.includeCloseApproachData as boolean; - - endpoint = `/neo/rest/v1/neo/${asteroidId}`; - - } else { - throw new NodeOperationError(this.getNode(), `The operation '${operation}' is unknown!`); + // additionalFields are brought up here to prevent repetition on most endpoints. + // The few endpoints like asteroidNeoBrowse that do not have additionalFields + // trigger an error in getNodeParameter dealt with in the catch block. + let additionalFields; + try { + additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + } catch (error) { + additionalFields = {} as IDataObject; } - } - if (resource === 'asteroidNeoBrowse') { - - if (operation === 'getAll') { - - returnAll = this.getNodeParameter('returnAll', 0) as boolean; - - if (returnAll === false) { - qs.size = this.getNodeParameter('limit', 0) as number; - } - - propertyName = 'near_earth_objects'; - - endpoint = `/neo/rest/v1/neo/browse`; - - } else { - throw new NodeOperationError(this.getNode(), `The operation '${operation}' is unknown!`); - } - - } - if (resource.startsWith('donki')) { - - if (additionalFields.startDate) { - qs.startDate = moment(additionalFields.startDate as string).format('YYYY-MM-DD'); - } else { - qs.startDate = moment().subtract(30, 'days').format('YYYY-MM-DD'); - } - - if (additionalFields.endDate) { - qs.endDate = moment(additionalFields.endDate as string).format('YYYY-MM-DD'); - } else { - qs.endDate = moment().format('YYYY-MM-DD'); - } - - if (resource === 'donkiCoronalMassEjection') { + if (resource === 'astronomyPictureOfTheDay') { if (operation === 'get') { - endpoint = '/DONKI/CME'; + endpoint = '/planetary/apod'; - } - - } else if (resource === 'donkiGeomagneticStorm') { - - if (operation === 'get') { - - endpoint = '/DONKI/GST'; - - } - - } else if (resource === 'donkiInterplanetaryShock') { - - if (operation === 'get') { - - endpoint = '/DONKI/IPS'; - - qs.location = additionalFields.location as string || 'ALL'; // default per API - qs.catalog = additionalFields.catalog as string || 'ALL'; // default per API - - } - - } else if (resource === 'donkiSolarFlare') { - - if (operation === 'get') { - - endpoint = '/DONKI/FLR'; - - } - - } else if (resource === 'donkiSolarEnergeticParticle') { - - if (operation === 'get') { - - endpoint = '/DONKI/SEP'; - - } - - } else if (resource === 'donkiMagnetopauseCrossing') { - - if (operation === 'get') { - - endpoint = '/DONKI/MPC'; - - } - - } else if (resource === 'donkiRadiationBeltEnhancement') { - - if (operation === 'get') { - - endpoint = '/DONKI/RBE'; - - } - - } else if (resource === 'donkiHighSpeedStream') { - - if (operation === 'get') { - - endpoint = '/DONKI/HSS'; - - } - - } else if (resource === 'donkiWsaEnlilSimulation') { - - if (operation === 'get') { - - endpoint = '/DONKI/WSAEnlilSimulations'; - - } - } else if (resource === 'donkiNotifications') { - - if (operation === 'get') { - - endpoint = '/DONKI/notifications'; - - qs.type = additionalFields.type as string || 'all'; // default per API + qs.date = moment(additionalFields.date as string).format('YYYY-MM-DD') || moment().format('YYYY-MM-DD'); } } + if (resource === 'asteroidNeoFeed') { - } - if (resource === 'earthImagery') { + if (operation === 'get') { - if (operation === 'get') { + endpoint = '/neo/rest/v1/feed'; - endpoint = '/planetary/earth/imagery'; + propertyName = 'near_earth_objects'; - qs.lat = this.getNodeParameter('lat', i) as IDataObject; - qs.lon = this.getNodeParameter('lon', i) as IDataObject; + // The range defaults to the current date to reduce the number of results. + const currentDate = moment().format('YYYY-MM-DD'); + qs.start_date = moment(additionalFields.startDate as string).format('YYYY-MM-DD') || currentDate; + qs.end_date = moment(additionalFields.endDate as string).format('YYYY-MM-DD') || currentDate; - qs.dim = additionalFields.dim as string || 0.025; // default per API + } + } + if (resource === 'asteroidNeoLookup') { + + if (operation === 'get') { + + const asteroidId = this.getNodeParameter('asteroidId', i) as IDataObject; + + includeCloseApproachData = additionalFields.includeCloseApproachData as boolean; + + endpoint = `/neo/rest/v1/neo/${asteroidId}`; - if (additionalFields.date) { - qs.date = moment(additionalFields.date as string).format('YYYY-MM-DD'); } else { - qs.date = moment().format('YYYY-MM-DD'); + throw new NodeOperationError(this.getNode(), `The operation '${operation}' is unknown!`); + } + + } + if (resource === 'asteroidNeoBrowse') { + + if (operation === 'getAll') { + + returnAll = this.getNodeParameter('returnAll', 0) as boolean; + + if (returnAll === false) { + qs.size = this.getNodeParameter('limit', 0) as number; + } + + propertyName = 'near_earth_objects'; + + endpoint = `/neo/rest/v1/neo/browse`; + + } else { + throw new NodeOperationError(this.getNode(), `The operation '${operation}' is unknown!`); + } + + } + if (resource.startsWith('donki')) { + + if (additionalFields.startDate) { + qs.startDate = moment(additionalFields.startDate as string).format('YYYY-MM-DD'); + } else { + qs.startDate = moment().subtract(30, 'days').format('YYYY-MM-DD'); + } + + if (additionalFields.endDate) { + qs.endDate = moment(additionalFields.endDate as string).format('YYYY-MM-DD'); + } else { + qs.endDate = moment().format('YYYY-MM-DD'); + } + + if (resource === 'donkiCoronalMassEjection') { + + if (operation === 'get') { + + endpoint = '/DONKI/CME'; + + } + + } else if (resource === 'donkiGeomagneticStorm') { + + if (operation === 'get') { + + endpoint = '/DONKI/GST'; + + } + + } else if (resource === 'donkiInterplanetaryShock') { + + if (operation === 'get') { + + endpoint = '/DONKI/IPS'; + + qs.location = additionalFields.location as string || 'ALL'; // default per API + qs.catalog = additionalFields.catalog as string || 'ALL'; // default per API + + } + + } else if (resource === 'donkiSolarFlare') { + + if (operation === 'get') { + + endpoint = '/DONKI/FLR'; + + } + + } else if (resource === 'donkiSolarEnergeticParticle') { + + if (operation === 'get') { + + endpoint = '/DONKI/SEP'; + + } + + } else if (resource === 'donkiMagnetopauseCrossing') { + + if (operation === 'get') { + + endpoint = '/DONKI/MPC'; + + } + + } else if (resource === 'donkiRadiationBeltEnhancement') { + + if (operation === 'get') { + + endpoint = '/DONKI/RBE'; + + } + + } else if (resource === 'donkiHighSpeedStream') { + + if (operation === 'get') { + + endpoint = '/DONKI/HSS'; + + } + + } else if (resource === 'donkiWsaEnlilSimulation') { + + if (operation === 'get') { + + endpoint = '/DONKI/WSAEnlilSimulations'; + + } + } else if (resource === 'donkiNotifications') { + + if (operation === 'get') { + + endpoint = '/DONKI/notifications'; + + qs.type = additionalFields.type as string || 'all'; // default per API + + } + } + + } + if (resource === 'earthImagery') { + + if (operation === 'get') { + + endpoint = '/planetary/earth/imagery'; + + qs.lat = this.getNodeParameter('lat', i) as IDataObject; + qs.lon = this.getNodeParameter('lon', i) as IDataObject; + + qs.dim = additionalFields.dim as string || 0.025; // default per API + + if (additionalFields.date) { + qs.date = moment(additionalFields.date as string).format('YYYY-MM-DD'); + } else { + qs.date = moment().format('YYYY-MM-DD'); + } + } + + } + if (resource === 'earthAssets') { + + if (operation === 'get') { + + endpoint = '/planetary/earth/assets'; + + qs.lat = this.getNodeParameter('lat', i) as IDataObject; + qs.lon = this.getNodeParameter('lon', i) as IDataObject; + + qs.dim = additionalFields.dim as string || 0.025; // default per API + + if (additionalFields.date) { + qs.date = moment(additionalFields.date as string).format('YYYY-MM-DD'); + } + } + + if (operation === 'get') { + + endpoint = '/insight_weather/earth/imagery'; + + // Hardcoded because these are the only options available right now. + qs.feedtype = 'json'; + qs.ver = '1.0'; + } } - } - if (resource === 'earthAssets') { + if (returnAll) { + responseData = nasaApiRequestAllItems.call(this, propertyName, 'GET', endpoint, qs); + } else { + responseData = await nasaApiRequest.call(this, 'GET', endpoint, qs); - if (operation === 'get') { - - endpoint = '/planetary/earth/assets'; - - qs.lat = this.getNodeParameter('lat', i) as IDataObject; - qs.lon = this.getNodeParameter('lon', i) as IDataObject; - - qs.dim = additionalFields.dim as string || 0.025; // default per API - - if (additionalFields.date) { - qs.date = moment(additionalFields.date as string).format('YYYY-MM-DD'); + if (propertyName !== '') { + responseData = responseData[propertyName]; } } - if (operation === 'get') { - - endpoint = '/insight_weather/earth/imagery'; - - // Hardcoded because these are the only options available right now. - qs.feedtype = 'json'; - qs.ver = '1.0'; - - } - } - - if (returnAll) { - responseData = nasaApiRequestAllItems.call(this, propertyName, 'GET', endpoint, qs); - } else { - responseData = await nasaApiRequest.call(this, 'GET', endpoint, qs); - - if (propertyName !== '') { - responseData = responseData[propertyName]; - } - } - - if (resource === 'asteroidNeoLookup' && operation === 'get' && !includeCloseApproachData) { - delete responseData.close_approach_data; - } - - if (resource === 'asteroidNeoFeed') { - const date = Object.keys(responseData)[0]; - responseData = responseData[date]; - } - - if (resource === 'earthImagery') { - - const binaryProperty = this.getNodeParameter('binaryPropertyName', i) as string; - - const data = await nasaApiRequest.call(this, 'GET', endpoint, qs, { encoding: null }); - - const newItem: INodeExecutionData = { - json: items[i].json, - binary: {}, - }; - - if (items[i].binary !== undefined) { - Object.assign(newItem.binary, items[i].binary); + if (resource === 'asteroidNeoLookup' && operation === 'get' && !includeCloseApproachData) { + delete responseData.close_approach_data; } - items[i] = newItem; + if (resource === 'asteroidNeoFeed') { + const date = Object.keys(responseData)[0]; + responseData = responseData[date]; + } - items[i].binary![binaryProperty] = await this.helpers.prepareBinaryData(data); - } - - if (resource === 'astronomyPictureOfTheDay') { - download = this.getNodeParameter('download', 0) as boolean; - - if (download === true) { + if (resource === 'earthImagery') { const binaryProperty = this.getNodeParameter('binaryPropertyName', i) as string; - const data = await nasaApiRequest.call(this, 'GET', endpoint, qs, { encoding: null }, responseData.hdurl); - - const filename = (responseData.hdurl as string).split('/'); + const data = await nasaApiRequest.call(this, 'GET', endpoint, qs, { encoding: null }); const newItem: INodeExecutionData = { json: items[i].json, binary: {}, }; - Object.assign(newItem.json, responseData); - if (items[i].binary !== undefined) { Object.assign(newItem.binary, items[i].binary); } items[i] = newItem; - items[i].binary![binaryProperty] = await this.helpers.prepareBinaryData(data, filename[filename.length - 1]); + items[i].binary![binaryProperty] = await this.helpers.prepareBinaryData(data); } - } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else { - returnData.push(responseData as IDataObject); + if (resource === 'astronomyPictureOfTheDay') { + download = this.getNodeParameter('download', 0) as boolean; + + if (download === true) { + + const binaryProperty = this.getNodeParameter('binaryPropertyName', i) as string; + + const data = await nasaApiRequest.call(this, 'GET', endpoint, qs, { encoding: null }, responseData.hdurl); + + const filename = (responseData.hdurl as string).split('/'); + + const newItem: INodeExecutionData = { + json: items[i].json, + binary: {}, + }; + + Object.assign(newItem.json, responseData); + + if (items[i].binary !== undefined) { + Object.assign(newItem.binary, items[i].binary); + } + + items[i] = newItem; + + items[i].binary![binaryProperty] = await this.helpers.prepareBinaryData(data, filename[filename.length - 1]); + } + } + + if (Array.isArray(responseData)) { + returnData.push.apply(returnData, responseData as IDataObject[]); + } else { + returnData.push(responseData as IDataObject); + } + } catch (error) { + if (this.continueOnFail()) { + if (resource === 'earthImagery' && operation === 'get') { + items[i].json = { error: error.message }; + } else if (resource === 'astronomyPictureOfTheDay' && operation === 'get' && download === true) { + items[i].json = { error: error.message }; + } else { + returnData.push({ error: error.message }); + } + continue; + } + throw error; } } diff --git a/packages/nodes-base/nodes/NextCloud/NextCloud.node.ts b/packages/nodes-base/nodes/NextCloud/NextCloud.node.ts index a05ddea926..011ca2e27d 100644 --- a/packages/nodes-base/nodes/NextCloud/NextCloud.node.ts +++ b/packages/nodes-base/nodes/NextCloud/NextCloud.node.ts @@ -806,329 +806,345 @@ export class NextCloud implements INodeType { let qs; for (let i = 0; i < items.length; i++) { - if (resource === 'file') { - if (operation === 'download') { - // ---------------------------------- - // download - // ---------------------------------- - - requestMethod = 'GET'; - endpoint = this.getNodeParameter('path', i) as string; - - } else if (operation === 'upload') { - // ---------------------------------- - // upload - // ---------------------------------- - - requestMethod = 'PUT'; - endpoint = this.getNodeParameter('path', i) as string; - - if (this.getNodeParameter('binaryDataUpload', i) === true) { - // Is binary file to upload - const item = items[i]; - - if (item.binary === undefined) { - throw new NodeOperationError(this.getNode(), 'No binary data exists on item!'); - } - - const propertyNameUpload = this.getNodeParameter('binaryPropertyName', i) as string; - - - if (item.binary[propertyNameUpload] === undefined) { - throw new NodeOperationError(this.getNode(), `No binary data property "${propertyNameUpload}" does not exists on item!`); - } - - body = Buffer.from(item.binary[propertyNameUpload].data, BINARY_ENCODING); - } else { - // Is text file - body = this.getNodeParameter('fileContent', i) as string; - } - } - } else if (resource === 'folder') { - if (operation === 'create') { - // ---------------------------------- - // create - // ---------------------------------- - - requestMethod = 'MKCOL'; - endpoint = this.getNodeParameter('path', i) as string; - - } else if (operation === 'list') { - // ---------------------------------- - // list - // ---------------------------------- - - requestMethod = 'PROPFIND'; - endpoint = this.getNodeParameter('path', i) as string; - - } - } - - if (['file', 'folder'].includes(resource)) { - if (operation === 'copy') { - // ---------------------------------- - // copy - // ---------------------------------- - - requestMethod = 'COPY'; - endpoint = this.getNodeParameter('path', i) as string; - const toPath = this.getNodeParameter('toPath', i) as string; - headers.Destination = `${credentials.webDavUrl}/${encodeURI(toPath)}`; - - } else if (operation === 'delete') { - // ---------------------------------- - // delete - // ---------------------------------- - - requestMethod = 'DELETE'; - endpoint = this.getNodeParameter('path', i) as string; - - } else if (operation === 'move') { - // ---------------------------------- - // move - // ---------------------------------- - - requestMethod = 'MOVE'; - endpoint = this.getNodeParameter('path', i) as string; - const toPath = this.getNodeParameter('toPath', i) as string; - headers.Destination = `${credentials.webDavUrl}/${encodeURI(toPath)}`; - - } - - } else if (resource === 'user') { - if (operation === 'create') { - // ---------------------------------- - // user:create - // ---------------------------------- - - requestMethod = 'POST'; - - endpoint = 'ocs/v1.php/cloud/users'; - - headers['OCS-APIRequest'] = true; - headers['Content-Type'] = 'application/x-www-form-urlencoded'; - - const userid = this.getNodeParameter('userId', i) as string; - const email = this.getNodeParameter('email', i) as string; - - body = `userid=${userid}&email=${email}`; - - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - - if (additionalFields.displayName) { - body += `&displayName=${additionalFields.displayName}`; - } - } - if (operation === 'delete') { - // ---------------------------------- - // user:delete - // ---------------------------------- - - requestMethod = 'DELETE'; - - const userid = this.getNodeParameter('userId', i) as string; - endpoint = `ocs/v1.php/cloud/users/${userid}`; - - headers['OCS-APIRequest'] = true; - headers['Content-Type'] = 'application/x-www-form-urlencoded'; - } - if (operation === 'get') { - // ---------------------------------- - // user:get - // ---------------------------------- - - requestMethod = 'GET'; - - const userid = this.getNodeParameter('userId', i) as string; - endpoint = `ocs/v1.php/cloud/users/${userid}`; - - headers['OCS-APIRequest'] = true; - headers['Content-Type'] = 'application/x-www-form-urlencoded'; - } - if (operation === 'getAll') { - // ---------------------------------- - // user:getAll - // ---------------------------------- - - requestMethod = 'GET'; - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - qs = this.getNodeParameter('options', i) as IDataObject; - if (!returnAll) { - qs.limit = this.getNodeParameter('limit', i) as number; - } - endpoint = `ocs/v1.php/cloud/users`; - - headers['OCS-APIRequest'] = true; - headers['Content-Type'] = 'application/x-www-form-urlencoded'; - } - if (operation === 'update') { - // ---------------------------------- - // user:update - // ---------------------------------- - - requestMethod = 'PUT'; - - const userid = this.getNodeParameter('userId', i) as string; - endpoint = `ocs/v1.php/cloud/users/${userid}`; - - body = Object.entries((this.getNodeParameter('updateFields', i) as IDataObject).field as IDataObject).map(entry => { - const [key, value] = entry; - return `${key}=${value}`; - }).join('&'); - - headers['OCS-APIRequest'] = true; - headers['Content-Type'] = 'application/x-www-form-urlencoded'; - } - } else { - throw new NodeOperationError(this.getNode(), `The resource "${resource}" is not known!`); - } - - // Make sure that the webdav URL does never have a trailing slash because - // one gets added always automatically - let webDavUrl = credentials.webDavUrl as string; - if (webDavUrl.slice(-1) === '/') { - webDavUrl = webDavUrl.slice(0, -1); - } - - let encoding = undefined; - if (resource === 'file' && operation === 'download') { - // Return the data as a buffer - encoding = null; - } - try { - responseData = await nextCloudApiRequest.call(this, requestMethod, endpoint, body, headers, encoding, qs); - } catch (error) { - if (this.continueOnFail() === true) { - returnData.push({ error }); - continue; + if (resource === 'file') { + if (operation === 'download') { + // ---------------------------------- + // download + // ---------------------------------- + + requestMethod = 'GET'; + endpoint = this.getNodeParameter('path', i) as string; + + } else if (operation === 'upload') { + // ---------------------------------- + // upload + // ---------------------------------- + + requestMethod = 'PUT'; + endpoint = this.getNodeParameter('path', i) as string; + + if (this.getNodeParameter('binaryDataUpload', i) === true) { + // Is binary file to upload + const item = items[i]; + + if (item.binary === undefined) { + throw new NodeOperationError(this.getNode(), 'No binary data exists on item!'); + } + + const propertyNameUpload = this.getNodeParameter('binaryPropertyName', i) as string; + + + if (item.binary[propertyNameUpload] === undefined) { + throw new NodeOperationError(this.getNode(), `No binary data property "${propertyNameUpload}" does not exists on item!`); + } + + body = Buffer.from(item.binary[propertyNameUpload].data, BINARY_ENCODING); + } else { + // Is text file + body = this.getNodeParameter('fileContent', i) as string; + } + } + } else if (resource === 'folder') { + if (operation === 'create') { + // ---------------------------------- + // create + // ---------------------------------- + + requestMethod = 'MKCOL'; + endpoint = this.getNodeParameter('path', i) as string; + + } else if (operation === 'list') { + // ---------------------------------- + // list + // ---------------------------------- + + requestMethod = 'PROPFIND'; + endpoint = this.getNodeParameter('path', i) as string; + + } } - throw error; - } + if (['file', 'folder'].includes(resource)) { + if (operation === 'copy') { + // ---------------------------------- + // copy + // ---------------------------------- - if (resource === 'file' && operation === 'download') { + requestMethod = 'COPY'; + endpoint = this.getNodeParameter('path', i) as string; + const toPath = this.getNodeParameter('toPath', i) as string; + headers.Destination = `${credentials.webDavUrl}/${encodeURI(toPath)}`; - const newItem: INodeExecutionData = { - json: items[i].json, - binary: {}, - }; + } else if (operation === 'delete') { + // ---------------------------------- + // delete + // ---------------------------------- - if (items[i].binary !== undefined) { - // Create a shallow copy of the binary data so that the old - // data references which do not get changed still stay behind - // but the incoming data does not get changed. - Object.assign(newItem.binary, items[i].binary); + requestMethod = 'DELETE'; + endpoint = this.getNodeParameter('path', i) as string; + + } else if (operation === 'move') { + // ---------------------------------- + // move + // ---------------------------------- + + requestMethod = 'MOVE'; + endpoint = this.getNodeParameter('path', i) as string; + const toPath = this.getNodeParameter('toPath', i) as string; + headers.Destination = `${credentials.webDavUrl}/${encodeURI(toPath)}`; + + } + + } else if (resource === 'user') { + if (operation === 'create') { + // ---------------------------------- + // user:create + // ---------------------------------- + + requestMethod = 'POST'; + + endpoint = 'ocs/v1.php/cloud/users'; + + headers['OCS-APIRequest'] = true; + headers['Content-Type'] = 'application/x-www-form-urlencoded'; + + const userid = this.getNodeParameter('userId', i) as string; + const email = this.getNodeParameter('email', i) as string; + + body = `userid=${userid}&email=${email}`; + + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + + if (additionalFields.displayName) { + body += `&displayName=${additionalFields.displayName}`; + } + } + if (operation === 'delete') { + // ---------------------------------- + // user:delete + // ---------------------------------- + + requestMethod = 'DELETE'; + + const userid = this.getNodeParameter('userId', i) as string; + endpoint = `ocs/v1.php/cloud/users/${userid}`; + + headers['OCS-APIRequest'] = true; + headers['Content-Type'] = 'application/x-www-form-urlencoded'; + } + if (operation === 'get') { + // ---------------------------------- + // user:get + // ---------------------------------- + + requestMethod = 'GET'; + + const userid = this.getNodeParameter('userId', i) as string; + endpoint = `ocs/v1.php/cloud/users/${userid}`; + + headers['OCS-APIRequest'] = true; + headers['Content-Type'] = 'application/x-www-form-urlencoded'; + } + if (operation === 'getAll') { + // ---------------------------------- + // user:getAll + // ---------------------------------- + + requestMethod = 'GET'; + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + qs = this.getNodeParameter('options', i) as IDataObject; + if (!returnAll) { + qs.limit = this.getNodeParameter('limit', i) as number; + } + endpoint = `ocs/v1.php/cloud/users`; + + headers['OCS-APIRequest'] = true; + headers['Content-Type'] = 'application/x-www-form-urlencoded'; + } + if (operation === 'update') { + // ---------------------------------- + // user:update + // ---------------------------------- + + requestMethod = 'PUT'; + + const userid = this.getNodeParameter('userId', i) as string; + endpoint = `ocs/v1.php/cloud/users/${userid}`; + + body = Object.entries((this.getNodeParameter('updateFields', i) as IDataObject).field as IDataObject).map(entry => { + const [key, value] = entry; + return `${key}=${value}`; + }).join('&'); + + headers['OCS-APIRequest'] = true; + headers['Content-Type'] = 'application/x-www-form-urlencoded'; + } + } else { + throw new NodeOperationError(this.getNode(), `The resource "${resource}" is not known!`); } - items[i] = newItem; + // Make sure that the webdav URL does never have a trailing slash because + // one gets added always automatically + let webDavUrl = credentials.webDavUrl as string; + if (webDavUrl.slice(-1) === '/') { + webDavUrl = webDavUrl.slice(0, -1); + } - const binaryPropertyName = this.getNodeParameter('binaryPropertyName', i) as string; + let encoding = undefined; + if (resource === 'file' && operation === 'download') { + // Return the data as a buffer + encoding = null; + } - items[i].binary![binaryPropertyName] = await this.helpers.prepareBinaryData(responseData, endpoint); + try { + responseData = await nextCloudApiRequest.call(this, requestMethod, endpoint, body, headers, encoding, qs); + } catch (error) { + if (this.continueOnFail()) { + if (resource === 'file' && operation === 'download') { + items[i].json = { error: error.message }; + } else { + returnData.push({ error: error.message }); + } + continue; + } - } else if (resource === 'user') { + throw error; + } - if (operation !== 'getAll') { + if (resource === 'file' && operation === 'download') { + + const newItem: INodeExecutionData = { + json: items[i].json, + binary: {}, + }; + + if (items[i].binary !== undefined) { + // Create a shallow copy of the binary data so that the old + // data references which do not get changed still stay behind + // but the incoming data does not get changed. + Object.assign(newItem.binary, items[i].binary); + } + + items[i] = newItem; + + const binaryPropertyName = this.getNodeParameter('binaryPropertyName', i) as string; + + items[i].binary![binaryPropertyName] = await this.helpers.prepareBinaryData(responseData, endpoint); + + } else if (resource === 'user') { + + if (operation !== 'getAll') { + + const jsonResponseData: IDataObject = await new Promise((resolve, reject) => { + parseString(responseData, { explicitArray: false }, (err, data) => { + if (err) { + return reject(err); + } + + if (data.ocs.meta.status !== 'ok') { + return reject(new Error(data.ocs.meta.message || data.ocs.meta.status)); + } + + if (operation === 'delete' || operation === 'update') { + resolve(data.ocs.meta as IDataObject); + } else { + resolve(data.ocs.data as IDataObject); + } + }); + }); + + returnData.push(jsonResponseData as IDataObject); + } else { + + const jsonResponseData: IDataObject[] = await new Promise((resolve, reject) => { + parseString(responseData, { explicitArray: false }, (err, data) => { + if (err) { + return reject(err); + } + + if (data.ocs.meta.status !== 'ok') { + return reject(new Error(data.ocs.meta.message)); + } + + if (typeof (data.ocs.data.users.element) === 'string') { + resolve([data.ocs.data.users.element] as IDataObject[]); + } else { + resolve(data.ocs.data.users.element as IDataObject[]); + } + }); + }); + + jsonResponseData.forEach(value => { + returnData.push({ id: value } as IDataObject); + }); + } + + } else if (resource === 'folder' && operation === 'list') { const jsonResponseData: IDataObject = await new Promise((resolve, reject) => { parseString(responseData, { explicitArray: false }, (err, data) => { if (err) { return reject(err); } - - if (data.ocs.meta.status !== 'ok') { - return reject(new Error(data.ocs.meta.message || data.ocs.meta.status)); - } - - if (operation === 'delete' || operation === 'update') { - resolve(data.ocs.meta as IDataObject); - } else { - resolve(data.ocs.data as IDataObject); - } + resolve(data as IDataObject); }); }); - returnData.push(jsonResponseData as IDataObject); - } else { + const propNames: { [key: string]: string } = { + 'd:getlastmodified': 'lastModified', + 'd:getcontentlength': 'contentLength', + 'd:getcontenttype': 'contentType', + }; - const jsonResponseData: IDataObject[] = await new Promise((resolve, reject) => { - parseString(responseData, { explicitArray: false }, (err, data) => { - if (err) { - return reject(err); + if (jsonResponseData['d:multistatus'] !== undefined && + jsonResponseData['d:multistatus'] !== null && + (jsonResponseData['d:multistatus'] as IDataObject)['d:response'] !== undefined && + (jsonResponseData['d:multistatus'] as IDataObject)['d:response'] !== null) { + let skippedFirst = false; + + // @ts-ignore + for (const item of jsonResponseData['d:multistatus']['d:response']) { + if (skippedFirst === false) { + skippedFirst = true; + continue; + } + const newItem: IDataObject = {}; + + newItem.path = item['d:href'].slice(19); + + const props = item['d:propstat'][0]['d:prop']; + + // Get the props and save them under a proper name + for (const propName of Object.keys(propNames)) { + if (props[propName] !== undefined) { + newItem[propNames[propName]] = props[propName]; + } } - if (data.ocs.meta.status !== 'ok') { - return reject(new Error(data.ocs.meta.message)); - } - - if (typeof (data.ocs.data.users.element) === 'string') { - resolve([data.ocs.data.users.element] as IDataObject[]); + if (props['d:resourcetype'] === '') { + newItem.type = 'file'; } else { - resolve(data.ocs.data.users.element as IDataObject[]); + newItem.type = 'folder'; } - }); - }); + newItem.eTag = props['d:getetag'].slice(1, -1); - jsonResponseData.forEach(value => { - returnData.push({ id: value } as IDataObject); - }); - } - - } else if (resource === 'folder' && operation === 'list') { - - const jsonResponseData: IDataObject = await new Promise((resolve, reject) => { - parseString(responseData, { explicitArray: false }, (err, data) => { - if (err) { - return reject(err); + returnData.push(newItem as IDataObject); } - resolve(data as IDataObject); - }); - }); - - const propNames: { [key: string]: string } = { - 'd:getlastmodified': 'lastModified', - 'd:getcontentlength': 'contentLength', - 'd:getcontenttype': 'contentType', - }; - - if (jsonResponseData['d:multistatus'] !== undefined && - jsonResponseData['d:multistatus'] !== null && - (jsonResponseData['d:multistatus'] as IDataObject)['d:response'] !== undefined && - (jsonResponseData['d:multistatus'] as IDataObject)['d:response'] !== null) { - let skippedFirst = false; - - // @ts-ignore - for (const item of jsonResponseData['d:multistatus']['d:response']) { - if (skippedFirst === false) { - skippedFirst = true; - continue; - } - const newItem: IDataObject = {}; - - newItem.path = item['d:href'].slice(19); - - const props = item['d:propstat'][0]['d:prop']; - - // Get the props and save them under a proper name - for (const propName of Object.keys(propNames)) { - if (props[propName] !== undefined) { - newItem[propNames[propName]] = props[propName]; - } - } - - if (props['d:resourcetype'] === '') { - newItem.type = 'file'; - } else { - newItem.type = 'folder'; - } - newItem.eTag = props['d:getetag'].slice(1, -1); - - returnData.push(newItem as IDataObject); } + } else { + returnData.push(responseData as IDataObject); } - } else { - returnData.push(responseData as IDataObject); + } catch (error) { + if (this.continueOnFail()) { + if (resource === 'file' && operation === 'download') { + items[i].json = { error: error.message }; + } else { + returnData.push({ error: error.message }); + } + continue; + } + throw error; } } diff --git a/packages/nodes-base/nodes/OpenThesaurus/OpenThesaurus.node.ts b/packages/nodes-base/nodes/OpenThesaurus/OpenThesaurus.node.ts index 4b8734d529..76855f8f69 100644 --- a/packages/nodes-base/nodes/OpenThesaurus/OpenThesaurus.node.ts +++ b/packages/nodes-base/nodes/OpenThesaurus/OpenThesaurus.node.ts @@ -145,21 +145,29 @@ export class OpenThesaurus implements INodeType { const operation = this.getNodeParameter('operation', 0) as string; for (let i = 0; i < length; i++) { - if (operation === 'getSynonyms') { - const text = this.getNodeParameter('text', i) as string; - const options = this.getNodeParameter('options', i) as IDataObject; + try { + if (operation === 'getSynonyms') { + const text = this.getNodeParameter('text', i) as string; + const options = this.getNodeParameter('options', i) as IDataObject; - qs.q = text; + qs.q = text; - Object.assign(qs, options); + Object.assign(qs, options); - responseData = await openThesaurusApiRequest.call(this, 'GET', `/synonyme/search`, {}, qs); - responseData = responseData.synsets; - } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else { - returnData.push(responseData as IDataObject); + responseData = await openThesaurusApiRequest.call(this, 'GET', `/synonyme/search`, {}, qs); + responseData = responseData.synsets; + } + if (Array.isArray(responseData)) { + returnData.push.apply(returnData, responseData as IDataObject[]); + } else { + returnData.push(responseData as IDataObject); + } + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } } return [this.helpers.returnJsonArray(returnData)]; diff --git a/packages/nodes-base/nodes/OpenWeatherMap.node.ts b/packages/nodes-base/nodes/OpenWeatherMap.node.ts index 305d7e8c2a..70821ea19a 100644 --- a/packages/nodes-base/nodes/OpenWeatherMap.node.ts +++ b/packages/nodes-base/nodes/OpenWeatherMap.node.ts @@ -223,65 +223,76 @@ export class OpenWeatherMap implements INodeType { let qs: IDataObject; for (let i = 0; i < items.length; i++) { - // Set base data - qs = { - APPID: credentials.accessToken, - units: this.getNodeParameter('format', i) as string, - }; - // Get the location - locationSelection = this.getNodeParameter('locationSelection', i) as string; - if (locationSelection === 'cityName') { - qs.q = this.getNodeParameter('cityName', i) as string; - } else if (locationSelection === 'cityId') { - qs.id = this.getNodeParameter('cityId', i) as number; - } else if (locationSelection === 'coordinates') { - qs.lat = this.getNodeParameter('latitude', i) as string; - qs.lon = this.getNodeParameter('longitude', i) as string; - } else if (locationSelection === 'zipCode') { - qs.zip = this.getNodeParameter('zipCode', i) as string; - } else { - throw new NodeOperationError(this.getNode(), `The locationSelection "${locationSelection}" is not known!`); - } - - // Get the language - language = this.getNodeParameter('language', i) as string; - if (language) { - qs.lang = language; - } - - if (operation === 'currentWeather') { - // ---------------------------------- - // currentWeather - // ---------------------------------- - - endpoint = 'weather'; - } else if (operation === '5DayForecast') { - // ---------------------------------- - // 5DayForecast - // ---------------------------------- - - endpoint = 'forecast'; - } else { - throw new NodeOperationError(this.getNode(), `The operation "${operation}" is not known!`); - } - - const options: OptionsWithUri = { - method: 'GET', - qs, - uri: `https://api.openweathermap.org/data/2.5/${endpoint}`, - json: true, - }; - - let responseData; try { - responseData = await this.helpers.request(options); + + // Set base data + qs = { + APPID: credentials.accessToken, + units: this.getNodeParameter('format', i) as string, + }; + + // Get the location + locationSelection = this.getNodeParameter('locationSelection', i) as string; + if (locationSelection === 'cityName') { + qs.q = this.getNodeParameter('cityName', i) as string; + } else if (locationSelection === 'cityId') { + qs.id = this.getNodeParameter('cityId', i) as number; + } else if (locationSelection === 'coordinates') { + qs.lat = this.getNodeParameter('latitude', i) as string; + qs.lon = this.getNodeParameter('longitude', i) as string; + } else if (locationSelection === 'zipCode') { + qs.zip = this.getNodeParameter('zipCode', i) as string; + } else { + throw new NodeOperationError(this.getNode(), `The locationSelection "${locationSelection}" is not known!`); + } + + // Get the language + language = this.getNodeParameter('language', i) as string; + if (language) { + qs.lang = language; + } + + if (operation === 'currentWeather') { + // ---------------------------------- + // currentWeather + // ---------------------------------- + + endpoint = 'weather'; + } else if (operation === '5DayForecast') { + // ---------------------------------- + // 5DayForecast + // ---------------------------------- + + endpoint = 'forecast'; + } else { + throw new NodeOperationError(this.getNode(), `The operation "${operation}" is not known!`); + } + + const options: OptionsWithUri = { + method: 'GET', + qs, + uri: `https://api.openweathermap.org/data/2.5/${endpoint}`, + json: true, + }; + + let responseData; + try { + responseData = await this.helpers.request(options); + } catch (error) { + throw new NodeApiError(this.getNode(), error); + } + + + returnData.push(responseData as IDataObject); + } catch (error) { - throw new NodeApiError(this.getNode(), error); + if (this.continueOnFail()) { + returnData.push({json:{ error: error.message }}); + continue; + } + throw error; } - - - returnData.push(responseData as IDataObject); } return [this.helpers.returnJsonArray(returnData)]; diff --git a/packages/nodes-base/nodes/Orbit/Orbit.node.ts b/packages/nodes-base/nodes/Orbit/Orbit.node.ts index de80e61123..a19aa7f77d 100644 --- a/packages/nodes-base/nodes/Orbit/Orbit.node.ts +++ b/packages/nodes-base/nodes/Orbit/Orbit.node.ts @@ -149,314 +149,333 @@ export class Orbit implements INodeType { 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 === 'activity') { - if (operation === 'create') { - const workspaceId = this.getNodeParameter('workspaceId', i) as string; - const memberId = this.getNodeParameter('memberId', i) as string; - const title = this.getNodeParameter('title', i) as string; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const body: IDataObject = { - title, - }; - if (additionalFields.description) { - body.description = additionalFields.description as string; - } - if (additionalFields.link) { - body.link = additionalFields.link as string; - } - if (additionalFields.linkText) { - body.link_text = additionalFields.linkText as string; - } - if (additionalFields.activityType) { - body.activity_type = additionalFields.activityType as string; - } - if (additionalFields.key) { - body.key = additionalFields.key as string; - } - if (additionalFields.occurredAt) { - body.occurred_at = additionalFields.occurredAt as string; - } + try { + if (resource === 'activity') { + if (operation === 'create') { + const workspaceId = this.getNodeParameter('workspaceId', i) as string; + const memberId = this.getNodeParameter('memberId', i) as string; + const title = this.getNodeParameter('title', i) as string; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const body: IDataObject = { + title, + }; + if (additionalFields.description) { + body.description = additionalFields.description as string; + } + if (additionalFields.link) { + body.link = additionalFields.link as string; + } + if (additionalFields.linkText) { + body.link_text = additionalFields.linkText as string; + } + if (additionalFields.activityType) { + body.activity_type = additionalFields.activityType as string; + } + if (additionalFields.key) { + body.key = additionalFields.key as string; + } + if (additionalFields.occurredAt) { + body.occurred_at = additionalFields.occurredAt as string; + } - responseData = await orbitApiRequest.call(this, 'POST', `/${workspaceId}/members/${memberId}/activities`, body); - responseData = responseData.data; - } - if (operation === 'getAll') { - const workspaceId = this.getNodeParameter('workspaceId', i) as string; - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - const filters = this.getNodeParameter('filters', i) as IDataObject; - let endpoint = `/${workspaceId}/activities`; - if (filters.memberId) { - endpoint = `/${workspaceId}/members/${filters.memberId}/activities`; + responseData = await orbitApiRequest.call(this, 'POST', `/${workspaceId}/members/${memberId}/activities`, body); + responseData = responseData.data; } - if (returnAll === true) { - responseData = await orbitApiRequestAllItems.call(this, 'data', 'GET', endpoint, {}, qs); - } else { - qs.limit = this.getNodeParameter('limit', 0) as boolean; - responseData = await orbitApiRequestAllItems.call(this, 'data', 'GET', endpoint, {}, qs); - responseData = responseData.splice(0, qs.limit); + if (operation === 'getAll') { + const workspaceId = this.getNodeParameter('workspaceId', i) as string; + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + const filters = this.getNodeParameter('filters', i) as IDataObject; + let endpoint = `/${workspaceId}/activities`; + if (filters.memberId) { + endpoint = `/${workspaceId}/members/${filters.memberId}/activities`; + } + if (returnAll === true) { + responseData = await orbitApiRequestAllItems.call(this, 'data', 'GET', endpoint, {}, qs); + } else { + qs.limit = this.getNodeParameter('limit', 0) as boolean; + responseData = await orbitApiRequestAllItems.call(this, 'data', 'GET', endpoint, {}, qs); + responseData = responseData.splice(0, qs.limit); + } } } - } - if (resource === 'member') { - if (operation === 'upsert') { - const workspaceId = this.getNodeParameter('workspaceId', i) as string; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const member: IDataObject = {}; - const identity: IDataObject = {}; - if (additionalFields.bio) { - member.bio = additionalFields.bio as string; - } - if (additionalFields.birthday) { - member.birthday = moment(additionalFields.birthday as string).format('MM-DD-YYYY'); - } - if (additionalFields.company) { - member.company = additionalFields.company as string; - } - if (additionalFields.location) { - member.location = additionalFields.location as string; - } - if (additionalFields.name) { - member.name = additionalFields.name as string; - } - if (additionalFields.bio) { - member.bio = additionalFields.bio as string; - } - if (additionalFields.pronouns) { - member.pronouns = additionalFields.pronouns as string; - } - if (additionalFields.shippingAddress) { - member.shipping_address = additionalFields.shippingAddress as string; - } - if (additionalFields.slug) { - member.slug = additionalFields.slug as string; - } - if (additionalFields.tagsToAdd) { - member.tags_to_add = additionalFields.tagsToAdd as string; - } - if (additionalFields.tagList) { - member.tag_list = additionalFields.tagList as string; - } - if (additionalFields.tshirt) { - member.tshirt = additionalFields.tshirt as string; - } - if (additionalFields.hasOwnProperty('teammate')) { - member.teammate = additionalFields.teammate as boolean; - } - if (additionalFields.url) { - member.url = additionalFields.url as string; - } + if (resource === 'member') { + if (operation === 'upsert') { + const workspaceId = this.getNodeParameter('workspaceId', i) as string; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const member: IDataObject = {}; + const identity: IDataObject = {}; + if (additionalFields.bio) { + member.bio = additionalFields.bio as string; + } + if (additionalFields.birthday) { + member.birthday = moment(additionalFields.birthday as string).format('MM-DD-YYYY'); + } + if (additionalFields.company) { + member.company = additionalFields.company as string; + } + if (additionalFields.location) { + member.location = additionalFields.location as string; + } + if (additionalFields.name) { + member.name = additionalFields.name as string; + } + if (additionalFields.bio) { + member.bio = additionalFields.bio as string; + } + if (additionalFields.pronouns) { + member.pronouns = additionalFields.pronouns as string; + } + if (additionalFields.shippingAddress) { + member.shipping_address = additionalFields.shippingAddress as string; + } + if (additionalFields.slug) { + member.slug = additionalFields.slug as string; + } + if (additionalFields.tagsToAdd) { + member.tags_to_add = additionalFields.tagsToAdd as string; + } + if (additionalFields.tagList) { + member.tag_list = additionalFields.tagList as string; + } + if (additionalFields.tshirt) { + member.tshirt = additionalFields.tshirt as string; + } + if (additionalFields.hasOwnProperty('teammate')) { + member.teammate = additionalFields.teammate as boolean; + } + if (additionalFields.url) { + member.url = additionalFields.url as string; + } - const data = (this.getNodeParameter('identityUi', i) as IDataObject).identityValue as IDataObject; - if (data) { - if (['github', 'twitter', 'discourse'].includes(data.source as string)) { - identity.source = data.source as string; - const searchBy = data.searchBy as string; - if (searchBy === 'id') { - identity.uid = data.id as string; + const data = (this.getNodeParameter('identityUi', i) as IDataObject).identityValue as IDataObject; + if (data) { + if (['github', 'twitter', 'discourse'].includes(data.source as string)) { + identity.source = data.source as string; + const searchBy = data.searchBy as string; + if (searchBy === 'id') { + identity.uid = data.id as string; + } else { + identity.username = data.username as string; + } + if (data.source === 'discourse') { + identity.source_host = data.host as string; + } } else { - identity.username = data.username as string; + //it's email + identity.email = data.email as string; } - if (data.source === 'discourse') { - identity.source_host = data.host as string; + } + + responseData = await orbitApiRequest.call(this, 'POST', `/${workspaceId}/members`, { member, identity }); + responseData = responseData.data; + } + if (operation === 'delete') { + const workspaceId = this.getNodeParameter('workspaceId', i) as string; + const memberId = this.getNodeParameter('memberId', i) as string; + responseData = await orbitApiRequest.call(this, 'DELETE', `/${workspaceId}/members/${memberId}`); + responseData = { success: true }; + } + if (operation === 'get') { + const workspaceId = this.getNodeParameter('workspaceId', i) as string; + const memberId = this.getNodeParameter('memberId', i) as string; + const resolve = this.getNodeParameter('resolveIdentities', 0) as boolean; + responseData = await orbitApiRequest.call(this, 'GET', `/${workspaceId}/members/${memberId}`); + if (resolve === true) { + resolveIdentities(responseData); + } + responseData = responseData.data; + } + if (operation === 'getAll') { + const workspaceId = this.getNodeParameter('workspaceId', i) as string; + const returnAll = this.getNodeParameter('returnAll', 0) as boolean; + const options = this.getNodeParameter('options', i) as IDataObject; + Object.assign(qs, options); + qs.resolveIdentities = this.getNodeParameter('resolveIdentities', 0) as boolean; + if (returnAll === true) { + responseData = await orbitApiRequestAllItems.call(this, 'data', 'GET', `/${workspaceId}/members`, {}, qs); + } else { + qs.limit = this.getNodeParameter('limit', 0) as boolean; + responseData = await orbitApiRequestAllItems.call(this, 'data', 'GET', `/${workspaceId}/members`, {}, qs); + responseData = responseData.splice(0, qs.limit); + } + } + if (operation === 'lookup') { + const workspaceId = this.getNodeParameter('workspaceId', i) as string; + const source = this.getNodeParameter('source', i) as string; + + if (['github', 'twitter', 'discourse'].includes(source)) { + qs.source = this.getNodeParameter('source', i) as string; + const searchBy = this.getNodeParameter('searchBy', i) as string; + if (searchBy === 'id') { + qs.uid = this.getNodeParameter('id', i) as string; + } else { + qs.username = this.getNodeParameter('username', i) as string; + } + if (source === 'discourse') { + qs.source_host = this.getNodeParameter('host', i) as string; } } else { //it's email - identity.email = data.email as string; + qs.email = this.getNodeParameter('email', i) as string; } - } - responseData = await orbitApiRequest.call(this, 'POST', `/${workspaceId}/members`, { member, identity }); - responseData = responseData.data; - } - if (operation === 'delete') { - const workspaceId = this.getNodeParameter('workspaceId', i) as string; - const memberId = this.getNodeParameter('memberId', i) as string; - responseData = await orbitApiRequest.call(this, 'DELETE', `/${workspaceId}/members/${memberId}`); - responseData = { success: true }; - } - if (operation === 'get') { - const workspaceId = this.getNodeParameter('workspaceId', i) as string; - const memberId = this.getNodeParameter('memberId', i) as string; - const resolve = this.getNodeParameter('resolveIdentities', 0) as boolean; - responseData = await orbitApiRequest.call(this, 'GET', `/${workspaceId}/members/${memberId}`); - if (resolve === true) { - resolveIdentities(responseData); + responseData = await orbitApiRequest.call(this, 'GET', `/${workspaceId}/members/find`, {}, qs); + responseData = responseData.data; } - responseData = responseData.data; - } - if (operation === 'getAll') { - const workspaceId = this.getNodeParameter('workspaceId', i) as string; - const returnAll = this.getNodeParameter('returnAll', 0) as boolean; - const options = this.getNodeParameter('options', i) as IDataObject; - Object.assign(qs, options); - qs.resolveIdentities = this.getNodeParameter('resolveIdentities', 0) as boolean; - if (returnAll === true) { - responseData = await orbitApiRequestAllItems.call(this, 'data', 'GET', `/${workspaceId}/members`, {}, qs); - } else { - qs.limit = this.getNodeParameter('limit', 0) as boolean; - responseData = await orbitApiRequestAllItems.call(this, 'data', 'GET', `/${workspaceId}/members`, {}, qs); - responseData = responseData.splice(0, qs.limit); - } - } - if (operation === 'lookup') { - const workspaceId = this.getNodeParameter('workspaceId', i) as string; - const source = this.getNodeParameter('source', i) as string; + if (operation === 'update') { + const workspaceId = this.getNodeParameter('workspaceId', i) as string; + const memberId = this.getNodeParameter('memberId', i) as string; + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + const body: IDataObject = { + }; + if (updateFields.bio) { + body.bio = updateFields.bio as string; + } + if (updateFields.birthday) { + body.birthday = moment(updateFields.birthday as string).format('MM-DD-YYYY'); + } + if (updateFields.company) { + body.company = updateFields.company as string; + } + if (updateFields.location) { + body.location = updateFields.location as string; + } + if (updateFields.name) { + body.name = updateFields.name as string; + } + if (updateFields.bio) { + body.bio = updateFields.bio as string; + } + if (updateFields.pronouns) { + body.pronouns = updateFields.pronouns as string; + } + if (updateFields.shippingAddress) { + body.shipping_address = updateFields.shippingAddress as string; + } + if (updateFields.slug) { + body.slug = updateFields.slug as string; + } + if (updateFields.tagsToAdd) { + body.tags_to_add = updateFields.tagsToAdd as string; + } + if (updateFields.tagList) { + body.tag_list = updateFields.tagList as string; + } + if (updateFields.tshirt) { + body.tshirt = updateFields.tshirt as string; + } + if (updateFields.hasOwnProperty('teammate')) { + body.teammate = updateFields.teammate as boolean; + } + if (updateFields.url) { + body.url = updateFields.url as string; + } - if (['github', 'twitter', 'discourse'].includes(source)) { - qs.source = this.getNodeParameter('source', i) as string; - const searchBy = this.getNodeParameter('searchBy', i) as string; - if (searchBy === 'id') { - qs.uid = this.getNodeParameter('id', i) as string; + responseData = await orbitApiRequest.call(this, 'PUT', `/${workspaceId}/members/${memberId}`, body); + responseData = { success: true }; + } + } + if (resource === 'note') { + if (operation === 'create') { + const workspaceId = this.getNodeParameter('workspaceId', i) as string; + const memberId = this.getNodeParameter('memberId', i) as string; + const note = this.getNodeParameter('note', i) as string; + + responseData = await orbitApiRequest.call(this, 'POST', `/${workspaceId}/members/${memberId}/notes`, { body: note }); + responseData = responseData.data; + } + if (operation === 'getAll') { + const workspaceId = this.getNodeParameter('workspaceId', i) as string; + const memberId = this.getNodeParameter('memberId', i) as string; + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + qs.resolveMember = this.getNodeParameter('resolveMember', 0) as boolean; + if (returnAll === true) { + responseData = await orbitApiRequestAllItems.call(this, 'data', 'GET', `/${workspaceId}/members/${memberId}/notes`, {}, qs); } else { - qs.username = this.getNodeParameter('username', i) as string; + qs.limit = this.getNodeParameter('limit', 0) as boolean; + responseData = await orbitApiRequestAllItems.call(this, 'data', 'GET', `/${workspaceId}/members/${memberId}/notes`, {}, qs); + responseData = responseData.splice(0, qs.limit); } - if (source === 'discourse') { - qs.source_host = this.getNodeParameter('host', i) as string; + } + if (operation === 'update') { + const workspaceId = this.getNodeParameter('workspaceId', i) as string; + const memberId = this.getNodeParameter('memberId', i) as string; + const noteId = this.getNodeParameter('noteId', i) as string; + const note = this.getNodeParameter('note', i) as string; + + responseData = await orbitApiRequest.call(this, 'PUT', `/${workspaceId}/members/${memberId}/notes/${noteId}`, { body: note }); + responseData = { success: true }; + } + } + if (resource === 'post') { + if (operation === 'create') { + const workspaceId = this.getNodeParameter('workspaceId', i) as string; + const memberId = this.getNodeParameter('memberId', i) as string; + const url = this.getNodeParameter('url', i) as string; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const body: IDataObject = { + type: 'post', + activity_type: 'post', + url, + }; + if (additionalFields.publishedAt) { + body.occurred_at = additionalFields.publishedAt as string; + delete body.publishedAt; } - } else { - //it's email - qs.email = this.getNodeParameter('email', i) as string; - } - responseData = await orbitApiRequest.call(this, 'GET', `/${workspaceId}/members/find`, {}, qs); - responseData = responseData.data; - } - if (operation === 'update') { - const workspaceId = this.getNodeParameter('workspaceId', i) as string; - const memberId = this.getNodeParameter('memberId', i) as string; - const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; - const body: IDataObject = { - }; - if (updateFields.bio) { - body.bio = updateFields.bio as string; + responseData = await orbitApiRequest.call(this, 'POST', `/${workspaceId}/members/${memberId}/activities/`, body); + responseData = responseData.data; } - if (updateFields.birthday) { - body.birthday = moment(updateFields.birthday as string).format('MM-DD-YYYY'); - } - if (updateFields.company) { - body.company = updateFields.company as string; - } - if (updateFields.location) { - body.location = updateFields.location as string; - } - if (updateFields.name) { - body.name = updateFields.name as string; - } - if (updateFields.bio) { - body.bio = updateFields.bio as string; - } - if (updateFields.pronouns) { - body.pronouns = updateFields.pronouns as string; - } - if (updateFields.shippingAddress) { - body.shipping_address = updateFields.shippingAddress as string; - } - if (updateFields.slug) { - body.slug = updateFields.slug as string; - } - if (updateFields.tagsToAdd) { - body.tags_to_add = updateFields.tagsToAdd as string; - } - if (updateFields.tagList) { - body.tag_list = updateFields.tagList as string; - } - if (updateFields.tshirt) { - body.tshirt = updateFields.tshirt as string; - } - if (updateFields.hasOwnProperty('teammate')) { - body.teammate = updateFields.teammate as boolean; - } - if (updateFields.url) { - body.url = updateFields.url as string; + if (operation === 'getAll') { + const workspaceId = this.getNodeParameter('workspaceId', i) as string; + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + const filters = this.getNodeParameter('filters', i) as IDataObject; + let endpoint = `/${workspaceId}/activities`; + qs.type = 'content'; + if (filters.memberId) { + endpoint = `/${workspaceId}/members/${filters.memberId}/activities`; + } + if (returnAll === true) { + responseData = await orbitApiRequestAllItems.call(this, 'data', 'GET', endpoint, {}, qs); + } else { + qs.limit = this.getNodeParameter('limit', 0) as boolean; + responseData = await orbitApiRequestAllItems.call(this, 'data', 'GET', endpoint, {}, qs); + responseData = responseData.splice(0, qs.limit); + } } + if (operation === 'delete') { + const workspaceId = this.getNodeParameter('workspaceId', i) as string; + const memberId = this.getNodeParameter('memberId', i) as string; + const postId = this.getNodeParameter('postId', i) as string; - responseData = await orbitApiRequest.call(this, 'PUT', `/${workspaceId}/members/${memberId}`, body); - responseData = { success: true }; - } - } - if (resource === 'note') { - if (operation === 'create') { - const workspaceId = this.getNodeParameter('workspaceId', i) as string; - const memberId = this.getNodeParameter('memberId', i) as string; - const note = this.getNodeParameter('note', i) as string; - - responseData = await orbitApiRequest.call(this, 'POST', `/${workspaceId}/members/${memberId}/notes`, { body: note }); - responseData = responseData.data; - } - if (operation === 'getAll') { - const workspaceId = this.getNodeParameter('workspaceId', i) as string; - const memberId = this.getNodeParameter('memberId', i) as string; - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - qs.resolveMember = this.getNodeParameter('resolveMember', 0) as boolean; - if (returnAll === true) { - responseData = await orbitApiRequestAllItems.call(this, 'data', 'GET', `/${workspaceId}/members/${memberId}/notes`, {}, qs); - } else { - qs.limit = this.getNodeParameter('limit', 0) as boolean; - responseData = await orbitApiRequestAllItems.call(this, 'data', 'GET', `/${workspaceId}/members/${memberId}/notes`, {}, qs); - responseData = responseData.splice(0, qs.limit); + responseData = await orbitApiRequest.call(this, 'DELETE', `/${workspaceId}/members/${memberId}/activities/${postId}`); + responseData = { success: true }; } } - if (operation === 'update') { - const workspaceId = this.getNodeParameter('workspaceId', i) as string; - const memberId = this.getNodeParameter('memberId', i) as string; - const noteId = this.getNodeParameter('noteId', i) as string; - const note = this.getNodeParameter('note', i) as string; - - responseData = await orbitApiRequest.call(this, 'PUT', `/${workspaceId}/members/${memberId}/notes/${noteId}`, { body: note }); - responseData = { success: true }; + if (Array.isArray(responseData)) { + returnData.push.apply(returnData, responseData as IDataObject[]); + } else { + returnData.push(responseData as IDataObject); } - } - if (resource === 'post') { - if (operation === 'create') { - const workspaceId = this.getNodeParameter('workspaceId', i) as string; - const memberId = this.getNodeParameter('memberId', i) as string; - const url = this.getNodeParameter('url', i) as string; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const body: IDataObject = { - type: 'post', - activity_type: 'post', - url, - }; - if (additionalFields.publishedAt) { - body.occurred_at = additionalFields.publishedAt as string; - delete body.publishedAt; - } - - responseData = await orbitApiRequest.call(this, 'POST', `/${workspaceId}/members/${memberId}/activities/`, body); - responseData = responseData.data; + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; } - if (operation === 'getAll') { - const workspaceId = this.getNodeParameter('workspaceId', i) as string; - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - const filters = this.getNodeParameter('filters', i) as IDataObject; - let endpoint = `/${workspaceId}/activities`; - qs.type = 'content'; - if (filters.memberId) { - endpoint = `/${workspaceId}/members/${filters.memberId}/activities`; - } - if (returnAll === true) { - responseData = await orbitApiRequestAllItems.call(this, 'data', 'GET', endpoint, {}, qs); - } else { - qs.limit = this.getNodeParameter('limit', 0) as boolean; - responseData = await orbitApiRequestAllItems.call(this, 'data', 'GET', endpoint, {}, qs); - responseData = responseData.splice(0, qs.limit); - } - } - if (operation === 'delete') { - const workspaceId = this.getNodeParameter('workspaceId', i) as string; - const memberId = this.getNodeParameter('memberId', i) as string; - const postId = this.getNodeParameter('postId', i) as string; - - responseData = await orbitApiRequest.call(this, 'DELETE', `/${workspaceId}/members/${memberId}/activities/${postId}`); - responseData = { success: true }; - } - } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else { - returnData.push(responseData as IDataObject); + throw error; } } return [this.helpers.returnJsonArray(returnData)]; } } + + + + + + + + + + + diff --git a/packages/nodes-base/nodes/Paddle/Paddle.node.ts b/packages/nodes-base/nodes/Paddle/Paddle.node.ts index 6fdc69cf7b..f302d4bc34 100644 --- a/packages/nodes-base/nodes/Paddle/Paddle.node.ts +++ b/packages/nodes-base/nodes/Paddle/Paddle.node.ts @@ -191,323 +191,330 @@ export class Paddle implements INodeType { 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 === 'coupon') { - if (operation === 'create') { - const jsonParameters = this.getNodeParameter('jsonParameters', i) as boolean; + try { + if (resource === 'coupon') { + if (operation === 'create') { + const jsonParameters = this.getNodeParameter('jsonParameters', i) as boolean; - if (jsonParameters) { - const additionalFieldsJson = this.getNodeParameter('additionalFieldsJson', i) as string; + if (jsonParameters) { + const additionalFieldsJson = this.getNodeParameter('additionalFieldsJson', i) as string; - if (additionalFieldsJson !== '') { - if (validateJSON(additionalFieldsJson) !== undefined) { - Object.assign(body, JSON.parse(additionalFieldsJson)); - } else { - throw new NodeOperationError(this.getNode(), 'Additional fields must be a valid JSON'); + if (additionalFieldsJson !== '') { + if (validateJSON(additionalFieldsJson) !== undefined) { + Object.assign(body, JSON.parse(additionalFieldsJson)); + } else { + throw new NodeOperationError(this.getNode(), 'Additional fields must be a valid JSON'); + } } - } - } else { - const discountType = this.getNodeParameter('discountType', i) as string; - const couponType = this.getNodeParameter('couponType', i) as string; - const discountAmount = this.getNodeParameter('discountAmount', i) as number; - - if (couponType === 'product') { - body.product_ids = this.getNodeParameter('productIds', i) as string; - } - - if (discountType === 'flat') { - body.currency = this.getNodeParameter('currency', i) as string; - } - - body.coupon_type = couponType; - body.discount_type = discountType; - body.discount_amount = discountAmount; - - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - - if (additionalFields.allowedUses) { - body.allowed_uses = additionalFields.allowedUses as number; - } - if (additionalFields.couponCode) { - body.coupon_code = additionalFields.couponCode as string; - } - if (additionalFields.couponPrefix) { - body.coupon_prefix = additionalFields.couponPrefix as string; - } - if (additionalFields.expires) { - body.expires = moment(additionalFields.expires as Date).format('YYYY-MM-DD') as string; - } - if (additionalFields.group) { - body.group = additionalFields.group as string; - } - if (additionalFields.recurring) { - body.recurring = 1; } else { - body.recurring = 0; - } - if (additionalFields.numberOfCoupons) { - body.num_coupons = additionalFields.numberOfCoupons as number; - } - if (additionalFields.description) { - body.description = additionalFields.description as string; - } + const discountType = this.getNodeParameter('discountType', i) as string; + const couponType = this.getNodeParameter('couponType', i) as string; + const discountAmount = this.getNodeParameter('discountAmount', i) as number; - const endpoint = '/2.1/product/create_coupon'; + if (couponType === 'product') { + body.product_ids = this.getNodeParameter('productIds', i) as string; + } + + if (discountType === 'flat') { + body.currency = this.getNodeParameter('currency', i) as string; + } + + body.coupon_type = couponType; + body.discount_type = discountType; + body.discount_amount = discountAmount; + + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + + if (additionalFields.allowedUses) { + body.allowed_uses = additionalFields.allowedUses as number; + } + if (additionalFields.couponCode) { + body.coupon_code = additionalFields.couponCode as string; + } + if (additionalFields.couponPrefix) { + body.coupon_prefix = additionalFields.couponPrefix as string; + } + if (additionalFields.expires) { + body.expires = moment(additionalFields.expires as Date).format('YYYY-MM-DD') as string; + } + if (additionalFields.group) { + body.group = additionalFields.group as string; + } + if (additionalFields.recurring) { + body.recurring = 1; + } else { + body.recurring = 0; + } + if (additionalFields.numberOfCoupons) { + body.num_coupons = additionalFields.numberOfCoupons as number; + } + if (additionalFields.description) { + body.description = additionalFields.description as string; + } + + const endpoint = '/2.1/product/create_coupon'; + + responseData = await paddleApiRequest.call(this, endpoint, 'POST', body); + responseData = responseData.response.coupon_codes.map((coupon : string) => ({coupon})); + } + } + + if (operation === 'getAll') { + const productId = this.getNodeParameter('productId', i) as string; + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + const endpoint = '/2.0/product/list_coupons'; + + body.product_id = productId as string; responseData = await paddleApiRequest.call(this, endpoint, 'POST', body); - responseData = responseData.response.coupon_codes.map((coupon : string) => ({coupon})); - } - } - if (operation === 'getAll') { - const productId = this.getNodeParameter('productId', i) as string; - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - const endpoint = '/2.0/product/list_coupons'; - - body.product_id = productId as string; - - responseData = await paddleApiRequest.call(this, endpoint, 'POST', body); - - if (returnAll) { - responseData = responseData.response; - } else { - const limit = this.getNodeParameter('limit', i) as number; - responseData = responseData.response.splice(0, limit); - } - } - - if (operation === 'update') { - - const jsonParameters = this.getNodeParameter('jsonParameters', i) as boolean; - - if (jsonParameters) { - const additionalFieldsJson = this.getNodeParameter('additionalFieldsJson', i) as string; - - if (additionalFieldsJson !== '') { - if (validateJSON(additionalFieldsJson) !== undefined) { - Object.assign(body, JSON.parse(additionalFieldsJson)); - } else { - throw new NodeOperationError(this.getNode(), 'Additional fields must be a valid JSON'); - } - } - - } else { - const updateBy = this.getNodeParameter('updateBy', i) as string; - - if (updateBy === 'group') { - body.group = this.getNodeParameter('group', i) as string; + if (returnAll) { + responseData = responseData.response; } else { - body.coupon_code = this.getNodeParameter('couponCode', i) as string; - } - - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - - if (additionalFields.allowedUses) { - body.allowed_uses = additionalFields.allowedUses as number; - } - if (additionalFields.currency) { - body.currency = additionalFields.currency as string; - } - if (additionalFields.newCouponCode) { - body.new_coupon_code = additionalFields.newCouponCode as string; - } - if (additionalFields.expires) { - body.expires = moment(additionalFields.expires as Date).format('YYYY-MM-DD') as string; - } - if (additionalFields.newGroup) { - body.new_group = additionalFields.newGroup as string; - } - if (additionalFields.recurring === true) { - body.recurring = 1; - } else if (additionalFields.recurring === false) { - body.recurring = 0; - } - if (additionalFields.productIds) { - body.product_ids = additionalFields.productIds as number; - } - if (additionalFields.discountAmount) { - body.discount_amount = additionalFields.discountAmount as number; - } - if (additionalFields.discount) { - //@ts-ignore - if (additionalFields.discount.discountProperties.discountType === 'percentage') { - // @ts-ignore - body.discount_amount = additionalFields.discount.discountProperties.discountAmount as number; - } else { - //@ts-ignore - body.currency = additionalFields.discount.discountProperties.currency as string; - //@ts-ignore - body.discount_amount = additionalFields.discount.discountProperties.discountAmount as number; - } + const limit = this.getNodeParameter('limit', i) as number; + responseData = responseData.response.splice(0, limit); } } - const endpoint = '/2.1/product/update_coupon'; + if (operation === 'update') { - responseData = await paddleApiRequest.call(this, endpoint, 'POST', body); - responseData = responseData.response; - } - } - if (resource === 'payment') { - if (operation === 'getAll') { - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - const jsonParameters = this.getNodeParameter('jsonParameters', i) as boolean; + const jsonParameters = this.getNodeParameter('jsonParameters', i) as boolean; - if (jsonParameters) { - const additionalFieldsJson = this.getNodeParameter('additionalFieldsJson', i) as string; + if (jsonParameters) { + const additionalFieldsJson = this.getNodeParameter('additionalFieldsJson', i) as string; - if (additionalFieldsJson !== '') { - if (validateJSON(additionalFieldsJson) !== undefined) { - Object.assign(body, JSON.parse(additionalFieldsJson)); - } else { - throw new NodeOperationError(this.getNode(), 'Additional fields must be a valid JSON'); + if (additionalFieldsJson !== '') { + if (validateJSON(additionalFieldsJson) !== undefined) { + Object.assign(body, JSON.parse(additionalFieldsJson)); + } else { + throw new NodeOperationError(this.getNode(), 'Additional fields must be a valid JSON'); + } } - } - } else { - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - - if (additionalFields.subscriptionId) { - body.subscription_id = additionalFields.subscriptionId as number; - } - if (additionalFields.plan) { - body.plan = additionalFields.plan as string; - } - if (additionalFields.state) { - body.state = additionalFields.state as string; - } - if (additionalFields.isPaid) { - body.is_paid = 1; } else { - body.is_paid = 0; - } - if (additionalFields.from) { - body.from = moment(additionalFields.from as Date).format('YYYY-MM-DD') as string; - } - if (additionalFields.to) { - body.to = moment(additionalFields.to as Date).format('YYYY-MM-DD') as string; - } - if (additionalFields.isOneOffCharge) { - body.is_one_off_charge = additionalFields.isOneOffCharge as boolean; - } - } - const endpoint = '/2.0/subscription/payments'; + const updateBy = this.getNodeParameter('updateBy', i) as string; - responseData = await paddleApiRequest.call(this, endpoint, 'POST', body); - - if (returnAll) { - responseData = responseData.response; - } else { - const limit = this.getNodeParameter('limit', i) as number; - responseData = responseData.response.splice(0, limit); - } - } - if (operation === 'reschedule') { - const paymentId = this.getNodeParameter('paymentId', i) as number; - const date = this.getNodeParameter('date', i) as Date; - - body.payment_id = paymentId; - body.date = body.to = moment(date as Date).format('YYYY-MM-DD') as string; - - const endpoint = '/2.0/subscription/payments_reschedule'; - - responseData = await paddleApiRequest.call(this, endpoint, 'POST', body); - } - } - if (resource === 'plan') { - if (operation === 'getAll') { - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - const endpoint = '/2.0/subscription/plans'; - - responseData = await paddleApiRequest.call(this, endpoint, 'POST', body); - - if (returnAll) { - responseData = responseData.response; - } else { - const limit = this.getNodeParameter('limit', i) as number; - responseData = responseData.response.splice(0, limit); - } - } - if (operation === 'get') { - const planId = this.getNodeParameter('planId', i) as string; - - body.plan = planId; - - const endpoint = '/2.0/subscription/plans'; - - responseData = await paddleApiRequest.call(this, endpoint, 'POST', body); - responseData = responseData.response; - } - } - if (resource === 'product') { - if (operation === 'getAll') { - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - const endpoint = '/2.0/product/get_products'; - - responseData = await paddleApiRequest.call(this, endpoint, 'POST', body); - - if (returnAll) { - responseData = responseData.response.products; - } else { - const limit = this.getNodeParameter('limit', i) as number; - responseData = responseData.response.products.splice(0, limit); - } - } - } - if (resource === 'order') { - if (operation === 'get') { - const endpoint = '/1.0/order'; - const checkoutId = this.getNodeParameter('checkoutId', i) as string; - - body.checkout_id = checkoutId; - - responseData = await paddleApiRequest.call(this, endpoint, 'GET', body); - } - } - if (resource === 'user') { - if (operation === 'getAll') { - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - - const jsonParameters = this.getNodeParameter('jsonParameters', i) as boolean; - - if (jsonParameters) { - const additionalFieldsJson = this.getNodeParameter('additionalFieldsJson', i) as string; - - if (additionalFieldsJson !== '') { - if (validateJSON(additionalFieldsJson) !== undefined) { - Object.assign(body, JSON.parse(additionalFieldsJson)); + if (updateBy === 'group') { + body.group = this.getNodeParameter('group', i) as string; } else { - throw new NodeOperationError(this.getNode(), 'Additional fields must be a valid JSON'); + body.coupon_code = this.getNodeParameter('couponCode', i) as string; + } + + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + + if (additionalFields.allowedUses) { + body.allowed_uses = additionalFields.allowedUses as number; + } + if (additionalFields.currency) { + body.currency = additionalFields.currency as string; + } + if (additionalFields.newCouponCode) { + body.new_coupon_code = additionalFields.newCouponCode as string; + } + if (additionalFields.expires) { + body.expires = moment(additionalFields.expires as Date).format('YYYY-MM-DD') as string; + } + if (additionalFields.newGroup) { + body.new_group = additionalFields.newGroup as string; + } + if (additionalFields.recurring === true) { + body.recurring = 1; + } else if (additionalFields.recurring === false) { + body.recurring = 0; + } + if (additionalFields.productIds) { + body.product_ids = additionalFields.productIds as number; + } + if (additionalFields.discountAmount) { + body.discount_amount = additionalFields.discountAmount as number; + } + if (additionalFields.discount) { + //@ts-ignore + if (additionalFields.discount.discountProperties.discountType === 'percentage') { + // @ts-ignore + body.discount_amount = additionalFields.discount.discountProperties.discountAmount as number; + } else { + //@ts-ignore + body.currency = additionalFields.discount.discountProperties.currency as string; + //@ts-ignore + body.discount_amount = additionalFields.discount.discountProperties.discountAmount as number; + } } } - } else { + const endpoint = '/2.1/product/update_coupon'; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - - if (additionalFields.state) { - body.state = additionalFields.state as string; - } - if (additionalFields.planId) { - body.plan_id = additionalFields.planId as string; - } - if (additionalFields.subscriptionId) { - body.subscription_id = additionalFields.subscriptionId as string; - } - } - - const endpoint = '/2.0/subscription/users'; - - if (returnAll) { - responseData = await paddleApiRequestAllItems.call(this, 'response', endpoint, 'POST', body); - } else { - body.results_per_page = this.getNodeParameter('limit', i) as number; responseData = await paddleApiRequest.call(this, endpoint, 'POST', body); responseData = responseData.response; } } - } + if (resource === 'payment') { + if (operation === 'getAll') { + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + const jsonParameters = this.getNodeParameter('jsonParameters', i) as boolean; + if (jsonParameters) { + const additionalFieldsJson = this.getNodeParameter('additionalFieldsJson', i) as string; + + if (additionalFieldsJson !== '') { + if (validateJSON(additionalFieldsJson) !== undefined) { + Object.assign(body, JSON.parse(additionalFieldsJson)); + } else { + throw new NodeOperationError(this.getNode(), 'Additional fields must be a valid JSON'); + } + } + + } else { + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + + if (additionalFields.subscriptionId) { + body.subscription_id = additionalFields.subscriptionId as number; + } + if (additionalFields.plan) { + body.plan = additionalFields.plan as string; + } + if (additionalFields.state) { + body.state = additionalFields.state as string; + } + if (additionalFields.isPaid) { + body.is_paid = 1; + } else { + body.is_paid = 0; + } + if (additionalFields.from) { + body.from = moment(additionalFields.from as Date).format('YYYY-MM-DD') as string; + } + if (additionalFields.to) { + body.to = moment(additionalFields.to as Date).format('YYYY-MM-DD') as string; + } + if (additionalFields.isOneOffCharge) { + body.is_one_off_charge = additionalFields.isOneOffCharge as boolean; + } + } + const endpoint = '/2.0/subscription/payments'; + + responseData = await paddleApiRequest.call(this, endpoint, 'POST', body); + + if (returnAll) { + responseData = responseData.response; + } else { + const limit = this.getNodeParameter('limit', i) as number; + responseData = responseData.response.splice(0, limit); + } + } + if (operation === 'reschedule') { + const paymentId = this.getNodeParameter('paymentId', i) as number; + const date = this.getNodeParameter('date', i) as Date; + + body.payment_id = paymentId; + body.date = body.to = moment(date as Date).format('YYYY-MM-DD') as string; + + const endpoint = '/2.0/subscription/payments_reschedule'; + + responseData = await paddleApiRequest.call(this, endpoint, 'POST', body); + } + } + if (resource === 'plan') { + if (operation === 'getAll') { + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + const endpoint = '/2.0/subscription/plans'; + + responseData = await paddleApiRequest.call(this, endpoint, 'POST', body); + + if (returnAll) { + responseData = responseData.response; + } else { + const limit = this.getNodeParameter('limit', i) as number; + responseData = responseData.response.splice(0, limit); + } + } + if (operation === 'get') { + const planId = this.getNodeParameter('planId', i) as string; + + body.plan = planId; + + const endpoint = '/2.0/subscription/plans'; + + responseData = await paddleApiRequest.call(this, endpoint, 'POST', body); + responseData = responseData.response; + } + } + if (resource === 'product') { + if (operation === 'getAll') { + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + const endpoint = '/2.0/product/get_products'; + + responseData = await paddleApiRequest.call(this, endpoint, 'POST', body); + + if (returnAll) { + responseData = responseData.response.products; + } else { + const limit = this.getNodeParameter('limit', i) as number; + responseData = responseData.response.products.splice(0, limit); + } + } + } + if (resource === 'order') { + if (operation === 'get') { + const endpoint = '/1.0/order'; + const checkoutId = this.getNodeParameter('checkoutId', i) as string; + + body.checkout_id = checkoutId; + + responseData = await paddleApiRequest.call(this, endpoint, 'GET', body); + } + } + if (resource === 'user') { + if (operation === 'getAll') { + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + + const jsonParameters = this.getNodeParameter('jsonParameters', i) as boolean; + + if (jsonParameters) { + const additionalFieldsJson = this.getNodeParameter('additionalFieldsJson', i) as string; + + if (additionalFieldsJson !== '') { + if (validateJSON(additionalFieldsJson) !== undefined) { + Object.assign(body, JSON.parse(additionalFieldsJson)); + } else { + throw new NodeOperationError(this.getNode(), 'Additional fields must be a valid JSON'); + } + } + + } else { + + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + + if (additionalFields.state) { + body.state = additionalFields.state as string; + } + if (additionalFields.planId) { + body.plan_id = additionalFields.planId as string; + } + if (additionalFields.subscriptionId) { + body.subscription_id = additionalFields.subscriptionId as string; + } + } + + const endpoint = '/2.0/subscription/users'; + + if (returnAll) { + responseData = await paddleApiRequestAllItems.call(this, 'response', endpoint, 'POST', body); + } else { + body.results_per_page = this.getNodeParameter('limit', i) as number; + responseData = await paddleApiRequest.call(this, endpoint, 'POST', body); + responseData = responseData.response; + } + } + } + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; + } if (Array.isArray(responseData)) { returnData.push.apply(returnData, responseData as IDataObject[]); } else { diff --git a/packages/nodes-base/nodes/PagerDuty/PagerDuty.node.ts b/packages/nodes-base/nodes/PagerDuty/PagerDuty.node.ts index 0526a7c2ba..3fede0ba76 100644 --- a/packages/nodes-base/nodes/PagerDuty/PagerDuty.node.ts +++ b/packages/nodes-base/nodes/PagerDuty/PagerDuty.node.ts @@ -218,196 +218,204 @@ export class PagerDuty implements INodeType { 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 === 'incident') { - //https://api-reference.pagerduty.com/#!/Incidents/post_incidents - if (operation === 'create') { - const title = this.getNodeParameter('title', i) as string; - const serviceId = this.getNodeParameter('serviceId', i) as string; - const email = this.getNodeParameter('email', i) as string; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const conferenceBridge = (this.getNodeParameter('conferenceBridgeUi', i) as IDataObject).conferenceBridgeValues as IDataObject; - const body: IIncident = { - type: 'incident', - title, - service: { - id: serviceId, - type: 'service_reference', - }, - }; - if (additionalFields.details) { - body.body = { - type: 'incident_body', - details: additionalFields.details, + try { + if (resource === 'incident') { + //https://api-reference.pagerduty.com/#!/Incidents/post_incidents + if (operation === 'create') { + const title = this.getNodeParameter('title', i) as string; + const serviceId = this.getNodeParameter('serviceId', i) as string; + const email = this.getNodeParameter('email', i) as string; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const conferenceBridge = (this.getNodeParameter('conferenceBridgeUi', i) as IDataObject).conferenceBridgeValues as IDataObject; + const body: IIncident = { + type: 'incident', + title, + service: { + id: serviceId, + type: 'service_reference', + }, }; + if (additionalFields.details) { + body.body = { + type: 'incident_body', + details: additionalFields.details, + }; + } + if (additionalFields.priorityId) { + body.priority = { + id: additionalFields.priorityId, + type: 'priority_reference', + }; + } + if (additionalFields.escalationPolicyId) { + body.escalation_policy = { + id: additionalFields.escalationPolicyId, + type: 'escalation_policy_reference', + }; + } + if (additionalFields.urgency) { + body.urgency = additionalFields.urgency as string; + } + if (additionalFields.incidentKey) { + body.incident_key = additionalFields.incidentKey as string; + } + if (conferenceBridge) { + body.conference_bridge = { + conference_number: conferenceBridge.conferenceNumber, + conference_url: conferenceBridge.conferenceUrl, + }; + } + responseData = await pagerDutyApiRequest.call(this, 'POST', '/incidents', { incident: body }, {}, undefined, { from: email }); + responseData = responseData.incident; } - if (additionalFields.priorityId) { - body.priority = { - id: additionalFields.priorityId, - type: 'priority_reference', + //https://api-reference.pagerduty.com/#!/Incidents/get_incidents_id + if (operation === 'get') { + const incidentId = this.getNodeParameter('incidentId', i) as string; + responseData = await pagerDutyApiRequest.call(this, 'GET', `/incidents/${incidentId}`); + responseData = responseData.incident; + } + //https://api-reference.pagerduty.com/#!/Incidents/get_incidents + if (operation === 'getAll') { + const returnAll = this.getNodeParameter('returnAll', 0) as boolean; + const options = this.getNodeParameter('options', 0) as IDataObject; + if (options.userIds) { + options.userIds = (options.userIds as string).split(',') as string[]; + } + if (options.teamIds) { + options.teamIds = (options.teamIds as string).split(',') as string[]; + } + if (options.include) { + options.include = (options.include as string[]).map((e) => snakeCase(e)); + } + if (options.sortBy) { + options.sortBy = options.sortBy as string; + } + Object.assign(qs, keysToSnakeCase(options)[0]); + if (returnAll) { + responseData = await pagerDutyApiRequestAllItems.call(this, 'incidents', 'GET', '/incidents', {}, qs); + } else { + qs.limit = this.getNodeParameter('limit', 0) as number; + responseData = await pagerDutyApiRequest.call(this, 'GET', '/incidents', {}, qs); + responseData = responseData.incidents; + } + } + //https://api-reference.pagerduty.com/#!/Incidents/put_incidents_id + if (operation === 'update') { + const incidentId = this.getNodeParameter('incidentId', i) as string; + const email = this.getNodeParameter('email', i) as string; + const conferenceBridge = (this.getNodeParameter('conferenceBridgeUi', i) as IDataObject).conferenceBridgeValues as IDataObject; + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + const body: IIncident = { + type: 'incident', }; + if (updateFields.title) { + body.title = updateFields.title as string; + } + if (updateFields.escalationLevel) { + body.escalation_level = updateFields.escalationLevel as number; + } + if (updateFields.details) { + body.body = { + type: 'incident_body', + details: updateFields.details, + }; + } + if (updateFields.priorityId) { + body.priority = { + id: updateFields.priorityId, + type: 'priority_reference', + }; + } + if (updateFields.escalationPolicyId) { + body.escalation_policy = { + id: updateFields.escalationPolicyId, + type: 'escalation_policy_reference', + }; + } + if (updateFields.urgency) { + body.urgency = updateFields.urgency as string; + } + if (updateFields.resolution) { + body.resolution = updateFields.resolution as string; + } + if (updateFields.status) { + body.status = updateFields.status as string; + } + if (conferenceBridge) { + body.conference_bridge = { + conference_number: conferenceBridge.conferenceNumber, + conference_url: conferenceBridge.conferenceUrl, + }; + } + responseData = await pagerDutyApiRequest.call(this, 'PUT', `/incidents/${incidentId}`, { incident: body }, {}, undefined, { from: email }); + responseData = responseData.incident; } - if (additionalFields.escalationPolicyId) { - body.escalation_policy = { - id: additionalFields.escalationPolicyId, - type: 'escalation_policy_reference', + } + if (resource === 'incidentNote') { + //https://api-reference.pagerduty.com/#!/Incidents/post_incidents_id_notes + if (operation === 'create') { + const incidentId = this.getNodeParameter('incidentId', i) as string; + const content = this.getNodeParameter('content', i) as string; + const email = this.getNodeParameter('email', i) as string; + const body: IDataObject = { + content, }; + responseData = await pagerDutyApiRequest.call(this, 'POST', `/incidents/${incidentId}/notes`, { note: body }, {}, undefined, { from: email }); } - if (additionalFields.urgency) { - body.urgency = additionalFields.urgency as string; - } - if (additionalFields.incidentKey) { - body.incident_key = additionalFields.incidentKey as string; - } - if (conferenceBridge) { - body.conference_bridge = { - conference_number: conferenceBridge.conferenceNumber, - conference_url: conferenceBridge.conferenceUrl, - }; - } - responseData = await pagerDutyApiRequest.call(this, 'POST', '/incidents', { incident: body }, {}, undefined, { from: email }); - responseData = responseData.incident; - } - //https://api-reference.pagerduty.com/#!/Incidents/get_incidents_id - if (operation === 'get') { - const incidentId = this.getNodeParameter('incidentId', i) as string; - responseData = await pagerDutyApiRequest.call(this, 'GET', `/incidents/${incidentId}`); - responseData = responseData.incident; - } - //https://api-reference.pagerduty.com/#!/Incidents/get_incidents - if (operation === 'getAll') { - const returnAll = this.getNodeParameter('returnAll', 0) as boolean; - const options = this.getNodeParameter('options', 0) as IDataObject; - if (options.userIds) { - options.userIds = (options.userIds as string).split(',') as string[]; - } - if (options.teamIds) { - options.teamIds = (options.teamIds as string).split(',') as string[]; - } - if (options.include) { - options.include = (options.include as string[]).map((e) => snakeCase(e)); - } - if (options.sortBy) { - options.sortBy = options.sortBy as string; - } - Object.assign(qs, keysToSnakeCase(options)[0]); - if (returnAll) { - responseData = await pagerDutyApiRequestAllItems.call(this, 'incidents', 'GET', '/incidents', {}, qs); - } else { - qs.limit = this.getNodeParameter('limit', 0) as number; - responseData = await pagerDutyApiRequest.call(this, 'GET', '/incidents', {}, qs); - responseData = responseData.incidents; + //https://api-reference.pagerduty.com/#!/Incidents/get_incidents_id_notes + if (operation === 'getAll') { + const incidentId = this.getNodeParameter('incidentId', i) as string; + const returnAll = this.getNodeParameter('returnAll', 0) as boolean; + if (returnAll) { + responseData = await pagerDutyApiRequestAllItems.call(this, 'notes', 'GET', `/incidents/${incidentId}/notes`, {}, qs); + } else { + qs.limit = this.getNodeParameter('limit', 0) as number; + responseData = await pagerDutyApiRequest.call(this, 'GET', `/incidents/${incidentId}/notes`, {}, qs); + responseData = responseData.notes; + } } } - //https://api-reference.pagerduty.com/#!/Incidents/put_incidents_id - if (operation === 'update') { - const incidentId = this.getNodeParameter('incidentId', i) as string; - const email = this.getNodeParameter('email', i) as string; - const conferenceBridge = (this.getNodeParameter('conferenceBridgeUi', i) as IDataObject).conferenceBridgeValues as IDataObject; - const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; - const body: IIncident = { - type: 'incident', - }; - if (updateFields.title) { - body.title = updateFields.title as string; + if (resource === 'logEntry') { + //https://api-reference.pagerduty.com/#!/Log_Entries/get_log_entries_id + if (operation === 'get') { + const logEntryId = this.getNodeParameter('logEntryId', i) as string; + responseData = await pagerDutyApiRequest.call(this, 'GET', `/log_entries/${logEntryId}`); + responseData = responseData.log_entry; } - if (updateFields.escalationLevel) { - body.escalation_level = updateFields.escalationLevel as number; - } - if (updateFields.details) { - body.body = { - type: 'incident_body', - details: updateFields.details, - }; - } - if (updateFields.priorityId) { - body.priority = { - id: updateFields.priorityId, - type: 'priority_reference', - }; - } - if (updateFields.escalationPolicyId) { - body.escalation_policy = { - id: updateFields.escalationPolicyId, - type: 'escalation_policy_reference', - }; - } - if (updateFields.urgency) { - body.urgency = updateFields.urgency as string; - } - if (updateFields.resolution) { - body.resolution = updateFields.resolution as string; - } - if (updateFields.status) { - body.status = updateFields.status as string; - } - if (conferenceBridge) { - body.conference_bridge = { - conference_number: conferenceBridge.conferenceNumber, - conference_url: conferenceBridge.conferenceUrl, - }; - } - responseData = await pagerDutyApiRequest.call(this, 'PUT', `/incidents/${incidentId}`, { incident: body }, {}, undefined, { from: email }); - responseData = responseData.incident; - } - } - if (resource === 'incidentNote') { - //https://api-reference.pagerduty.com/#!/Incidents/post_incidents_id_notes - if (operation === 'create') { - const incidentId = this.getNodeParameter('incidentId', i) as string; - const content = this.getNodeParameter('content', i) as string; - const email = this.getNodeParameter('email', i) as string; - const body: IDataObject = { - content, - }; - responseData = await pagerDutyApiRequest.call(this, 'POST', `/incidents/${incidentId}/notes`, { note: body }, {}, undefined, { from: email }); - } - //https://api-reference.pagerduty.com/#!/Incidents/get_incidents_id_notes - if (operation === 'getAll') { - const incidentId = this.getNodeParameter('incidentId', i) as string; - const returnAll = this.getNodeParameter('returnAll', 0) as boolean; - if (returnAll) { - responseData = await pagerDutyApiRequestAllItems.call(this, 'notes', 'GET', `/incidents/${incidentId}/notes`, {}, qs); - } else { - qs.limit = this.getNodeParameter('limit', 0) as number; - responseData = await pagerDutyApiRequest.call(this, 'GET', `/incidents/${incidentId}/notes`, {}, qs); - responseData = responseData.notes; + //https://api-reference.pagerduty.com/#!/Log_Entries/get_log_entries + if (operation === 'getAll') { + const options = this.getNodeParameter('options', i) as IDataObject; + Object.assign(qs, options); + keysToSnakeCase(qs); + const returnAll = this.getNodeParameter('returnAll', 0) as boolean; + if (returnAll) { + responseData = await pagerDutyApiRequestAllItems.call(this, 'log_entries', 'GET', '/log_entries', {}, qs); + } else { + qs.limit = this.getNodeParameter('limit', 0) as number; + responseData = await pagerDutyApiRequest.call(this, 'GET', '/log_entries', {}, qs); + responseData = responseData.log_entries; + } } } - } - if (resource === 'logEntry') { - //https://api-reference.pagerduty.com/#!/Log_Entries/get_log_entries_id - if (operation === 'get') { - const logEntryId = this.getNodeParameter('logEntryId', i) as string; - responseData = await pagerDutyApiRequest.call(this, 'GET', `/log_entries/${logEntryId}`); - responseData = responseData.log_entry; - } - //https://api-reference.pagerduty.com/#!/Log_Entries/get_log_entries - if (operation === 'getAll') { - const options = this.getNodeParameter('options', i) as IDataObject; - Object.assign(qs, options); - keysToSnakeCase(qs); - const returnAll = this.getNodeParameter('returnAll', 0) as boolean; - if (returnAll) { - responseData = await pagerDutyApiRequestAllItems.call(this, 'log_entries', 'GET', '/log_entries', {}, qs); - } else { - qs.limit = this.getNodeParameter('limit', 0) as number; - responseData = await pagerDutyApiRequest.call(this, 'GET', '/log_entries', {}, qs); - responseData = responseData.log_entries; + if (resource === 'user') { + //https://developer.pagerduty.com/api-reference/reference/REST/openapiv3.json/paths/~1users~1%7Bid%7D/get + if (operation === 'get') { + const userId = this.getNodeParameter('userId', i) as string; + responseData = await pagerDutyApiRequest.call(this, 'GET', `/users/${userId}`); + responseData = responseData.user; } } - } - if (resource === 'user') { - //https://developer.pagerduty.com/api-reference/reference/REST/openapiv3.json/paths/~1users~1%7Bid%7D/get - if (operation === 'get') { - const userId = this.getNodeParameter('userId', i) as string; - responseData = await pagerDutyApiRequest.call(this, 'GET', `/users/${userId}`); - responseData = responseData.user; + if (Array.isArray(responseData)) { + returnData.push.apply(returnData, responseData as IDataObject[]); + } else { + returnData.push(responseData as IDataObject); } - } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else { - returnData.push(responseData as IDataObject); + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } } return [this.helpers.returnJsonArray(returnData)]; diff --git a/packages/nodes-base/nodes/PayPal/PayPal.node.ts b/packages/nodes-base/nodes/PayPal/PayPal.node.ts index 7b12c8d835..8e2cd10a1c 100644 --- a/packages/nodes-base/nodes/PayPal/PayPal.node.ts +++ b/packages/nodes-base/nodes/PayPal/PayPal.node.ts @@ -87,77 +87,85 @@ export class PayPal implements INodeType { 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 NodeOperationError(this.getNode(), 'You must have at least one item.'); + try { + 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; } - } else { - const itemsJson = validateJSON(this.getNodeParameter('itemsJson', i) as string); - body.items = itemsJson; - } - responseData = await payPalApiRequest.call(this, '/payments/payouts', 'POST', body); + 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 NodeOperationError(this.getNode(), 'You must have at least one item.'); + } + } else { + const itemsJson = validateJSON(this.getNodeParameter('itemsJson', i) as string); + body.items = itemsJson; + } + responseData = await payPalApiRequest.call(this, '/payments/payouts', 'POST', body); - } - if (operation === 'get') { - const payoutBatchId = this.getNodeParameter('payoutBatchId', i) as string; - const returnAll = this.getNodeParameter('returnAll', 0) as boolean; - 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; + } + if (operation === 'get') { + const payoutBatchId = this.getNodeParameter('payoutBatchId', i) as string; + const returnAll = this.getNodeParameter('returnAll', 0) as boolean; + 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; + } + } + } else if (resource === 'payoutItem') { + if (operation === 'get') { + const payoutItemId = this.getNodeParameter('payoutItemId', i) as string; + responseData = await payPalApiRequest.call(this,`/payments/payouts-item/${payoutItemId}`, 'GET', {}, qs); + } + if (operation === 'cancel') { + const payoutItemId = this.getNodeParameter('payoutItemId', i) as string; + responseData = await payPalApiRequest.call(this,`/payments/payouts-item/${payoutItemId}/cancel`, 'POST', {}, qs); } } - } else if (resource === 'payoutItem') { - if (operation === 'get') { - const payoutItemId = this.getNodeParameter('payoutItemId', i) as string; - responseData = await payPalApiRequest.call(this,`/payments/payouts-item/${payoutItemId}`, 'GET', {}, qs); + if (Array.isArray(responseData)) { + returnData.push.apply(returnData, responseData as IDataObject[]); + } else { + returnData.push(responseData as IDataObject); } - if (operation === 'cancel') { - const payoutItemId = this.getNodeParameter('payoutItemId', i) as string; - responseData = await payPalApiRequest.call(this,`/payments/payouts-item/${payoutItemId}/cancel`, 'POST', {}, qs); + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; } - } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else { - returnData.push(responseData as IDataObject); + throw error; } } return [this.helpers.returnJsonArray(returnData)]; diff --git a/packages/nodes-base/nodes/Peekalink/Peekalink.node.ts b/packages/nodes-base/nodes/Peekalink/Peekalink.node.ts index adcaf4c907..7e2ed1b499 100644 --- a/packages/nodes-base/nodes/Peekalink/Peekalink.node.ts +++ b/packages/nodes-base/nodes/Peekalink/Peekalink.node.ts @@ -74,26 +74,34 @@ export class Peekalink implements INodeType { const operation = this.getNodeParameter('operation', 0) as string; for (let i = 0; i < length; i++) { - if (operation === 'isAvailable') { - const url = this.getNodeParameter('url', i) as string; - const body: IDataObject = { - link: url, - }; + try { + if (operation === 'isAvailable') { + const url = this.getNodeParameter('url', i) as string; + const body: IDataObject = { + link: url, + }; - responseData = await peekalinkApiRequest.call(this, 'POST', `/is-available/`, body); - } - if (operation === 'preview') { - const url = this.getNodeParameter('url', i) as string; - const body: IDataObject = { - link: url, - }; + responseData = await peekalinkApiRequest.call(this, 'POST', `/is-available/`, body); + } + if (operation === 'preview') { + const url = this.getNodeParameter('url', i) as string; + const body: IDataObject = { + link: url, + }; - responseData = await peekalinkApiRequest.call(this, 'POST', `/`, body); - } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else { - returnData.push(responseData as IDataObject); + responseData = await peekalinkApiRequest.call(this, 'POST', `/`, body); + } + if (Array.isArray(responseData)) { + returnData.push.apply(returnData, responseData as IDataObject[]); + } else { + returnData.push(responseData as IDataObject); + } + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } } return [this.helpers.returnJsonArray(returnData)]; diff --git a/packages/nodes-base/nodes/Phantombuster/Phantombuster.node.ts b/packages/nodes-base/nodes/Phantombuster/Phantombuster.node.ts index da913acdb2..20c9e70448 100644 --- a/packages/nodes-base/nodes/Phantombuster/Phantombuster.node.ts +++ b/packages/nodes-base/nodes/Phantombuster/Phantombuster.node.ts @@ -123,148 +123,156 @@ export class Phantombuster implements INodeType { const operation = this.getNodeParameter('operation', 0) as string; for (let i = 0; i < length; i++) { - if (resource === 'agent') { - //https://hub.phantombuster.com/reference#post_agents-delete-1 - if (operation === 'delete') { - const agentId = this.getNodeParameter('agentId', i) as string; + try { + if (resource === 'agent') { + //https://hub.phantombuster.com/reference#post_agents-delete-1 + if (operation === 'delete') { + const agentId = this.getNodeParameter('agentId', i) as string; - responseData = await phantombusterApiRequest.call( - this, - 'POST', - '/agents/delete', - { id: agentId }, - ); - - responseData = { success: true }; - } - //https://hub.phantombuster.com/reference#get_agents-fetch-1 - if (operation === 'get') { - const agentId = this.getNodeParameter('agentId', i) as string; - - responseData = await phantombusterApiRequest.call( - this, - 'GET', - '/agents/fetch', - {}, - { id: agentId }, - ); - } - //https://hub.phantombuster.com/reference#get_agents-fetch-output-1 - if (operation === 'getOutput') { - const agentId = this.getNodeParameter('agentId', i) as string; - - const resolveData = this.getNodeParameter('resolveData', i) as boolean; - - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - - Object.assign(qs, additionalFields); - - qs.id = agentId; - - responseData = await phantombusterApiRequest.call( - this, - 'GET', - '/agents/fetch-output', - {}, - qs, - ); - - if (resolveData === true) { - const { resultObject } = await phantombusterApiRequest.call( + responseData = await phantombusterApiRequest.call( this, - 'GET', - '/containers/fetch-result-object', - {}, - { id: responseData.containerId }, + 'POST', + '/agents/delete', + { id: agentId }, ); - if (resultObject === null) { - responseData = {}; - } else { - responseData = JSON.parse(resultObject); - } + responseData = { success: true }; } - } - //https://api.phantombuster.com/api/v2/agents/fetch-all - if (operation === 'getAll') { - const returnAll = this.getNodeParameter('returnAll', i) as boolean; + //https://hub.phantombuster.com/reference#get_agents-fetch-1 + if (operation === 'get') { + const agentId = this.getNodeParameter('agentId', i) as string; - responseData = await phantombusterApiRequest.call( - this, - 'GET', - '/agents/fetch-all', - ); - - if (returnAll === false) { - const limit = this.getNodeParameter('limit', 0) as number; - responseData = responseData.splice(0, limit); - } - } - //https://hub.phantombuster.com/reference#post_agents-launch-1 - if (operation === 'launch') { - const agentId = this.getNodeParameter('agentId', i) as string; - - const jsonParameters = this.getNodeParameter('jsonParameters', i) as boolean; - - const resolveData = this.getNodeParameter('resolveData', i) as boolean; - - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - - const body: IDataObject = { - id: agentId, - }; - - if (jsonParameters) { - if (additionalFields.argumentsJson) { - body.arguments = validateJSON(this, additionalFields.argumentsJson as string, 'Arguments'); - - delete additionalFields.argumentsJson; - } - if (additionalFields.bonusArgumentJson) { - body.bonusArgument = validateJSON(this, additionalFields.bonusArgumentJson as string, 'Bonus Argument'); - delete additionalFields.bonusArgumentJson; - } - } else { - const argumentParameters = ((additionalFields.argumentsUi as IDataObject || {}).argumentValues as IDataObject[]) || []; - body.arguments = argumentParameters.reduce((object, currentValue) => { - object[currentValue.key as string] = currentValue.value; - return object; - }, {}); - delete additionalFields.argumentsUi; - - const bonusParameters = ((additionalFields.bonusArgumentUi as IDataObject || {}).bonusArgumentValue as IDataObject[]) || []; - body.bonusArgument = bonusParameters.reduce((object, currentValue) => { - object[currentValue.key as string] = currentValue.value; - return object; - }, {}); - delete additionalFields.bonusArgumentUi; - } - - Object.assign(body, additionalFields); - - responseData = await phantombusterApiRequest.call( - this, - 'POST', - '/agents/launch', - body, - ); - - if (resolveData === true) { responseData = await phantombusterApiRequest.call( this, 'GET', - '/containers/fetch', + '/agents/fetch', {}, - { id: responseData.containerId }, + { id: agentId }, ); } - } - } + //https://hub.phantombuster.com/reference#get_agents-fetch-output-1 + if (operation === 'getOutput') { + const agentId = this.getNodeParameter('agentId', i) as string; - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else if (responseData !== undefined) { - returnData.push(responseData as IDataObject); + const resolveData = this.getNodeParameter('resolveData', i) as boolean; + + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + + Object.assign(qs, additionalFields); + + qs.id = agentId; + + responseData = await phantombusterApiRequest.call( + this, + 'GET', + '/agents/fetch-output', + {}, + qs, + ); + + if (resolveData === true) { + const { resultObject } = await phantombusterApiRequest.call( + this, + 'GET', + '/containers/fetch-result-object', + {}, + { id: responseData.containerId }, + ); + + if (resultObject === null) { + responseData = {}; + } else { + responseData = JSON.parse(resultObject); + } + } + } + //https://api.phantombuster.com/api/v2/agents/fetch-all + if (operation === 'getAll') { + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + + responseData = await phantombusterApiRequest.call( + this, + 'GET', + '/agents/fetch-all', + ); + + if (returnAll === false) { + const limit = this.getNodeParameter('limit', 0) as number; + responseData = responseData.splice(0, limit); + } + } + //https://hub.phantombuster.com/reference#post_agents-launch-1 + if (operation === 'launch') { + const agentId = this.getNodeParameter('agentId', i) as string; + + const jsonParameters = this.getNodeParameter('jsonParameters', i) as boolean; + + const resolveData = this.getNodeParameter('resolveData', i) as boolean; + + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + + const body: IDataObject = { + id: agentId, + }; + + if (jsonParameters) { + if (additionalFields.argumentsJson) { + body.arguments = validateJSON(this, additionalFields.argumentsJson as string, 'Arguments'); + + delete additionalFields.argumentsJson; + } + if (additionalFields.bonusArgumentJson) { + body.bonusArgument = validateJSON(this, additionalFields.bonusArgumentJson as string, 'Bonus Argument'); + delete additionalFields.bonusArgumentJson; + } + } else { + const argumentParameters = ((additionalFields.argumentsUi as IDataObject || {}).argumentValues as IDataObject[]) || []; + body.arguments = argumentParameters.reduce((object, currentValue) => { + object[currentValue.key as string] = currentValue.value; + return object; + }, {}); + delete additionalFields.argumentsUi; + + const bonusParameters = ((additionalFields.bonusArgumentUi as IDataObject || {}).bonusArgumentValue as IDataObject[]) || []; + body.bonusArgument = bonusParameters.reduce((object, currentValue) => { + object[currentValue.key as string] = currentValue.value; + return object; + }, {}); + delete additionalFields.bonusArgumentUi; + } + + Object.assign(body, additionalFields); + + responseData = await phantombusterApiRequest.call( + this, + 'POST', + '/agents/launch', + body, + ); + + if (resolveData === true) { + responseData = await phantombusterApiRequest.call( + this, + 'GET', + '/containers/fetch', + {}, + { id: responseData.containerId }, + ); + } + } + } + + if (Array.isArray(responseData)) { + returnData.push.apply(returnData, responseData as IDataObject[]); + } else if (responseData !== undefined) { + returnData.push(responseData as IDataObject); + } + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } } return [this.helpers.returnJsonArray(returnData)]; diff --git a/packages/nodes-base/nodes/Pipedrive/Pipedrive.node.ts b/packages/nodes-base/nodes/Pipedrive/Pipedrive.node.ts index 1bd42494fb..b9e4394499 100644 --- a/packages/nodes-base/nodes/Pipedrive/Pipedrive.node.ts +++ b/packages/nodes-base/nodes/Pipedrive/Pipedrive.node.ts @@ -3065,568 +3065,579 @@ export class Pipedrive implements INodeType { body = {}; formData = {}; qs = {}; + try { + if (resource === 'activity') { + if (operation === 'create') { + // ---------------------------------- + // activity:create + // ---------------------------------- - if (resource === 'activity') { - if (operation === 'create') { - // ---------------------------------- - // activity:create - // ---------------------------------- + requestMethod = 'POST'; + endpoint = '/activities'; - requestMethod = 'POST'; - endpoint = '/activities'; + body.subject = this.getNodeParameter('subject', i) as string; + body.done = this.getNodeParameter('done', i) as string; + body.type = this.getNodeParameter('type', i) as string; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + addAdditionalFields(body, additionalFields); - body.subject = this.getNodeParameter('subject', i) as string; - body.done = this.getNodeParameter('done', i) as string; - body.type = this.getNodeParameter('type', i) as string; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - addAdditionalFields(body, additionalFields); + } else if (operation === 'delete') { + // ---------------------------------- + // activity:delete + // ---------------------------------- - } else if (operation === 'delete') { - // ---------------------------------- - // activity:delete - // ---------------------------------- + requestMethod = 'DELETE'; - requestMethod = 'DELETE'; + const activityId = this.getNodeParameter('activityId', i) as number; + endpoint = `/activities/${activityId}`; - const activityId = this.getNodeParameter('activityId', i) as number; - endpoint = `/activities/${activityId}`; + } else if (operation === 'get') { + // ---------------------------------- + // activity:get + // ---------------------------------- - } else if (operation === 'get') { - // ---------------------------------- - // activity:get - // ---------------------------------- + requestMethod = 'GET'; - requestMethod = 'GET'; + const activityId = this.getNodeParameter('activityId', i) as number; - const activityId = this.getNodeParameter('activityId', i) as number; + endpoint = `/activities/${activityId}`; - endpoint = `/activities/${activityId}`; + } else if (operation === 'getAll') { + // ---------------------------------- + // activity:getAll + // ---------------------------------- - } else if (operation === 'getAll') { - // ---------------------------------- - // activity:getAll - // ---------------------------------- + requestMethod = 'GET'; - requestMethod = 'GET'; + returnAll = this.getNodeParameter('returnAll', i) as boolean; + if (returnAll === false) { + qs.limit = this.getNodeParameter('limit', i) as number; + } - returnAll = this.getNodeParameter('returnAll', i) as boolean; - if (returnAll === false) { - qs.limit = this.getNodeParameter('limit', i) as number; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + addAdditionalFields(qs, additionalFields); + + if (qs.type) { + qs.type = (qs.type as string[]).join(','); + } + + endpoint = `/activities`; + + } else if (operation === 'update') { + // ---------------------------------- + // activity:update + // ---------------------------------- + + requestMethod = 'PUT'; + + const activityId = this.getNodeParameter('activityId', i) as number; + endpoint = `/activities/${activityId}`; + + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + addAdditionalFields(body, updateFields); + + } + } else if (resource === 'deal') { + if (operation === 'create') { + // ---------------------------------- + // deal:create + // ---------------------------------- + + requestMethod = 'POST'; + endpoint = '/deals'; + + body.title = this.getNodeParameter('title', i) as string; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + addAdditionalFields(body, additionalFields); + + } else if (operation === 'delete') { + // ---------------------------------- + // deal:delete + // ---------------------------------- + + requestMethod = 'DELETE'; + + const dealId = this.getNodeParameter('dealId', i) as number; + endpoint = `/deals/${dealId}`; + + } else if (operation === 'duplicate') { + // ---------------------------------- + // deal:duplicate + // ---------------------------------- + + requestMethod = 'POST'; + + const dealId = this.getNodeParameter('dealId', i) as number; + endpoint = `/deals/${dealId}/duplicate`; + + } else if (operation === 'get') { + // ---------------------------------- + // deal:get + // ---------------------------------- + + requestMethod = 'GET'; + + const dealId = this.getNodeParameter('dealId', i) as number; + endpoint = `/deals/${dealId}`; + + } else if (operation === 'getAll') { + // ---------------------------------- + // deal:getAll + // ---------------------------------- + + requestMethod = 'GET'; + + returnAll = this.getNodeParameter('returnAll', i) as boolean; + if (returnAll === false) { + qs.limit = this.getNodeParameter('limit', i) as number; + } + + endpoint = `/deals`; + + } else if (operation === 'update') { + // ---------------------------------- + // deal:update + // ---------------------------------- + + requestMethod = 'PUT'; + + const dealId = this.getNodeParameter('dealId', i) as number; + endpoint = `/deals/${dealId}`; + + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + addAdditionalFields(body, updateFields); + + if (body.label === 'null') { + body.label = null; + } + } else if (operation === 'search') { + // ---------------------------------- + // deal:search + // ---------------------------------- + + requestMethod = 'GET'; + + qs.term = this.getNodeParameter('term', i) as string; + returnAll = this.getNodeParameter('returnAll', i) as boolean; + qs.exact_match = this.getNodeParameter('exactMatch', i) as boolean; + if (returnAll === false) { + qs.limit = this.getNodeParameter('limit', i) as number; + } + + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + + if (additionalFields.fields) { + qs.fields = (additionalFields.fields as string[]).join(','); + } + + if (additionalFields.organizationId) { + qs.organization_id = parseInt(additionalFields.organizationId as string, 10); + } + + if (additionalFields.includeFields) { + qs.include_fields = additionalFields.includeFields as string; + } + + if (additionalFields.personId) { + qs.person_id = parseInt(additionalFields.personId as string, 10); + } + if (additionalFields.status) { + qs.status = additionalFields.status as string; + } + + endpoint = `/deals/search`; + + } + } else if (resource === 'file') { + if (operation === 'create') { + // ---------------------------------- + // file:create + // ---------------------------------- + + requestMethod = 'POST'; + endpoint = '/files'; + + const item = items[i]; + + if (item.binary === undefined) { + throw new NodeOperationError(this.getNode(), 'No binary data exists on item!'); + } + + const binaryPropertyName = this.getNodeParameter('binaryPropertyName', i) as string; + + if (item.binary[binaryPropertyName] === undefined) { + throw new NodeOperationError(this.getNode(), `No binary data property "${binaryPropertyName}" does not exists on item!`); + } + + const fileBufferData = Buffer.from(item.binary[binaryPropertyName].data, BINARY_ENCODING); + + formData.file = { + value: fileBufferData, + options: { + contentType: item.binary[binaryPropertyName].mimeType, + filename: item.binary[binaryPropertyName].fileName, + }, + }; + + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + addAdditionalFields(formData, additionalFields); + + } else if (operation === 'delete') { + // ---------------------------------- + // file:delete + // ---------------------------------- + + requestMethod = 'DELETE'; + + const fileId = this.getNodeParameter('fileId', i) as number; + endpoint = `/files/${fileId}`; + + } else if (operation === 'download') { + // ---------------------------------- + // file:download + // ---------------------------------- + + requestMethod = 'GET'; + downloadFile = true; + + const fileId = this.getNodeParameter('fileId', i) as number; + endpoint = `/files/${fileId}/download`; + + } else if (operation === 'get') { + // ---------------------------------- + // file:get + // ---------------------------------- + + requestMethod = 'GET'; + + const fileId = this.getNodeParameter('fileId', i) as number; + endpoint = `/files/${fileId}`; + + } + } else if (resource === 'note') { + if (operation === 'create') { + // ---------------------------------- + // note:create + // ---------------------------------- + + requestMethod = 'POST'; + endpoint = '/notes'; + + body.content = this.getNodeParameter('content', i) as string; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + addAdditionalFields(body, additionalFields); + + } else if (operation === 'delete') { + // ---------------------------------- + // note:delete + // ---------------------------------- + + requestMethod = 'DELETE'; + + const noteId = this.getNodeParameter('noteId', i) as number; + endpoint = `/notes/${noteId}`; + + } else if (operation === 'get') { + // ---------------------------------- + // note:get + // ---------------------------------- + + requestMethod = 'GET'; + + const noteId = this.getNodeParameter('noteId', i) as number; + endpoint = `/notes/${noteId}`; + + } else if (operation === 'getAll') { + // ---------------------------------- + // note:getAll + // ---------------------------------- + + requestMethod = 'GET'; + endpoint = `/notes`; + + returnAll = this.getNodeParameter('returnAll', i) as boolean; + if (returnAll === false) { + qs.limit = this.getNodeParameter('limit', i) as number; + } + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + addAdditionalFields(qs, additionalFields); + + } else if (operation === 'update') { + // ---------------------------------- + // note:update + // ---------------------------------- + + requestMethod = 'PUT'; + + const noteId = this.getNodeParameter('noteId', i) as number; + endpoint = `/notes/${noteId}`; + + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + addAdditionalFields(body, updateFields); + + } + } else if (resource === 'organization') { + if (operation === 'create') { + // ---------------------------------- + // organization:create + // ---------------------------------- + + requestMethod = 'POST'; + endpoint = '/organizations'; + + body.name = this.getNodeParameter('name', i) as string; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + addAdditionalFields(body, additionalFields); + + } else if (operation === 'delete') { + // ---------------------------------- + // organization:delete + // ---------------------------------- + + requestMethod = 'DELETE'; + + const organizationId = this.getNodeParameter('organizationId', i) as number; + endpoint = `/organizations/${organizationId}`; + + } else if (operation === 'get') { + // ---------------------------------- + // organization:get + // ---------------------------------- + + requestMethod = 'GET'; + + const organizationId = this.getNodeParameter('organizationId', i) as number; + endpoint = `/organizations/${organizationId}`; + + } else if (operation === 'getAll') { + // ---------------------------------- + // organization:getAll + // ---------------------------------- + + requestMethod = 'GET'; + + returnAll = this.getNodeParameter('returnAll', i) as boolean; + if (returnAll === false) { + qs.limit = this.getNodeParameter('limit', i) as number; + } + + endpoint = `/organizations`; + + } + if (operation === 'update') { + // ---------------------------------- + // organization:update + // ---------------------------------- + + const id = this.getNodeParameter('organizationId', i) as string; + + requestMethod = 'PUT'; + endpoint = `/organizations/${id}`; + + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + addAdditionalFields(body, updateFields); + + if (body.label === 'null') { + body.label = null; + } + + } + } else if (resource === 'person') { + if (operation === 'create') { + // ---------------------------------- + // person:create + // ---------------------------------- + + requestMethod = 'POST'; + endpoint = '/persons'; + + body.name = this.getNodeParameter('name', i) as string; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + addAdditionalFields(body, additionalFields); + + } else if (operation === 'delete') { + // ---------------------------------- + // person:delete + // ---------------------------------- + + requestMethod = 'DELETE'; + + const personId = this.getNodeParameter('personId', i) as number; + endpoint = `/persons/${personId}`; + + } else if (operation === 'get') { + // ---------------------------------- + // person:get + // ---------------------------------- + + requestMethod = 'GET'; + + const personId = this.getNodeParameter('personId', i) as number; + endpoint = `/persons/${personId}`; + + } else if (operation === 'getAll') { + // ---------------------------------- + // persons:getAll + // ---------------------------------- + + requestMethod = 'GET'; + + returnAll = this.getNodeParameter('returnAll', i) as boolean; + if (returnAll === false) { + qs.limit = this.getNodeParameter('limit', i) as number; + } + + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + + if (additionalFields.filterId) { + qs.filter_id = additionalFields.filterId as string; + } + + if (additionalFields.firstChar) { + qs.first_char = additionalFields.firstChar as string; + } + + endpoint = `/persons`; + + } else if (operation === 'search') { + // ---------------------------------- + // persons:search + // ---------------------------------- + + requestMethod = 'GET'; + + qs.term = this.getNodeParameter('term', i) as string; + returnAll = this.getNodeParameter('returnAll', i) as boolean; + if (returnAll === false) { + qs.limit = this.getNodeParameter('limit', i) as number; + } + + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + + if (additionalFields.fields) { + qs.fields = additionalFields.fields as string; + } + + if (additionalFields.exactMatch) { + qs.exact_match = additionalFields.exactMatch as boolean; + } + + if (additionalFields.organizationId) { + qs.organization_id = parseInt(additionalFields.organizationId as string, 10); + } + + if (additionalFields.includeFields) { + qs.include_fields = additionalFields.includeFields as string; + } + + endpoint = `/persons/search`; + + } else if (operation === 'update') { + // ---------------------------------- + // person:update + // ---------------------------------- + + requestMethod = 'PUT'; + + const personId = this.getNodeParameter('personId', i) as number; + endpoint = `/persons/${personId}`; + + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + addAdditionalFields(body, updateFields); + + if (body.label === 'null') { + body.label = null; + } + + } + } else if (resource === 'product') { + if (operation === 'getAll') { + // ---------------------------------- + // product:getAll + // ---------------------------------- + + requestMethod = 'GET'; + + returnAll = this.getNodeParameter('returnAll', i) as boolean; + if (returnAll === false) { + qs.limit = this.getNodeParameter('limit', i) as number; + } + + endpoint = `/products`; + + } + } else { + throw new NodeOperationError(this.getNode(), `The resource "${resource}" is not known!`); + } + + let responseData; + if (returnAll === true) { + + responseData = await pipedriveApiRequestAllItems.call(this, requestMethod, endpoint, body, qs); + + } else { + + if (customProperties !== undefined) { + pipedriveEncodeCustomProperties(customProperties!, body); } - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - addAdditionalFields(qs, additionalFields); - - if (qs.type) { - qs.type = (qs.type as string[]).join(','); - } - - endpoint = `/activities`; - - } else if (operation === 'update') { - // ---------------------------------- - // activity:update - // ---------------------------------- - - requestMethod = 'PUT'; - - const activityId = this.getNodeParameter('activityId', i) as number; - endpoint = `/activities/${activityId}`; - - const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; - addAdditionalFields(body, updateFields); + responseData = await pipedriveApiRequest.call(this, requestMethod, endpoint, body, qs, formData, downloadFile); } - } else if (resource === 'deal') { - if (operation === 'create') { - // ---------------------------------- - // deal:create - // ---------------------------------- - requestMethod = 'POST'; - endpoint = '/deals'; + if (resource === 'file' && operation === 'download') { + const newItem: INodeExecutionData = { + json: items[i].json, + binary: {}, + }; - body.title = this.getNodeParameter('title', i) as string; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - addAdditionalFields(body, additionalFields); - - } else if (operation === 'delete') { - // ---------------------------------- - // deal:delete - // ---------------------------------- - - requestMethod = 'DELETE'; - - const dealId = this.getNodeParameter('dealId', i) as number; - endpoint = `/deals/${dealId}`; - - } else if (operation === 'duplicate') { - // ---------------------------------- - // deal:duplicate - // ---------------------------------- - - requestMethod = 'POST'; - - const dealId = this.getNodeParameter('dealId', i) as number; - endpoint = `/deals/${dealId}/duplicate`; - - } else if (operation === 'get') { - // ---------------------------------- - // deal:get - // ---------------------------------- - - requestMethod = 'GET'; - - const dealId = this.getNodeParameter('dealId', i) as number; - endpoint = `/deals/${dealId}`; - - } else if (operation === 'getAll') { - // ---------------------------------- - // deal:getAll - // ---------------------------------- - - requestMethod = 'GET'; - - returnAll = this.getNodeParameter('returnAll', i) as boolean; - if (returnAll === false) { - qs.limit = this.getNodeParameter('limit', i) as number; + if (items[i].binary !== undefined) { + // Create a shallow copy of the binary data so that the old + // data references which do not get changed still stay behind + // but the incoming data does not get changed. + Object.assign(newItem.binary, items[i].binary); } - endpoint = `/deals`; - - } else if (operation === 'update') { - // ---------------------------------- - // deal:update - // ---------------------------------- - - requestMethod = 'PUT'; - - const dealId = this.getNodeParameter('dealId', i) as number; - endpoint = `/deals/${dealId}`; - - const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; - addAdditionalFields(body, updateFields); - - if (body.label === 'null') { - body.label = null; - } - } else if (operation === 'search') { - // ---------------------------------- - // deal:search - // ---------------------------------- - - requestMethod = 'GET'; - - qs.term = this.getNodeParameter('term', i) as string; - returnAll = this.getNodeParameter('returnAll', i) as boolean; - qs.exact_match = this.getNodeParameter('exactMatch', i) as boolean; - if (returnAll === false) { - qs.limit = this.getNodeParameter('limit', i) as number; - } - - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - - if (additionalFields.fields) { - qs.fields = (additionalFields.fields as string[]).join(','); - } - - if (additionalFields.organizationId) { - qs.organization_id = parseInt(additionalFields.organizationId as string, 10); - } - - if (additionalFields.includeFields) { - qs.include_fields = additionalFields.includeFields as string; - } - - if (additionalFields.personId) { - qs.person_id = parseInt(additionalFields.personId as string, 10); - } - if (additionalFields.status) { - qs.status = additionalFields.status as string; - } - - endpoint = `/deals/search`; - - } - } else if (resource === 'file') { - if (operation === 'create') { - // ---------------------------------- - // file:create - // ---------------------------------- - - requestMethod = 'POST'; - endpoint = '/files'; - - const item = items[i]; - - if (item.binary === undefined) { - throw new NodeOperationError(this.getNode(), 'No binary data exists on item!'); - } + items[i] = newItem; const binaryPropertyName = this.getNodeParameter('binaryPropertyName', i) as string; - if (item.binary[binaryPropertyName] === undefined) { - throw new NodeOperationError(this.getNode(), `No binary data property "${binaryPropertyName}" does not exists on item!`); - } - - const fileBufferData = Buffer.from(item.binary[binaryPropertyName].data, BINARY_ENCODING); - - formData.file = { - value: fileBufferData, - options: { - contentType: item.binary[binaryPropertyName].mimeType, - filename: item.binary[binaryPropertyName].fileName, - }, - }; - - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - addAdditionalFields(formData, additionalFields); - - } else if (operation === 'delete') { - // ---------------------------------- - // file:delete - // ---------------------------------- - - requestMethod = 'DELETE'; - - const fileId = this.getNodeParameter('fileId', i) as number; - endpoint = `/files/${fileId}`; - - } else if (operation === 'download') { - // ---------------------------------- - // file:download - // ---------------------------------- - - requestMethod = 'GET'; - downloadFile = true; - - const fileId = this.getNodeParameter('fileId', i) as number; - endpoint = `/files/${fileId}/download`; - - } else if (operation === 'get') { - // ---------------------------------- - // file:get - // ---------------------------------- - - requestMethod = 'GET'; - - const fileId = this.getNodeParameter('fileId', i) as number; - endpoint = `/files/${fileId}`; - - } - } else if (resource === 'note') { - if (operation === 'create') { - // ---------------------------------- - // note:create - // ---------------------------------- - - requestMethod = 'POST'; - endpoint = '/notes'; - - body.content = this.getNodeParameter('content', i) as string; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - addAdditionalFields(body, additionalFields); - - } else if (operation === 'delete') { - // ---------------------------------- - // note:delete - // ---------------------------------- - - requestMethod = 'DELETE'; - - const noteId = this.getNodeParameter('noteId', i) as number; - endpoint = `/notes/${noteId}`; - - } else if (operation === 'get') { - // ---------------------------------- - // note:get - // ---------------------------------- - - requestMethod = 'GET'; - - const noteId = this.getNodeParameter('noteId', i) as number; - endpoint = `/notes/${noteId}`; - - } else if (operation === 'getAll') { - // ---------------------------------- - // note:getAll - // ---------------------------------- - - requestMethod = 'GET'; - endpoint = `/notes`; - - returnAll = this.getNodeParameter('returnAll', i) as boolean; - if (returnAll === false) { - qs.limit = this.getNodeParameter('limit', i) as number; - } - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - addAdditionalFields(qs, additionalFields); - - } else if (operation === 'update') { - // ---------------------------------- - // note:update - // ---------------------------------- - - requestMethod = 'PUT'; - - const noteId = this.getNodeParameter('noteId', i) as number; - endpoint = `/notes/${noteId}`; - - const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; - addAdditionalFields(body, updateFields); - - } - } else if (resource === 'organization') { - if (operation === 'create') { - // ---------------------------------- - // organization:create - // ---------------------------------- - - requestMethod = 'POST'; - endpoint = '/organizations'; - - body.name = this.getNodeParameter('name', i) as string; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - addAdditionalFields(body, additionalFields); - - } else if (operation === 'delete') { - // ---------------------------------- - // organization:delete - // ---------------------------------- - - requestMethod = 'DELETE'; - - const organizationId = this.getNodeParameter('organizationId', i) as number; - endpoint = `/organizations/${organizationId}`; - - } else if (operation === 'get') { - // ---------------------------------- - // organization:get - // ---------------------------------- - - requestMethod = 'GET'; - - const organizationId = this.getNodeParameter('organizationId', i) as number; - endpoint = `/organizations/${organizationId}`; - - } else if (operation === 'getAll') { - // ---------------------------------- - // organization:getAll - // ---------------------------------- - - requestMethod = 'GET'; - - returnAll = this.getNodeParameter('returnAll', i) as boolean; - if (returnAll === false) { - qs.limit = this.getNodeParameter('limit', i) as number; - } - - endpoint = `/organizations`; - - } - if (operation === 'update') { - // ---------------------------------- - // organization:update - // ---------------------------------- - - const id = this.getNodeParameter('organizationId', i) as string; - - requestMethod = 'PUT'; - endpoint = `/organizations/${id}`; - - const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; - addAdditionalFields(body, updateFields); - - if (body.label === 'null') { - body.label = null; - } - - } - } else if (resource === 'person') { - if (operation === 'create') { - // ---------------------------------- - // person:create - // ---------------------------------- - - requestMethod = 'POST'; - endpoint = '/persons'; - - body.name = this.getNodeParameter('name', i) as string; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - addAdditionalFields(body, additionalFields); - - } else if (operation === 'delete') { - // ---------------------------------- - // person:delete - // ---------------------------------- - - requestMethod = 'DELETE'; - - const personId = this.getNodeParameter('personId', i) as number; - endpoint = `/persons/${personId}`; - - } else if (operation === 'get') { - // ---------------------------------- - // person:get - // ---------------------------------- - - requestMethod = 'GET'; - - const personId = this.getNodeParameter('personId', i) as number; - endpoint = `/persons/${personId}`; - - } else if (operation === 'getAll') { - // ---------------------------------- - // persons:getAll - // ---------------------------------- - - requestMethod = 'GET'; - - returnAll = this.getNodeParameter('returnAll', i) as boolean; - if (returnAll === false) { - qs.limit = this.getNodeParameter('limit', i) as number; - } - - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - - if (additionalFields.filterId) { - qs.filter_id = additionalFields.filterId as string; - } - - if (additionalFields.firstChar) { - qs.first_char = additionalFields.firstChar as string; - } - - endpoint = `/persons`; - - } else if (operation === 'search') { - // ---------------------------------- - // persons:search - // ---------------------------------- - - requestMethod = 'GET'; - - qs.term = this.getNodeParameter('term', i) as string; - returnAll = this.getNodeParameter('returnAll', i) as boolean; - if (returnAll === false) { - qs.limit = this.getNodeParameter('limit', i) as number; - } - - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - - if (additionalFields.fields) { - qs.fields = additionalFields.fields as string; - } - - if (additionalFields.exactMatch) { - qs.exact_match = additionalFields.exactMatch as boolean; - } - - if (additionalFields.organizationId) { - qs.organization_id = parseInt(additionalFields.organizationId as string, 10); - } - - if (additionalFields.includeFields) { - qs.include_fields = additionalFields.includeFields as string; - } - - endpoint = `/persons/search`; - - } else if (operation === 'update') { - // ---------------------------------- - // person:update - // ---------------------------------- - - requestMethod = 'PUT'; - - const personId = this.getNodeParameter('personId', i) as number; - endpoint = `/persons/${personId}`; - - const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; - addAdditionalFields(body, updateFields); - - if (body.label === 'null') { - body.label = null; - } - - } - } else if (resource === 'product') { - if (operation === 'getAll') { - // ---------------------------------- - // product:getAll - // ---------------------------------- - - requestMethod = 'GET'; - - returnAll = this.getNodeParameter('returnAll', i) as boolean; - if (returnAll === false) { - qs.limit = this.getNodeParameter('limit', i) as number; - } - - endpoint = `/products`; - - } - } else { - throw new NodeOperationError(this.getNode(), `The resource "${resource}" is not known!`); - } - - let responseData; - if (returnAll === true) { - - responseData = await pipedriveApiRequestAllItems.call(this, requestMethod, endpoint, body, qs); - - } else { - - if (customProperties !== undefined) { - pipedriveEncodeCustomProperties(customProperties!, body); - } - - responseData = await pipedriveApiRequest.call(this, requestMethod, endpoint, body, qs, formData, downloadFile); - - } - - if (resource === 'file' && operation === 'download') { - const newItem: INodeExecutionData = { - json: items[i].json, - binary: {}, - }; - - if (items[i].binary !== undefined) { - // Create a shallow copy of the binary data so that the old - // data references which do not get changed still stay behind - // but the incoming data does not get changed. - Object.assign(newItem.binary, items[i].binary); - } - - items[i] = newItem; - - const binaryPropertyName = this.getNodeParameter('binaryPropertyName', i) as string; - - items[i].binary![binaryPropertyName] = await this.helpers.prepareBinaryData(responseData.data); - } else { - - if (responseData.data === null) { - responseData.data = []; - } - - if (operation === 'search' && responseData.data && responseData.data.items) { - responseData.data = responseData.data.items; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - if (additionalFields.rawData !== true) { - responseData.data = responseData.data.map((item: { result_score: number, item: object }) => { - return { - result_score: item.result_score, - ...item.item, - }; - }); - } - } - - if (Array.isArray(responseData.data)) { - returnData.push.apply(returnData, responseData.data as IDataObject[]); + items[i].binary![binaryPropertyName] = await this.helpers.prepareBinaryData(responseData.data); } else { - returnData.push(responseData.data as IDataObject); + + if (responseData.data === null) { + responseData.data = []; + } + + if (operation === 'search' && responseData.data && responseData.data.items) { + responseData.data = responseData.data.items; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + if (additionalFields.rawData !== true) { + responseData.data = responseData.data.map((item: { result_score: number, item: object }) => { + return { + result_score: item.result_score, + ...item.item, + }; + }); + } + } + + if (Array.isArray(responseData.data)) { + returnData.push.apply(returnData, responseData.data as IDataObject[]); + } else { + returnData.push(responseData.data as IDataObject); + } } + } catch (error) { + if (this.continueOnFail()) { + if (resource === 'file' && operation === 'download') { + items[i].json = { error: error.message }; + } else { + returnData.push({ error: error.message }); + } + continue; + } + throw error; } } diff --git a/packages/nodes-base/nodes/PostHog/PostHog.node.ts b/packages/nodes-base/nodes/PostHog/PostHog.node.ts index 7f4dbce2c5..4598e5ef44 100644 --- a/packages/nodes-base/nodes/PostHog/PostHog.node.ts +++ b/packages/nodes-base/nodes/PostHog/PostHog.node.ts @@ -109,99 +109,123 @@ export class PostHog implements INodeType { if (resource === 'alias') { if (operation === 'create') { for (let i = 0; i < length; i++) { - const distinctId = this.getNodeParameter('distinctId', i) as string; + try { + const distinctId = this.getNodeParameter('distinctId', i) as string; - const alias = this.getNodeParameter('alias', i) as string; + const alias = this.getNodeParameter('alias', i) as string; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const context = (additionalFields.contextUi as IDataObject || {}).contextValues as IDataObject[] || []; + const context = (additionalFields.contextUi as IDataObject || {}).contextValues as IDataObject[] || []; - const event: IAlias = { - type: 'alias', - event: '$create_alias', - context: context.reduce((obj, value) => Object.assign(obj, { [`${value.key}`]: value.value }), {}), - properties: { - distinct_id: distinctId, - alias, - }, - }; + const event: IAlias = { + type: 'alias', + event: '$create_alias', + context: context.reduce((obj, value) => Object.assign(obj, { [`${value.key}`]: value.value }), {}), + properties: { + distinct_id: distinctId, + alias, + }, + }; - Object.assign(event, additionalFields); + Object.assign(event, additionalFields); - if (additionalFields.timestamp) { - additionalFields.timestamp = moment(additionalFields.timestamp as string).toISOString(); + if (additionalFields.timestamp) { + additionalFields.timestamp = moment(additionalFields.timestamp as string).toISOString(); + } + + responseData = await posthogApiRequest.call(this, 'POST', '/batch', event); + + returnData.push(responseData); + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } - - responseData = await posthogApiRequest.call(this, 'POST', '/batch', event); - - returnData.push(responseData); } } } if (resource === 'event') { if (operation === 'create') { - const events: IEvent[] = []; - for (let i = 0; i < length; i++) { - const eventName = this.getNodeParameter('eventName', i) as string; + try { + const events: IEvent[] = []; + for (let i = 0; i < length; i++) { + const eventName = this.getNodeParameter('eventName', i) as string; - const distinctId = this.getNodeParameter('distinctId', i) as string; + const distinctId = this.getNodeParameter('distinctId', i) as string; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const properties = (additionalFields.propertiesUi as IDataObject || {}).propertyValues as IDataObject[] || []; + const properties = (additionalFields.propertiesUi as IDataObject || {}).propertyValues as IDataObject[] || []; - const event: IEvent = { - event: eventName, - properties: properties.reduce((obj, value) => Object.assign(obj, { [`${value.key}`]: value.value }), {}), - }; + const event: IEvent = { + event: eventName, + properties: properties.reduce((obj, value) => Object.assign(obj, { [`${value.key}`]: value.value }), {}), + }; - event.properties['distinct_id'] = distinctId; + event.properties['distinct_id'] = distinctId; - Object.assign(event, additionalFields); + Object.assign(event, additionalFields); - if (additionalFields.timestamp) { - additionalFields.timestamp = moment(additionalFields.timestamp as string).toISOString(); + if (additionalFields.timestamp) { + additionalFields.timestamp = moment(additionalFields.timestamp as string).toISOString(); + } + //@ts-ignore + delete event.propertiesUi; + + events.push(event); } - //@ts-ignore - delete event.propertiesUi; - events.push(event); + responseData = await posthogApiRequest.call(this, 'POST', '/capture', { batch: events }); + + returnData.push(responseData); + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + } else { + throw error; + } } - - responseData = await posthogApiRequest.call(this, 'POST', '/capture', { batch: events }); - - returnData.push(responseData); } } if (resource === 'identity') { if (operation === 'create') { for (let i = 0; i < length; i++) { - const distinctId = this.getNodeParameter('distinctId', i) as string; + try { + const distinctId = this.getNodeParameter('distinctId', i) as string; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const properties = (additionalFields.propertiesUi as IDataObject || {}).propertyValues as IDataObject[] || []; + const properties = (additionalFields.propertiesUi as IDataObject || {}).propertyValues as IDataObject[] || []; - const event: IIdentity = { - event: '$identify', - properties: properties.reduce((obj, value) => Object.assign(obj, { [`${value.key}`]: value.value }), {}), - distinct_id: distinctId, - }; + const event: IIdentity = { + event: '$identify', + properties: properties.reduce((obj, value) => Object.assign(obj, { [`${value.key}`]: value.value }), {}), + distinct_id: distinctId, + }; - Object.assign(event, additionalFields); + Object.assign(event, additionalFields); - if (additionalFields.timestamp) { - additionalFields.timestamp = moment(additionalFields.timestamp as string).toISOString(); + if (additionalFields.timestamp) { + additionalFields.timestamp = moment(additionalFields.timestamp as string).toISOString(); + } + //@ts-ignore + delete event.propertiesUi; + + responseData = await posthogApiRequest.call(this, 'POST', '/batch', event); + + returnData.push(responseData); + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } - //@ts-ignore - delete event.propertiesUi; - - responseData = await posthogApiRequest.call(this, 'POST', '/batch', event); - - returnData.push(responseData); } } } @@ -209,36 +233,44 @@ export class PostHog implements INodeType { if (resource === 'track') { if (operation === 'page' || operation === 'screen') { for (let i = 0; i < length; i++) { - const distinctId = this.getNodeParameter('distinctId', i) as string; + try { + const distinctId = this.getNodeParameter('distinctId', i) as string; - const name = this.getNodeParameter('name', i) as string; + const name = this.getNodeParameter('name', i) as string; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const context = (additionalFields.contextUi as IDataObject || {}).contextValues as IDataObject[] || []; + const context = (additionalFields.contextUi as IDataObject || {}).contextValues as IDataObject[] || []; - const properties = (additionalFields.propertiesUi as IDataObject || {}).propertyValues as IDataObject[] || []; + const properties = (additionalFields.propertiesUi as IDataObject || {}).propertyValues as IDataObject[] || []; - const event: ITrack = { - name, - type: operation, - event: `$${operation}`, - context: context.reduce((obj, value) => Object.assign(obj, { [`${value.key}`]: value.value }), {}), - distinct_id: distinctId, - properties: properties.reduce((obj, value) => Object.assign(obj, { [`${value.key}`]: value.value }), {}), - }; + const event: ITrack = { + name, + type: operation, + event: `$${operation}`, + context: context.reduce((obj, value) => Object.assign(obj, { [`${value.key}`]: value.value }), {}), + distinct_id: distinctId, + properties: properties.reduce((obj, value) => Object.assign(obj, { [`${value.key}`]: value.value }), {}), + }; - Object.assign(event, additionalFields); + Object.assign(event, additionalFields); - if (additionalFields.timestamp) { - additionalFields.timestamp = moment(additionalFields.timestamp as string).toISOString(); + if (additionalFields.timestamp) { + additionalFields.timestamp = moment(additionalFields.timestamp as string).toISOString(); + } + //@ts-ignore + delete event.propertiesUi; + + responseData = await posthogApiRequest.call(this, 'POST', '/batch', event); + + returnData.push(responseData); + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } - //@ts-ignore - delete event.propertiesUi; - - responseData = await posthogApiRequest.call(this, 'POST', '/batch', event); - - returnData.push(responseData); } } } diff --git a/packages/nodes-base/nodes/ProfitWell/ProfitWell.node.ts b/packages/nodes-base/nodes/ProfitWell/ProfitWell.node.ts index ebd8e86cb6..c53106d7c8 100644 --- a/packages/nodes-base/nodes/ProfitWell/ProfitWell.node.ts +++ b/packages/nodes-base/nodes/ProfitWell/ProfitWell.node.ts @@ -104,50 +104,58 @@ export class ProfitWell implements INodeType { 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 === 'company') { - if (operation === 'getSetting') { - responseData = await profitWellApiRequest.call(this, 'GET', `/company/settings/`); + try { + if (resource === 'company') { + if (operation === 'getSetting') { + responseData = await profitWellApiRequest.call(this, 'GET', `/company/settings/`); + } } - } - if (resource === 'metric') { - if (operation === 'get') { - const type = this.getNodeParameter('type', i) as string; + if (resource === 'metric') { + if (operation === 'get') { + const type = this.getNodeParameter('type', i) as string; - const simple = this.getNodeParameter('simple', 0) as boolean; + const simple = this.getNodeParameter('simple', 0) as boolean; - if (type === 'daily') { - qs.month = this.getNodeParameter('month', i) as string; - } - const options = this.getNodeParameter('options', i) as IDataObject; - - Object.assign(qs, options); - - if (qs.dailyMetrics) { - qs.metrics = (qs.dailyMetrics as string[]).join(','); - delete qs.dailyMetrics; - } - - if (qs.monthlyMetrics) { - qs.metrics = (qs.monthlyMetrics as string[]).join(','); - delete qs.monthlyMetrics; - } - - responseData = await profitWellApiRequest.call(this, 'GET', `/metrics/${type}`, {}, qs); - responseData = responseData.data; - - if (simple === true) { if (type === 'daily') { - responseData = simplifyDailyMetrics(responseData); - } else { - responseData = simplifyMontlyMetrics(responseData); + qs.month = this.getNodeParameter('month', i) as string; + } + const options = this.getNodeParameter('options', i) as IDataObject; + + Object.assign(qs, options); + + if (qs.dailyMetrics) { + qs.metrics = (qs.dailyMetrics as string[]).join(','); + delete qs.dailyMetrics; + } + + if (qs.monthlyMetrics) { + qs.metrics = (qs.monthlyMetrics as string[]).join(','); + delete qs.monthlyMetrics; + } + + responseData = await profitWellApiRequest.call(this, 'GET', `/metrics/${type}`, {}, qs); + responseData = responseData.data; + + if (simple === true) { + if (type === 'daily') { + responseData = simplifyDailyMetrics(responseData); + } else { + responseData = simplifyMontlyMetrics(responseData); + } } } } - } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else { - returnData.push(responseData as IDataObject); + if (Array.isArray(responseData)) { + returnData.push.apply(returnData, responseData as IDataObject[]); + } else { + returnData.push(responseData as IDataObject); + } + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } } return [this.helpers.returnJsonArray(returnData)]; diff --git a/packages/nodes-base/nodes/Pushbullet/Pushbullet.node.ts b/packages/nodes-base/nodes/Pushbullet/Pushbullet.node.ts index ea95fe61ca..718a5f8a5b 100644 --- a/packages/nodes-base/nodes/Pushbullet/Pushbullet.node.ts +++ b/packages/nodes-base/nodes/Pushbullet/Pushbullet.node.ts @@ -456,154 +456,162 @@ export class Pushbullet implements INodeType { const resource = this.getNodeParameter('resource', 0) as string; const operation = this.getNodeParameter('operation', 0) as string; for (let i = 0; i < length; i++) { + try { + if (resource === 'push') { + if (operation === 'create') { + const type = this.getNodeParameter('type', i) as string; - if (resource === 'push') { - if (operation === 'create') { - const type = this.getNodeParameter('type', i) as string; + const message = this.getNodeParameter('body', i) as string; - const message = this.getNodeParameter('body', i) as string; + const target = this.getNodeParameter('target', i) as string; - const target = this.getNodeParameter('target', i) as string; + const body: IDataObject = { + type, + body: message, + }; - const body: IDataObject = { - type, - body: message, - }; - - if (target !== 'default') { - const value = this.getNodeParameter('value', i) as string; - body[target as string] = value; - } - - if (['note', 'link'].includes(type)) { - body.title = this.getNodeParameter('title', i) as string; - - if (type === 'link') { - body.url = this.getNodeParameter('url', i) as string; - } - } - - if (type === 'file') { - const binaryPropertyName = this.getNodeParameter('binaryPropertyName', 0) as string; - - if (items[i].binary === undefined) { - throw new NodeOperationError(this.getNode(), 'No binary data exists on item!'); - } - //@ts-ignore - if (items[i].binary[binaryPropertyName] === undefined) { - throw new NodeOperationError(this.getNode(), `No binary data property "${binaryPropertyName}" does not exists on item!`); + if (target !== 'default') { + const value = this.getNodeParameter('value', i) as string; + body[target as string] = value; } - const binaryData = (items[i].binary as IBinaryKeyData)[binaryPropertyName]; + if (['note', 'link'].includes(type)) { + body.title = this.getNodeParameter('title', i) as string; - //create upload url - const { - upload_url: uploadUrl, - file_name, - file_type, - file_url, - } = await pushbulletApiRequest.call( - this, - 'POST', - `/upload-request`, - { - file_name: binaryData.fileName, - file_type: binaryData.mimeType, - }, - ); + if (type === 'link') { + body.url = this.getNodeParameter('url', i) as string; + } + } - //upload the file - await pushbulletApiRequest.call( - this, - 'POST', - '', - {}, - {}, - uploadUrl, - { - formData: { - file: { - value: Buffer.from(binaryData.data, BINARY_ENCODING), - options: { - filename: binaryData.fileName, + if (type === 'file') { + const binaryPropertyName = this.getNodeParameter('binaryPropertyName', 0) as string; + + if (items[i].binary === undefined) { + throw new NodeOperationError(this.getNode(), 'No binary data exists on item!'); + } + //@ts-ignore + if (items[i].binary[binaryPropertyName] === undefined) { + throw new NodeOperationError(this.getNode(), `No binary data property "${binaryPropertyName}" does not exists on item!`); + } + + const binaryData = (items[i].binary as IBinaryKeyData)[binaryPropertyName]; + + //create upload url + const { + upload_url: uploadUrl, + file_name, + file_type, + file_url, + } = await pushbulletApiRequest.call( + this, + 'POST', + `/upload-request`, + { + file_name: binaryData.fileName, + file_type: binaryData.mimeType, + }, + ); + + //upload the file + await pushbulletApiRequest.call( + this, + 'POST', + '', + {}, + {}, + uploadUrl, + { + formData: { + file: { + value: Buffer.from(binaryData.data, BINARY_ENCODING), + options: { + filename: binaryData.fileName, + }, }, }, + json: false, }, - json: false, - }, + ); + + body.file_name = file_name; + body.file_type = file_type; + body.file_url = file_url; + } + + responseData = await pushbulletApiRequest.call( + this, + 'POST', + `/pushes`, + body, + ); + } + + if (operation === 'getAll') { + const returnAll = this.getNodeParameter('returnAll', 0) as boolean; + + const filters = this.getNodeParameter('filters', i) as IDataObject; + + Object.assign(qs, filters); + + if (qs.modified_after) { + qs.modified_after = moment(qs.modified_after as string).unix(); + } + + if (returnAll) { + responseData = await pushbulletApiRequestAllItems.call(this, 'pushes', 'GET', '/pushes', {}, qs); + + } else { + qs.limit = this.getNodeParameter('limit', 0) as number; + + responseData = await pushbulletApiRequest.call(this, 'GET', '/pushes', {}, qs); + + responseData = responseData.pushes; + } + } + + if (operation === 'delete') { + const pushId = this.getNodeParameter('pushId', i) as string; + + responseData = await pushbulletApiRequest.call( + this, + 'DELETE', + `/pushes/${pushId}`, ); - body.file_name = file_name; - body.file_type = file_type; - body.file_url = file_url; + responseData = { success: true }; } - responseData = await pushbulletApiRequest.call( - this, - 'POST', - `/pushes`, - body, - ); - } + if (operation === 'update') { + const pushId = this.getNodeParameter('pushId', i) as string; - if (operation === 'getAll') { - const returnAll = this.getNodeParameter('returnAll', 0) as boolean; + const dismissed = this.getNodeParameter('dismissed', i) as boolean; - const filters = this.getNodeParameter('filters', i) as IDataObject; - - Object.assign(qs, filters); - - if (qs.modified_after) { - qs.modified_after = moment(qs.modified_after as string).unix(); - } - - if (returnAll) { - responseData = await pushbulletApiRequestAllItems.call(this, 'pushes', 'GET', '/pushes', {}, qs); - - } else { - qs.limit = this.getNodeParameter('limit', 0) as number; - - responseData = await pushbulletApiRequest.call(this, 'GET', '/pushes', {}, qs); - - responseData = responseData.pushes; + responseData = await pushbulletApiRequest.call( + this, + 'POST', + `/pushes/${pushId}`, + { + dismissed, + }, + ); } } + if (Array.isArray(responseData)) { + returnData.push.apply(returnData, responseData as IDataObject[]); - if (operation === 'delete') { - const pushId = this.getNodeParameter('pushId', i) as string; + } else if (responseData !== undefined) { + returnData.push(responseData as IDataObject); - responseData = await pushbulletApiRequest.call( - this, - 'DELETE', - `/pushes/${pushId}`, - ); - - responseData = { success: true }; } - - if (operation === 'update') { - const pushId = this.getNodeParameter('pushId', i) as string; - - const dismissed = this.getNodeParameter('dismissed', i) as boolean; - - responseData = await pushbulletApiRequest.call( - this, - 'POST', - `/pushes/${pushId}`, - { - dismissed, - }, - ); + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; } + throw error; } } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else if (responseData !== undefined) { - returnData.push(responseData as IDataObject); - - } return [this.helpers.returnJsonArray(returnData)]; } } diff --git a/packages/nodes-base/nodes/Pushover/Pushover.node.ts b/packages/nodes-base/nodes/Pushover/Pushover.node.ts index 44cc8438dd..b6b56f1459 100644 --- a/packages/nodes-base/nodes/Pushover/Pushover.node.ts +++ b/packages/nodes-base/nodes/Pushover/Pushover.node.ts @@ -322,68 +322,75 @@ export class Pushover implements INodeType { const resource = this.getNodeParameter('resource', 0) as string; const operation = this.getNodeParameter('operation', 0) as string; for (let i = 0; i < length; i++) { + try { + if (resource === 'message') { + if (operation === 'push') { + const userKey = this.getNodeParameter('userKey', i) as string; - if (resource === 'message') { - if (operation === 'push') { - const userKey = this.getNodeParameter('userKey', i) as string; + const message = this.getNodeParameter('message', i) as string; - const message = this.getNodeParameter('message', i) as string; + const priority = this.getNodeParameter('priority', i) as number; - const priority = this.getNodeParameter('priority', i) as number; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const body: IDataObject = { + user: userKey, + message, + priority, + }; - const body: IDataObject = { - user: userKey, - message, - priority, - }; + if (priority === 2) { + body.retry = this.getNodeParameter('retry', i) as number; - if (priority === 2) { - body.retry = this.getNodeParameter('retry', i) as number; - - body.expire = this.getNodeParameter('expire', i) as number; - } - - Object.assign(body, additionalFields); - - if (body.attachmentsUi) { - const attachment = (body.attachmentsUi as IDataObject).attachmentsValues as IDataObject; - - if (attachment) { - - const binaryPropertyName = attachment.binaryPropertyName as string; - - if (items[i].binary === undefined) { - throw new NodeOperationError(this.getNode(), 'No binary data exists on item!'); - } - - const item = items[i].binary as IBinaryKeyData; - - const binaryData = item[binaryPropertyName] as IBinaryData; - - if (binaryData === undefined) { - throw new NodeOperationError(this.getNode(), `No binary data property "${binaryPropertyName}" does not exists on item!`); - } - - body.attachment = { - value: Buffer.from(binaryData.data, BINARY_ENCODING), - options: { - filename: binaryData.fileName, - }, - }; - - delete body.attachmentsUi; + body.expire = this.getNodeParameter('expire', i) as number; } - } - responseData = await pushoverApiRequest.call( - this, - 'POST', - `/messages.json`, - body, - ); + Object.assign(body, additionalFields); + + if (body.attachmentsUi) { + const attachment = (body.attachmentsUi as IDataObject).attachmentsValues as IDataObject; + + if (attachment) { + + const binaryPropertyName = attachment.binaryPropertyName as string; + + if (items[i].binary === undefined) { + throw new NodeOperationError(this.getNode(), 'No binary data exists on item!'); + } + + const item = items[i].binary as IBinaryKeyData; + + const binaryData = item[binaryPropertyName] as IBinaryData; + + if (binaryData === undefined) { + throw new NodeOperationError(this.getNode(), `No binary data property "${binaryPropertyName}" does not exists on item!`); + } + + body.attachment = { + value: Buffer.from(binaryData.data, BINARY_ENCODING), + options: { + filename: binaryData.fileName, + }, + }; + + delete body.attachmentsUi; + } + } + + responseData = await pushoverApiRequest.call( + this, + 'POST', + `/messages.json`, + body, + ); + } } + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } } if (Array.isArray(responseData)) { diff --git a/packages/nodes-base/nodes/QuickBooks/QuickBooks.node.ts b/packages/nodes-base/nodes/QuickBooks/QuickBooks.node.ts index 9f3ad7a81d..31e4798dfb 100644 --- a/packages/nodes-base/nodes/QuickBooks/QuickBooks.node.ts +++ b/packages/nodes-base/nodes/QuickBooks/QuickBooks.node.ts @@ -181,845 +181,863 @@ export class QuickBooks implements INodeType { const companyId = oauthTokenData.callbackQueryString.realmId; for (let i = 0; i < items.length; i++) { + try { + if (resource === 'bill') { - if (resource === 'bill') { + // ********************************************************************* + // bill + // ********************************************************************* - // ********************************************************************* - // bill - // ********************************************************************* + // https://developer.intuit.com/app/developer/qbo/docs/api/accounting/most-commonly-used/bill - // https://developer.intuit.com/app/developer/qbo/docs/api/accounting/most-commonly-used/bill + if (operation === 'create') { - if (operation === 'create') { + // ---------------------------------- + // bill: create + // ---------------------------------- - // ---------------------------------- - // bill: create - // ---------------------------------- + const lines = this.getNodeParameter('Line', i) as IDataObject[]; - const lines = this.getNodeParameter('Line', i) as IDataObject[]; - - if (!lines.length) { - throw new NodeOperationError(this.getNode(), `Please enter at least one line for the ${resource}.`); - } - - if (lines.some(line => line.DetailType === undefined || line.Amount === undefined || line.Description === undefined)) { - throw new NodeOperationError(this.getNode(), 'Please enter detail type, amount and description for every line.'); - } - - lines.forEach(line => { - if (line.DetailType === 'AccountBasedExpenseLineDetail' && line.accountId === undefined) { - throw new NodeOperationError(this.getNode(), 'Please enter an account ID for the associated line.'); - } else if (line.DetailType === 'ItemBasedExpenseLineDetail' && line.itemId === undefined) { - throw new NodeOperationError(this.getNode(), 'Please enter an item ID for the associated line.'); + if (!lines.length) { + throw new NodeOperationError(this.getNode(), `Please enter at least one line for the ${resource}.`); } - }); - let body = { - VendorRef: { - value: this.getNodeParameter('VendorRef', i), - }, - } as IDataObject; - - body.Line = processLines.call(this, body, lines, resource); - - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - - body = populateFields.call(this, body, additionalFields, resource); - - const endpoint = `/v3/company/${companyId}/${resource}`; - responseData = await quickBooksApiRequest.call(this, 'POST', endpoint, {}, body); - responseData = responseData[capitalCase(resource)]; - - } else if (operation === 'delete') { - - // ---------------------------------- - // bill: delete - // ---------------------------------- - - const qs = { - operation: 'delete', - } as IDataObject; - - const body = { - Id: this.getNodeParameter('billId', i), - SyncToken: await getSyncToken.call(this, i, companyId, resource), - } as IDataObject; - - const endpoint = `/v3/company/${companyId}/${resource}`; - responseData = await quickBooksApiRequest.call(this, 'POST', endpoint, qs, body); - responseData = responseData[capitalCase(resource)]; - - } else if (operation === 'get') { - - // ---------------------------------- - // bill: get - // ---------------------------------- - - const billId = this.getNodeParameter('billId', i); - const endpoint = `/v3/company/${companyId}/${resource}/${billId}`; - responseData = await quickBooksApiRequest.call(this, 'GET', endpoint, {}, {}); - responseData = responseData[capitalCase(resource)]; - - } else if (operation === 'getAll') { - - // ---------------------------------- - // bill: getAll - // ---------------------------------- - - const endpoint = `/v3/company/${companyId}/query`; - responseData = await handleListing.call(this, i, endpoint, resource); - - } else if (operation === 'update') { - - // ---------------------------------- - // bill: update - // ---------------------------------- - - const { ref, syncToken } = await getRefAndSyncToken.call(this, i, companyId, resource, 'VendorRef'); - - let body = { - Id: this.getNodeParameter('billId', i), - SyncToken: syncToken, - sparse: true, - VendorRef: { - name: ref.name, - value: ref.value, - }, - } as IDataObject; - - const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; - - if (isEmpty(updateFields)) { - throw new NodeOperationError(this.getNode(), `Please enter at least one field to update for the ${resource}.`); - } - - body = populateFields.call(this, body, updateFields, resource); - - const endpoint = `/v3/company/${companyId}/${resource}`; - responseData = await quickBooksApiRequest.call(this, 'POST', endpoint, {}, body); - responseData = responseData[capitalCase(resource)]; - - } - - } else if (resource === 'customer') { - - // ********************************************************************* - // customer - // ********************************************************************* - - // https://developer.intuit.com/app/developer/qbo/docs/api/accounting/most-commonly-used/customer - - if (operation === 'create') { - - // ---------------------------------- - // customer: create - // ---------------------------------- - - let body = { - DisplayName: this.getNodeParameter('displayName', i), - } as IDataObject; - - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - - body = populateFields.call(this, body, additionalFields, resource); - - const endpoint = `/v3/company/${companyId}/${resource}`; - responseData = await quickBooksApiRequest.call(this, 'POST', endpoint, {}, body); - responseData = responseData[capitalCase(resource)]; - - } else if (operation === 'get') { - - // ---------------------------------- - // customer: get - // ---------------------------------- - - const customerId = this.getNodeParameter('customerId', i); - const endpoint = `/v3/company/${companyId}/${resource}/${customerId}`; - responseData = await quickBooksApiRequest.call(this, 'GET', endpoint, {}, {}); - responseData = responseData[capitalCase(resource)]; - - } else if (operation === 'getAll') { - - // ---------------------------------- - // customer: getAll - // ---------------------------------- - - const endpoint = `/v3/company/${companyId}/query`; - responseData = await handleListing.call(this, i, endpoint, resource); - - } else if (operation === 'update') { - - // ---------------------------------- - // customer: update - // ---------------------------------- - - let body = { - Id: this.getNodeParameter('customerId', i), - SyncToken: await getSyncToken.call(this, i, companyId, resource), - sparse: true, - } as IDataObject; - - const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; - - if (isEmpty(updateFields)) { - throw new NodeOperationError(this.getNode(), `Please enter at least one field to update for the ${resource}.`); - } - - body = populateFields.call(this, body, updateFields, resource); - - const endpoint = `/v3/company/${companyId}/${resource}`; - responseData = await quickBooksApiRequest.call(this, 'POST', endpoint, {}, body); - responseData = responseData[capitalCase(resource)]; - - } - - } else if (resource === 'employee') { - - // ********************************************************************* - // employee - // ********************************************************************* - - if (operation === 'create') { - - // ---------------------------------- - // employee: create - // ---------------------------------- - - let body = { - FamilyName: this.getNodeParameter('FamilyName', i), - GivenName: this.getNodeParameter('GivenName', i), - } as IDataObject; - - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - - body = populateFields.call(this, body, additionalFields, resource); - - const endpoint = `/v3/company/${companyId}/${resource}`; - responseData = await quickBooksApiRequest.call(this, 'POST', endpoint, {}, body); - responseData = responseData[capitalCase(resource)]; - - } else if (operation === 'get') { - - // ---------------------------------- - // employee: get - // ---------------------------------- - - const employeeId = this.getNodeParameter('employeeId', i); - const endpoint = `/v3/company/${companyId}/${resource}/${employeeId}`; - responseData = await quickBooksApiRequest.call(this, 'GET', endpoint, {}, {}); - responseData = responseData[capitalCase(resource)]; - - } else if (operation === 'getAll') { - - // ---------------------------------- - // employee: getAll - // ---------------------------------- - - const endpoint = `/v3/company/${companyId}/query`; - responseData = await handleListing.call(this, i, endpoint, resource); - - } else if (operation === 'update') { - - // ---------------------------------- - // employee: update - // ---------------------------------- - - let body = { - Id: this.getNodeParameter('employeeId', i), - SyncToken: await getSyncToken.call(this, i, companyId, resource), - sparse: true, - } as IDataObject; - - const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; - - if (isEmpty(updateFields)) { - throw new NodeOperationError(this.getNode(), `Please enter at least one field to update for the ${resource}.`); - } - - body = populateFields.call(this, body, updateFields, resource); - - const endpoint = `/v3/company/${companyId}/${resource}`; - responseData = await quickBooksApiRequest.call(this, 'POST', endpoint, {}, body); - responseData = responseData[capitalCase(resource)]; - - } - - } else if (resource === 'estimate') { - - // ********************************************************************* - // estimate - // ********************************************************************* - - // https://developer.intuit.com/app/developer/qbo/docs/api/accounting/most-commonly-used/estimate - - if (operation === 'create') { - - // ---------------------------------- - // estimate: create - // ---------------------------------- - - const lines = this.getNodeParameter('Line', i) as IDataObject[]; - - if (!lines.length) { - throw new NodeOperationError(this.getNode(), `Please enter at least one line for the ${resource}.`); - } - - if (lines.some(line => line.DetailType === undefined || line.Amount === undefined || line.Description === undefined)) { - throw new NodeOperationError(this.getNode(), 'Please enter detail type, amount and description for every line.'); - } - - lines.forEach(line => { - if (line.DetailType === 'SalesItemLineDetail' && line.itemId === undefined) { - throw new NodeOperationError(this.getNode(), 'Please enter an item ID for the associated line.'); + if (lines.some(line => line.DetailType === undefined || line.Amount === undefined || line.Description === undefined)) { + throw new NodeOperationError(this.getNode(), 'Please enter detail type, amount and description for every line.'); } - }); - let body = { - CustomerRef: { - value: this.getNodeParameter('CustomerRef', i), - }, - } as IDataObject; + lines.forEach(line => { + if (line.DetailType === 'AccountBasedExpenseLineDetail' && line.accountId === undefined) { + throw new NodeOperationError(this.getNode(), 'Please enter an account ID for the associated line.'); + } else if (line.DetailType === 'ItemBasedExpenseLineDetail' && line.itemId === undefined) { + throw new NodeOperationError(this.getNode(), 'Please enter an item ID for the associated line.'); + } + }); - body.Line = processLines.call(this, body, lines, resource); + let body = { + VendorRef: { + value: this.getNodeParameter('VendorRef', i), + }, + } as IDataObject; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + body.Line = processLines.call(this, body, lines, resource); - body = populateFields.call(this, body, additionalFields, resource); + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const endpoint = `/v3/company/${companyId}/${resource}`; - responseData = await quickBooksApiRequest.call(this, 'POST', endpoint, {}, body); - responseData = responseData[capitalCase(resource)]; + body = populateFields.call(this, body, additionalFields, resource); - } else if (operation === 'delete') { + const endpoint = `/v3/company/${companyId}/${resource}`; + responseData = await quickBooksApiRequest.call(this, 'POST', endpoint, {}, body); + responseData = responseData[capitalCase(resource)]; - // ---------------------------------- - // estimate: delete - // ---------------------------------- + } else if (operation === 'delete') { - const qs = { - operation: 'delete', - } as IDataObject; + // ---------------------------------- + // bill: delete + // ---------------------------------- - const body = { - Id: this.getNodeParameter('estimateId', i), - SyncToken: await getSyncToken.call(this, i, companyId, resource), - } as IDataObject; + const qs = { + operation: 'delete', + } as IDataObject; - const endpoint = `/v3/company/${companyId}/${resource}`; - responseData = await quickBooksApiRequest.call(this, 'POST', endpoint, qs, body); - responseData = responseData[capitalCase(resource)]; + const body = { + Id: this.getNodeParameter('billId', i), + SyncToken: await getSyncToken.call(this, i, companyId, resource), + } as IDataObject; - } else if (operation === 'get') { + const endpoint = `/v3/company/${companyId}/${resource}`; + responseData = await quickBooksApiRequest.call(this, 'POST', endpoint, qs, body); + responseData = responseData[capitalCase(resource)]; - // ---------------------------------- - // estimate: get - // ---------------------------------- + } else if (operation === 'get') { - const estimateId = this.getNodeParameter('estimateId', i) as string; - const download = this.getNodeParameter('download', i) as boolean; + // ---------------------------------- + // bill: get + // ---------------------------------- - if (download) { - - responseData = await handleBinaryData.call(this, items, i, companyId, resource, estimateId); - - } else { - - const endpoint = `/v3/company/${companyId}/${resource}/${estimateId}`; + const billId = this.getNodeParameter('billId', i); + const endpoint = `/v3/company/${companyId}/${resource}/${billId}`; responseData = await quickBooksApiRequest.call(this, 'GET', endpoint, {}, {}); responseData = responseData[capitalCase(resource)]; + } else if (operation === 'getAll') { + + // ---------------------------------- + // bill: getAll + // ---------------------------------- + + const endpoint = `/v3/company/${companyId}/query`; + responseData = await handleListing.call(this, i, endpoint, resource); + + } else if (operation === 'update') { + + // ---------------------------------- + // bill: update + // ---------------------------------- + + const { ref, syncToken } = await getRefAndSyncToken.call(this, i, companyId, resource, 'VendorRef'); + + let body = { + Id: this.getNodeParameter('billId', i), + SyncToken: syncToken, + sparse: true, + VendorRef: { + name: ref.name, + value: ref.value, + }, + } as IDataObject; + + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + + if (isEmpty(updateFields)) { + throw new NodeOperationError(this.getNode(), `Please enter at least one field to update for the ${resource}.`); + } + + body = populateFields.call(this, body, updateFields, resource); + + const endpoint = `/v3/company/${companyId}/${resource}`; + responseData = await quickBooksApiRequest.call(this, 'POST', endpoint, {}, body); + responseData = responseData[capitalCase(resource)]; + } - } else if (operation === 'getAll') { + } else if (resource === 'customer') { - // ---------------------------------- - // estimate: getAll - // ---------------------------------- + // ********************************************************************* + // customer + // ********************************************************************* - const endpoint = `/v3/company/${companyId}/query`; - responseData = await handleListing.call(this, i, endpoint, resource); + // https://developer.intuit.com/app/developer/qbo/docs/api/accounting/most-commonly-used/customer - } else if (operation === 'send') { + if (operation === 'create') { - // ---------------------------------- - // estimate: send - // ---------------------------------- + // ---------------------------------- + // customer: create + // ---------------------------------- - const estimateId = this.getNodeParameter('estimateId', i) as string; + let body = { + DisplayName: this.getNodeParameter('displayName', i), + } as IDataObject; - const qs = { - sendTo: this.getNodeParameter('email', i) as string, - } as IDataObject; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const endpoint = `/v3/company/${companyId}/${resource}/${estimateId}/send`; - responseData = await quickBooksApiRequest.call(this, 'POST', endpoint, qs, {}); - responseData = responseData[capitalCase(resource)]; + body = populateFields.call(this, body, additionalFields, resource); - } else if (operation === 'update') { + const endpoint = `/v3/company/${companyId}/${resource}`; + responseData = await quickBooksApiRequest.call(this, 'POST', endpoint, {}, body); + responseData = responseData[capitalCase(resource)]; - // ---------------------------------- - // estimate: update - // ---------------------------------- + } else if (operation === 'get') { - const { ref, syncToken } = await getRefAndSyncToken.call(this, i, companyId, resource, 'CustomerRef'); + // ---------------------------------- + // customer: get + // ---------------------------------- - let body = { - Id: this.getNodeParameter('estimateId', i), - SyncToken: syncToken, - sparse: true, - CustomerRef: { - name: ref.name, - value: ref.value, - }, - } as IDataObject; + const customerId = this.getNodeParameter('customerId', i); + const endpoint = `/v3/company/${companyId}/${resource}/${customerId}`; + responseData = await quickBooksApiRequest.call(this, 'GET', endpoint, {}, {}); + responseData = responseData[capitalCase(resource)]; - const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + } else if (operation === 'getAll') { - if (isEmpty(updateFields)) { - throw new NodeOperationError(this.getNode(), `Please enter at least one field to update for the ${resource}.`); - } + // ---------------------------------- + // customer: getAll + // ---------------------------------- - body = populateFields.call(this, body, updateFields, resource); + const endpoint = `/v3/company/${companyId}/query`; + responseData = await handleListing.call(this, i, endpoint, resource); - const endpoint = `/v3/company/${companyId}/${resource}`; - responseData = await quickBooksApiRequest.call(this, 'POST', endpoint, {}, body); - responseData = responseData[capitalCase(resource)]; + } else if (operation === 'update') { - } + // ---------------------------------- + // customer: update + // ---------------------------------- - } else if (resource === 'invoice') { + let body = { + Id: this.getNodeParameter('customerId', i), + SyncToken: await getSyncToken.call(this, i, companyId, resource), + sparse: true, + } as IDataObject; - // ********************************************************************* - // invoice - // ********************************************************************* + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; - // https://developer.intuit.com/app/developer/qbo/docs/api/accounting/most-commonly-used/invoice - - if (operation === 'create') { - - // ---------------------------------- - // invoice: create - // ---------------------------------- - - const lines = this.getNodeParameter('Line', i) as IDataObject[]; - - if (!lines.length) { - throw new NodeOperationError(this.getNode(), `Please enter at least one line for the ${resource}.`); - } - - if (lines.some(line => line.DetailType === undefined || line.Amount === undefined || line.Description === undefined)) { - throw new NodeOperationError(this.getNode(), 'Please enter detail type, amount and description for every line.'); - } - - lines.forEach(line => { - if (line.DetailType === 'SalesItemLineDetail' && line.itemId === undefined) { - throw new NodeOperationError(this.getNode(), 'Please enter an item ID for the associated line.'); + if (isEmpty(updateFields)) { + throw new NodeOperationError(this.getNode(), `Please enter at least one field to update for the ${resource}.`); } - }); - let body = { - CustomerRef: { - value: this.getNodeParameter('CustomerRef', i), - }, - } as IDataObject; + body = populateFields.call(this, body, updateFields, resource); - body.Line = processLines.call(this, body, lines, resource); - - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - - body = populateFields.call(this, body, additionalFields, resource); - - const endpoint = `/v3/company/${companyId}/${resource}`; - responseData = await quickBooksApiRequest.call(this, 'POST', endpoint, {}, body); - responseData = responseData[capitalCase(resource)]; - - } else if (operation === 'delete') { - - // ---------------------------------- - // invoice: delete - // ---------------------------------- - - const qs = { - operation: 'delete', - } as IDataObject; - - const body = { - Id: this.getNodeParameter('invoiceId', i), - SyncToken: await getSyncToken.call(this, i, companyId, resource), - } as IDataObject; - - const endpoint = `/v3/company/${companyId}/${resource}`; - responseData = await quickBooksApiRequest.call(this, 'POST', endpoint, qs, body); - responseData = responseData[capitalCase(resource)]; - - } else if (operation === 'get') { - - // ---------------------------------- - // invoice: get - // ---------------------------------- - - const invoiceId = this.getNodeParameter('invoiceId', i) as string; - const download = this.getNodeParameter('download', i) as boolean; - - if (download) { - - responseData = await handleBinaryData.call(this, items, i, companyId, resource, invoiceId); - - } else { - - const endpoint = `/v3/company/${companyId}/${resource}/${invoiceId}`; - responseData = await quickBooksApiRequest.call(this, 'GET', endpoint, {}, {}); + const endpoint = `/v3/company/${companyId}/${resource}`; + responseData = await quickBooksApiRequest.call(this, 'POST', endpoint, {}, body); responseData = responseData[capitalCase(resource)]; } - } else if (operation === 'getAll') { + } else if (resource === 'employee') { - // ---------------------------------- - // invoice: getAll - // ---------------------------------- + // ********************************************************************* + // employee + // ********************************************************************* - const endpoint = `/v3/company/${companyId}/query`; - responseData = await handleListing.call(this, i, endpoint, resource); + if (operation === 'create') { - } else if (operation === 'send') { + // ---------------------------------- + // employee: create + // ---------------------------------- - // ---------------------------------- - // invoice: send - // ---------------------------------- + let body = { + FamilyName: this.getNodeParameter('FamilyName', i), + GivenName: this.getNodeParameter('GivenName', i), + } as IDataObject; - const invoiceId = this.getNodeParameter('invoiceId', i) as string; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const qs = { - sendTo: this.getNodeParameter('email', i) as string, - } as IDataObject; + body = populateFields.call(this, body, additionalFields, resource); - const endpoint = `/v3/company/${companyId}/${resource}/${invoiceId}/send`; - responseData = await quickBooksApiRequest.call(this, 'POST', endpoint, qs, {}); - responseData = responseData[capitalCase(resource)]; + const endpoint = `/v3/company/${companyId}/${resource}`; + responseData = await quickBooksApiRequest.call(this, 'POST', endpoint, {}, body); + responseData = responseData[capitalCase(resource)]; - } else if (operation === 'update') { + } else if (operation === 'get') { - // ---------------------------------- - // invoice: update - // ---------------------------------- + // ---------------------------------- + // employee: get + // ---------------------------------- - const { ref, syncToken } = await getRefAndSyncToken.call(this, i, companyId, resource, 'CustomerRef'); - - let body = { - Id: this.getNodeParameter('invoiceId', i), - SyncToken: syncToken, - sparse: true, - CustomerRef: { - name: ref.name, - value: ref.value, - }, - } as IDataObject; - - const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; - - if (isEmpty(updateFields)) { - throw new NodeOperationError(this.getNode(), `Please enter at least one field to update for the ${resource}.`); - } - - body = populateFields.call(this, body, updateFields, resource); - - const endpoint = `/v3/company/${companyId}/${resource}`; - responseData = await quickBooksApiRequest.call(this, 'POST', endpoint, {}, body); - responseData = responseData[capitalCase(resource)]; - - } else if (operation === 'void') { - - // ---------------------------------- - // invoice: void - // ---------------------------------- - - const qs = { - Id: this.getNodeParameter('invoiceId', i), - SyncToken: await getSyncToken.call(this, i, companyId, resource), - operation: 'void', - } as IDataObject; - - const endpoint = `/v3/company/${companyId}/${resource}`; - responseData = await quickBooksApiRequest.call(this, 'POST', endpoint, qs, {}); - responseData = responseData[capitalCase(resource)]; - - } - - } else if (resource === 'item') { - - // ********************************************************************* - // item - // ********************************************************************* - - // https://developer.intuit.com/app/developer/qbo/docs/api/accounting/most-commonly-used/item - - if (operation === 'get') { - - // ---------------------------------- - // item: get - // ---------------------------------- - - const item = this.getNodeParameter('itemId', i); - const endpoint = `/v3/company/${companyId}/${resource}/${item}`; - responseData = await quickBooksApiRequest.call(this, 'GET', endpoint, {}, {}); - responseData = responseData[capitalCase(resource)]; - - } else if (operation === 'getAll') { - - // ---------------------------------- - // item: getAll - // ---------------------------------- - - const endpoint = `/v3/company/${companyId}/query`; - responseData = await handleListing.call(this, i, endpoint, resource); - - } - - } else if (resource === 'payment') { - - // ********************************************************************* - // payment - // ********************************************************************* - - // https://developer.intuit.com/app/developer/qbo/docs/api/accounting/most-commonly-used/payment - - if (operation === 'create') { - - // ---------------------------------- - // payment: create - // ---------------------------------- - - let body = { - CustomerRef: { - value: this.getNodeParameter('CustomerRef', i), - }, - TotalAmt: this.getNodeParameter('TotalAmt', i), - } as IDataObject; - - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - - body = populateFields.call(this, body, additionalFields, resource); - - const endpoint = `/v3/company/${companyId}/${resource}`; - responseData = await quickBooksApiRequest.call(this, 'POST', endpoint, {}, body); - responseData = responseData[capitalCase(resource)]; - - } else if (operation === 'delete') { - - // ---------------------------------- - // payment: delete - // ---------------------------------- - - const qs = { - operation: 'delete', - } as IDataObject; - - const body = { - Id: this.getNodeParameter('paymentId', i), - SyncToken: await getSyncToken.call(this, i, companyId, resource), - } as IDataObject; - - const endpoint = `/v3/company/${companyId}/${resource}`; - responseData = await quickBooksApiRequest.call(this, 'POST', endpoint, qs, body); - responseData = responseData[capitalCase(resource)]; - - } else if (operation === 'get') { - - // ---------------------------------- - // payment: get - // ---------------------------------- - - const paymentId = this.getNodeParameter('paymentId', i) as string; - const download = this.getNodeParameter('download', i) as boolean; - - if (download) { - - responseData = await handleBinaryData.call(this, items, i, companyId, resource, paymentId); - - } else { - - const endpoint = `/v3/company/${companyId}/${resource}/${paymentId}`; + const employeeId = this.getNodeParameter('employeeId', i); + const endpoint = `/v3/company/${companyId}/${resource}/${employeeId}`; responseData = await quickBooksApiRequest.call(this, 'GET', endpoint, {}, {}); responseData = responseData[capitalCase(resource)]; + } else if (operation === 'getAll') { + + // ---------------------------------- + // employee: getAll + // ---------------------------------- + + const endpoint = `/v3/company/${companyId}/query`; + responseData = await handleListing.call(this, i, endpoint, resource); + + } else if (operation === 'update') { + + // ---------------------------------- + // employee: update + // ---------------------------------- + + let body = { + Id: this.getNodeParameter('employeeId', i), + SyncToken: await getSyncToken.call(this, i, companyId, resource), + sparse: true, + } as IDataObject; + + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + + if (isEmpty(updateFields)) { + throw new NodeOperationError(this.getNode(), `Please enter at least one field to update for the ${resource}.`); + } + + body = populateFields.call(this, body, updateFields, resource); + + const endpoint = `/v3/company/${companyId}/${resource}`; + responseData = await quickBooksApiRequest.call(this, 'POST', endpoint, {}, body); + responseData = responseData[capitalCase(resource)]; + } - } else if (operation === 'getAll') { + } else if (resource === 'estimate') { - // ---------------------------------- - // payment: getAll - // ---------------------------------- + // ********************************************************************* + // estimate + // ********************************************************************* - const endpoint = `/v3/company/${companyId}/query`; - responseData = await handleListing.call(this, i, endpoint, resource); + // https://developer.intuit.com/app/developer/qbo/docs/api/accounting/most-commonly-used/estimate - } else if (operation === 'send') { + if (operation === 'create') { - // ---------------------------------- - // payment: send - // ---------------------------------- + // ---------------------------------- + // estimate: create + // ---------------------------------- - const paymentId = this.getNodeParameter('paymentId', i) as string; + const lines = this.getNodeParameter('Line', i) as IDataObject[]; - const qs = { - sendTo: this.getNodeParameter('email', i) as string, - } as IDataObject; + if (!lines.length) { + throw new NodeOperationError(this.getNode(), `Please enter at least one line for the ${resource}.`); + } - const endpoint = `/v3/company/${companyId}/${resource}/${paymentId}/send`; - responseData = await quickBooksApiRequest.call(this, 'POST', endpoint, qs, {}); - responseData = responseData[capitalCase(resource)]; + if (lines.some(line => line.DetailType === undefined || line.Amount === undefined || line.Description === undefined)) { + throw new NodeOperationError(this.getNode(), 'Please enter detail type, amount and description for every line.'); + } - } else if (operation === 'update') { + lines.forEach(line => { + if (line.DetailType === 'SalesItemLineDetail' && line.itemId === undefined) { + throw new NodeOperationError(this.getNode(), 'Please enter an item ID for the associated line.'); + } + }); - // ---------------------------------- - // payment: update - // ---------------------------------- + let body = { + CustomerRef: { + value: this.getNodeParameter('CustomerRef', i), + }, + } as IDataObject; - const { ref, syncToken } = await getRefAndSyncToken.call(this, i, companyId, resource, 'CustomerRef'); + body.Line = processLines.call(this, body, lines, resource); - let body = { - Id: this.getNodeParameter('paymentId', i), - SyncToken: syncToken, - sparse: true, - CustomerRef: { - name: ref.name, - value: ref.value, - }, - } as IDataObject; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + body = populateFields.call(this, body, additionalFields, resource); + + const endpoint = `/v3/company/${companyId}/${resource}`; + responseData = await quickBooksApiRequest.call(this, 'POST', endpoint, {}, body); + responseData = responseData[capitalCase(resource)]; + + } else if (operation === 'delete') { + + // ---------------------------------- + // estimate: delete + // ---------------------------------- + + const qs = { + operation: 'delete', + } as IDataObject; + + const body = { + Id: this.getNodeParameter('estimateId', i), + SyncToken: await getSyncToken.call(this, i, companyId, resource), + } as IDataObject; + + const endpoint = `/v3/company/${companyId}/${resource}`; + responseData = await quickBooksApiRequest.call(this, 'POST', endpoint, qs, body); + responseData = responseData[capitalCase(resource)]; + + } else if (operation === 'get') { + + // ---------------------------------- + // estimate: get + // ---------------------------------- + + const estimateId = this.getNodeParameter('estimateId', i) as string; + const download = this.getNodeParameter('download', i) as boolean; + + if (download) { + + responseData = await handleBinaryData.call(this, items, i, companyId, resource, estimateId); + + } else { + + const endpoint = `/v3/company/${companyId}/${resource}/${estimateId}`; + responseData = await quickBooksApiRequest.call(this, 'GET', endpoint, {}, {}); + responseData = responseData[capitalCase(resource)]; + + } + + } else if (operation === 'getAll') { + + // ---------------------------------- + // estimate: getAll + // ---------------------------------- + + const endpoint = `/v3/company/${companyId}/query`; + responseData = await handleListing.call(this, i, endpoint, resource); + + } else if (operation === 'send') { + + // ---------------------------------- + // estimate: send + // ---------------------------------- + + const estimateId = this.getNodeParameter('estimateId', i) as string; + + const qs = { + sendTo: this.getNodeParameter('email', i) as string, + } as IDataObject; + + const endpoint = `/v3/company/${companyId}/${resource}/${estimateId}/send`; + responseData = await quickBooksApiRequest.call(this, 'POST', endpoint, qs, {}); + responseData = responseData[capitalCase(resource)]; + + } else if (operation === 'update') { + + // ---------------------------------- + // estimate: update + // ---------------------------------- + + const { ref, syncToken } = await getRefAndSyncToken.call(this, i, companyId, resource, 'CustomerRef'); + + let body = { + Id: this.getNodeParameter('estimateId', i), + SyncToken: syncToken, + sparse: true, + CustomerRef: { + name: ref.name, + value: ref.value, + }, + } as IDataObject; + + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + + if (isEmpty(updateFields)) { + throw new NodeOperationError(this.getNode(), `Please enter at least one field to update for the ${resource}.`); + } + + body = populateFields.call(this, body, updateFields, resource); + + const endpoint = `/v3/company/${companyId}/${resource}`; + responseData = await quickBooksApiRequest.call(this, 'POST', endpoint, {}, body); + responseData = responseData[capitalCase(resource)]; - if (isEmpty(updateFields)) { - throw new NodeOperationError(this.getNode(), `Please enter at least one field to update for the ${resource}.`); } - body = populateFields.call(this, body, updateFields, resource); + } else if (resource === 'invoice') { - const endpoint = `/v3/company/${companyId}/${resource}`; - responseData = await quickBooksApiRequest.call(this, 'POST', endpoint, {}, body); - responseData = responseData[capitalCase(resource)]; + // ********************************************************************* + // invoice + // ********************************************************************* - } else if (operation === 'void') { + // https://developer.intuit.com/app/developer/qbo/docs/api/accounting/most-commonly-used/invoice - // ---------------------------------- - // payment: void - // ---------------------------------- + if (operation === 'create') { - const qs = { - Id: this.getNodeParameter('paymentId', i), - SyncToken: await getSyncToken.call(this, i, companyId, resource), - operation: 'void', - } as IDataObject; + // ---------------------------------- + // invoice: create + // ---------------------------------- - const endpoint = `/v3/company/${companyId}/${resource}`; - responseData = await quickBooksApiRequest.call(this, 'POST', endpoint, qs, {}); - responseData = responseData[capitalCase(resource)]; + const lines = this.getNodeParameter('Line', i) as IDataObject[]; - } + if (!lines.length) { + throw new NodeOperationError(this.getNode(), `Please enter at least one line for the ${resource}.`); + } - } else if (resource === 'purchase') { + if (lines.some(line => line.DetailType === undefined || line.Amount === undefined || line.Description === undefined)) { + throw new NodeOperationError(this.getNode(), 'Please enter detail type, amount and description for every line.'); + } - // ********************************************************************* - // purchase - // ********************************************************************* + lines.forEach(line => { + if (line.DetailType === 'SalesItemLineDetail' && line.itemId === undefined) { + throw new NodeOperationError(this.getNode(), 'Please enter an item ID for the associated line.'); + } + }); - // https://developer.intuit.com/app/developer/qbo/docs/api/accounting/all-entities/purchase + let body = { + CustomerRef: { + value: this.getNodeParameter('CustomerRef', i), + }, + } as IDataObject; - if (operation === 'get') { + body.Line = processLines.call(this, body, lines, resource); - // ---------------------------------- - // purchase: get - // ---------------------------------- + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const purchaseId = this.getNodeParameter('purchaseId', i); - const endpoint = `/v3/company/${companyId}/${resource}/${purchaseId}`; - responseData = await quickBooksApiRequest.call(this, 'GET', endpoint, {}, {}); - responseData = responseData[capitalCase(resource)]; + body = populateFields.call(this, body, additionalFields, resource); - } else if (operation === 'getAll') { + const endpoint = `/v3/company/${companyId}/${resource}`; + responseData = await quickBooksApiRequest.call(this, 'POST', endpoint, {}, body); + responseData = responseData[capitalCase(resource)]; - // ---------------------------------- - // purchase: getAll - // ---------------------------------- + } else if (operation === 'delete') { - const endpoint = `/v3/company/${companyId}/query`; - responseData = await handleListing.call(this, i, endpoint, resource); + // ---------------------------------- + // invoice: delete + // ---------------------------------- - } + const qs = { + operation: 'delete', + } as IDataObject; - } else if (resource === 'vendor') { + const body = { + Id: this.getNodeParameter('invoiceId', i), + SyncToken: await getSyncToken.call(this, i, companyId, resource), + } as IDataObject; - // ********************************************************************* - // vendor - // ********************************************************************* + const endpoint = `/v3/company/${companyId}/${resource}`; + responseData = await quickBooksApiRequest.call(this, 'POST', endpoint, qs, body); + responseData = responseData[capitalCase(resource)]; - // https://developer.intuit.com/app/developer/qbo/docs/api/accounting/most-commonly-used/vendor + } else if (operation === 'get') { - if (operation === 'create') { + // ---------------------------------- + // invoice: get + // ---------------------------------- - // ---------------------------------- - // vendor: create - // ---------------------------------- + const invoiceId = this.getNodeParameter('invoiceId', i) as string; + const download = this.getNodeParameter('download', i) as boolean; - let body = { - DisplayName: this.getNodeParameter('displayName', i), - } as IDataObject; + if (download) { - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + responseData = await handleBinaryData.call(this, items, i, companyId, resource, invoiceId); - body = populateFields.call(this, body, additionalFields, resource); + } else { - const endpoint = `/v3/company/${companyId}/${resource}`; - responseData = await quickBooksApiRequest.call(this, 'POST', endpoint, {}, body); - responseData = responseData[capitalCase(resource)]; + const endpoint = `/v3/company/${companyId}/${resource}/${invoiceId}`; + responseData = await quickBooksApiRequest.call(this, 'GET', endpoint, {}, {}); + responseData = responseData[capitalCase(resource)]; - } else if (operation === 'get') { + } - // ---------------------------------- - // vendor: get - // ---------------------------------- + } else if (operation === 'getAll') { - const vendorId = this.getNodeParameter('vendorId', i); - const endpoint = `/v3/company/${companyId}/${resource}/${vendorId}`; - responseData = await quickBooksApiRequest.call(this, 'GET', endpoint, {}, {}); - responseData = responseData[capitalCase(resource)]; + // ---------------------------------- + // invoice: getAll + // ---------------------------------- - } else if (operation === 'getAll') { + const endpoint = `/v3/company/${companyId}/query`; + responseData = await handleListing.call(this, i, endpoint, resource); - // ---------------------------------- - // vendor: getAll - // ---------------------------------- + } else if (operation === 'send') { - const endpoint = `/v3/company/${companyId}/query`; - responseData = await handleListing.call(this, i, endpoint, resource); + // ---------------------------------- + // invoice: send + // ---------------------------------- - } else if (operation === 'update') { + const invoiceId = this.getNodeParameter('invoiceId', i) as string; - // ---------------------------------- - // vendor: update - // ---------------------------------- + const qs = { + sendTo: this.getNodeParameter('email', i) as string, + } as IDataObject; - let body = { - Id: this.getNodeParameter('vendorId', i), - SyncToken: await getSyncToken.call(this, i, companyId, resource), - sparse: true, - } as IDataObject; + const endpoint = `/v3/company/${companyId}/${resource}/${invoiceId}/send`; + responseData = await quickBooksApiRequest.call(this, 'POST', endpoint, qs, {}); + responseData = responseData[capitalCase(resource)]; - const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + } else if (operation === 'update') { + + // ---------------------------------- + // invoice: update + // ---------------------------------- + + const { ref, syncToken } = await getRefAndSyncToken.call(this, i, companyId, resource, 'CustomerRef'); + + let body = { + Id: this.getNodeParameter('invoiceId', i), + SyncToken: syncToken, + sparse: true, + CustomerRef: { + name: ref.name, + value: ref.value, + }, + } as IDataObject; + + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + + if (isEmpty(updateFields)) { + throw new NodeOperationError(this.getNode(), `Please enter at least one field to update for the ${resource}.`); + } + + body = populateFields.call(this, body, updateFields, resource); + + const endpoint = `/v3/company/${companyId}/${resource}`; + responseData = await quickBooksApiRequest.call(this, 'POST', endpoint, {}, body); + responseData = responseData[capitalCase(resource)]; + + } else if (operation === 'void') { + + // ---------------------------------- + // invoice: void + // ---------------------------------- + + const qs = { + Id: this.getNodeParameter('invoiceId', i), + SyncToken: await getSyncToken.call(this, i, companyId, resource), + operation: 'void', + } as IDataObject; + + const endpoint = `/v3/company/${companyId}/${resource}`; + responseData = await quickBooksApiRequest.call(this, 'POST', endpoint, qs, {}); + responseData = responseData[capitalCase(resource)]; - if (isEmpty(updateFields)) { - throw new NodeOperationError(this.getNode(), `Please enter at least one field to update for the ${resource}.`); } - body = populateFields.call(this, body, updateFields, resource); + } else if (resource === 'item') { - const endpoint = `/v3/company/${companyId}/${resource}`; - responseData = await quickBooksApiRequest.call(this, 'POST', endpoint, {}, body); - responseData = responseData[capitalCase(resource)]; + // ********************************************************************* + // item + // ********************************************************************* + + // https://developer.intuit.com/app/developer/qbo/docs/api/accounting/most-commonly-used/item + + if (operation === 'get') { + + // ---------------------------------- + // item: get + // ---------------------------------- + + const item = this.getNodeParameter('itemId', i); + const endpoint = `/v3/company/${companyId}/${resource}/${item}`; + responseData = await quickBooksApiRequest.call(this, 'GET', endpoint, {}, {}); + responseData = responseData[capitalCase(resource)]; + + } else if (operation === 'getAll') { + + // ---------------------------------- + // item: getAll + // ---------------------------------- + + const endpoint = `/v3/company/${companyId}/query`; + responseData = await handleListing.call(this, i, endpoint, resource); + + } + + } else if (resource === 'payment') { + + // ********************************************************************* + // payment + // ********************************************************************* + + // https://developer.intuit.com/app/developer/qbo/docs/api/accounting/most-commonly-used/payment + + if (operation === 'create') { + + // ---------------------------------- + // payment: create + // ---------------------------------- + + let body = { + CustomerRef: { + value: this.getNodeParameter('CustomerRef', i), + }, + TotalAmt: this.getNodeParameter('TotalAmt', i), + } as IDataObject; + + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + + body = populateFields.call(this, body, additionalFields, resource); + + const endpoint = `/v3/company/${companyId}/${resource}`; + responseData = await quickBooksApiRequest.call(this, 'POST', endpoint, {}, body); + responseData = responseData[capitalCase(resource)]; + + } else if (operation === 'delete') { + + // ---------------------------------- + // payment: delete + // ---------------------------------- + + const qs = { + operation: 'delete', + } as IDataObject; + + const body = { + Id: this.getNodeParameter('paymentId', i), + SyncToken: await getSyncToken.call(this, i, companyId, resource), + } as IDataObject; + + const endpoint = `/v3/company/${companyId}/${resource}`; + responseData = await quickBooksApiRequest.call(this, 'POST', endpoint, qs, body); + responseData = responseData[capitalCase(resource)]; + + } else if (operation === 'get') { + + // ---------------------------------- + // payment: get + // ---------------------------------- + + const paymentId = this.getNodeParameter('paymentId', i) as string; + const download = this.getNodeParameter('download', i) as boolean; + + if (download) { + + responseData = await handleBinaryData.call(this, items, i, companyId, resource, paymentId); + + } else { + + const endpoint = `/v3/company/${companyId}/${resource}/${paymentId}`; + responseData = await quickBooksApiRequest.call(this, 'GET', endpoint, {}, {}); + responseData = responseData[capitalCase(resource)]; + + } + + } else if (operation === 'getAll') { + + // ---------------------------------- + // payment: getAll + // ---------------------------------- + + const endpoint = `/v3/company/${companyId}/query`; + responseData = await handleListing.call(this, i, endpoint, resource); + + } else if (operation === 'send') { + + // ---------------------------------- + // payment: send + // ---------------------------------- + + const paymentId = this.getNodeParameter('paymentId', i) as string; + + const qs = { + sendTo: this.getNodeParameter('email', i) as string, + } as IDataObject; + + const endpoint = `/v3/company/${companyId}/${resource}/${paymentId}/send`; + responseData = await quickBooksApiRequest.call(this, 'POST', endpoint, qs, {}); + responseData = responseData[capitalCase(resource)]; + + } else if (operation === 'update') { + + // ---------------------------------- + // payment: update + // ---------------------------------- + + const { ref, syncToken } = await getRefAndSyncToken.call(this, i, companyId, resource, 'CustomerRef'); + + let body = { + Id: this.getNodeParameter('paymentId', i), + SyncToken: syncToken, + sparse: true, + CustomerRef: { + name: ref.name, + value: ref.value, + }, + } as IDataObject; + + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + + if (isEmpty(updateFields)) { + throw new NodeOperationError(this.getNode(), `Please enter at least one field to update for the ${resource}.`); + } + + body = populateFields.call(this, body, updateFields, resource); + + const endpoint = `/v3/company/${companyId}/${resource}`; + responseData = await quickBooksApiRequest.call(this, 'POST', endpoint, {}, body); + responseData = responseData[capitalCase(resource)]; + + } else if (operation === 'void') { + + // ---------------------------------- + // payment: void + // ---------------------------------- + + const qs = { + Id: this.getNodeParameter('paymentId', i), + SyncToken: await getSyncToken.call(this, i, companyId, resource), + operation: 'void', + } as IDataObject; + + const endpoint = `/v3/company/${companyId}/${resource}`; + responseData = await quickBooksApiRequest.call(this, 'POST', endpoint, qs, {}); + responseData = responseData[capitalCase(resource)]; + + } + + } else if (resource === 'purchase') { + + // ********************************************************************* + // purchase + // ********************************************************************* + + // https://developer.intuit.com/app/developer/qbo/docs/api/accounting/all-entities/purchase + + if (operation === 'get') { + + // ---------------------------------- + // purchase: get + // ---------------------------------- + + const purchaseId = this.getNodeParameter('purchaseId', i); + const endpoint = `/v3/company/${companyId}/${resource}/${purchaseId}`; + responseData = await quickBooksApiRequest.call(this, 'GET', endpoint, {}, {}); + responseData = responseData[capitalCase(resource)]; + + } else if (operation === 'getAll') { + + // ---------------------------------- + // purchase: getAll + // ---------------------------------- + + const endpoint = `/v3/company/${companyId}/query`; + responseData = await handleListing.call(this, i, endpoint, resource); + + } + + } else if (resource === 'vendor') { + + // ********************************************************************* + // vendor + // ********************************************************************* + + // https://developer.intuit.com/app/developer/qbo/docs/api/accounting/most-commonly-used/vendor + + if (operation === 'create') { + + // ---------------------------------- + // vendor: create + // ---------------------------------- + + let body = { + DisplayName: this.getNodeParameter('displayName', i), + } as IDataObject; + + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + + body = populateFields.call(this, body, additionalFields, resource); + + const endpoint = `/v3/company/${companyId}/${resource}`; + responseData = await quickBooksApiRequest.call(this, 'POST', endpoint, {}, body); + responseData = responseData[capitalCase(resource)]; + + } else if (operation === 'get') { + + // ---------------------------------- + // vendor: get + // ---------------------------------- + + const vendorId = this.getNodeParameter('vendorId', i); + const endpoint = `/v3/company/${companyId}/${resource}/${vendorId}`; + responseData = await quickBooksApiRequest.call(this, 'GET', endpoint, {}, {}); + responseData = responseData[capitalCase(resource)]; + + } else if (operation === 'getAll') { + + // ---------------------------------- + // vendor: getAll + // ---------------------------------- + + const endpoint = `/v3/company/${companyId}/query`; + responseData = await handleListing.call(this, i, endpoint, resource); + + } else if (operation === 'update') { + + // ---------------------------------- + // vendor: update + // ---------------------------------- + + let body = { + Id: this.getNodeParameter('vendorId', i), + SyncToken: await getSyncToken.call(this, i, companyId, resource), + sparse: true, + } as IDataObject; + + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + + if (isEmpty(updateFields)) { + throw new NodeOperationError(this.getNode(), `Please enter at least one field to update for the ${resource}.`); + } + + body = populateFields.call(this, body, updateFields, resource); + + const endpoint = `/v3/company/${companyId}/${resource}`; + responseData = await quickBooksApiRequest.call(this, 'POST', endpoint, {}, body); + responseData = responseData[capitalCase(resource)]; + + } } - + } catch (error) { + if (this.continueOnFail()) { + const download = this.getNodeParameter('download', 0, false) as boolean; + if (['invoice', 'estimate', 'payment'].includes(resource) && ['get'].includes(operation) && download) { + // in this case responseDate? === items + if (!responseData){ + items[i].json = { error: error.message }; + responseData = items; + }else { + responseData[i].json = { error: error.message }; + } + }else { + returnData.push({ error: error.message }); + } + continue; + } + throw error; } Array.isArray(responseData) @@ -1036,3 +1054,4 @@ export class QuickBooks implements INodeType { } } } + diff --git a/packages/nodes-base/nodes/Raindrop/Raindrop.node.ts b/packages/nodes-base/nodes/Raindrop/Raindrop.node.ts index 084c22cf5d..036d3e8649 100644 --- a/packages/nodes-base/nodes/Raindrop/Raindrop.node.ts +++ b/packages/nodes-base/nodes/Raindrop/Raindrop.node.ts @@ -113,338 +113,346 @@ export class Raindrop implements INodeType { const returnData: IDataObject[] = []; for (let i = 0; i < items.length; i++) { - if (resource === 'bookmark') { + try { + if (resource === 'bookmark') { - // ********************************************************************* - // bookmark - // ********************************************************************* + // ********************************************************************* + // bookmark + // ********************************************************************* - // https://developer.raindrop.io/v1/raindrops + // https://developer.raindrop.io/v1/raindrops - if (operation === 'create') { + if (operation === 'create') { - // ---------------------------------- - // bookmark: create - // ---------------------------------- + // ---------------------------------- + // bookmark: create + // ---------------------------------- - const body: IDataObject = { - link: this.getNodeParameter('link', i), - collection: { - '$id': this.getNodeParameter('collectionId', i), - }, - }; - - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - - if (!isEmpty(additionalFields)) { - Object.assign(body, additionalFields); - } - - if (additionalFields.pleaseParse === true) { - body.pleaseParse = {}; - delete additionalFields.pleaseParse; - } - - if (additionalFields.tags) { - body.tags = (additionalFields.tags as string).split(',').map(tag => tag.trim()) as string[]; - } - - const endpoint = `/raindrop`; - responseData = await raindropApiRequest.call(this, 'POST', endpoint, {}, body); - responseData = responseData.item; - - } else if (operation === 'delete') { - - // ---------------------------------- - // bookmark: delete - // ---------------------------------- - - const bookmarkId = this.getNodeParameter('bookmarkId', i); - const endpoint = `/raindrop/${bookmarkId}`; - responseData = await raindropApiRequest.call(this, 'DELETE', endpoint, {}, {}); - - } else if (operation === 'get') { - - // ---------------------------------- - // bookmark: get - // ---------------------------------- - - const bookmarkId = this.getNodeParameter('bookmarkId', i); - const endpoint = `/raindrop/${bookmarkId}`; - responseData = await raindropApiRequest.call(this, 'GET', endpoint, {}, {}); - responseData = responseData.item; - - } else if (operation === 'getAll') { - - // ---------------------------------- - // bookmark: getAll - // ---------------------------------- - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - - const collectionId = this.getNodeParameter('collectionId', i); - const endpoint = `/raindrops/${collectionId}`; - responseData = await raindropApiRequest.call(this, 'GET', endpoint, {}, {}); - responseData = responseData.items; - - - if (returnAll === false) { - const limit = this.getNodeParameter('limit', 0) as number; - responseData = responseData.slice(0, limit); - } - - } else if (operation === 'update') { - - // ---------------------------------- - // bookmark: update - // ---------------------------------- - - const bookmarkId = this.getNodeParameter('bookmarkId', i); - - const body = {} as IDataObject; - - const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; - - if (isEmpty(updateFields)) { - throw new NodeOperationError(this.getNode(), `Please enter at least one field to update for the ${resource}.`); - } - - Object.assign(body, updateFields); - - if (updateFields.collectionId) { - body.collection = { - '$id': updateFields.collectionId, - }; - delete updateFields.collectionId; - } - - if (updateFields.tags) { - body.tags = (updateFields.tags as string).split(',').map(tag => tag.trim()) as string[]; - } - - const endpoint = `/raindrop/${bookmarkId}`; - responseData = await raindropApiRequest.call(this, 'PUT', endpoint, {}, body); - responseData = responseData.item; - } - } else if (resource === 'collection') { - - // ********************************************************************* - // collection - // ********************************************************************* - - // https://developer.raindrop.io/v1/collections/methods - - if (operation === 'create') { - - // ---------------------------------- - // collection: create - // ---------------------------------- - - const body = { - title: this.getNodeParameter('title', i), - } as IDataObject; - - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - - if (!isEmpty(additionalFields)) { - Object.assign(body, additionalFields); - } - - if (additionalFields.cover) { - body.cover = [body.cover]; - } - - if (additionalFields.parentId) { - body['parent.$id'] = parseInt(additionalFields.parentId as string, 10) as number; - delete additionalFields.parentId; - } - - responseData = await raindropApiRequest.call(this, 'POST', `/collection`, {}, body); - responseData = responseData.item; - - } else if (operation === 'delete') { - - // ---------------------------------- - // collection: delete - // ---------------------------------- - - const collectionId = this.getNodeParameter('collectionId', i); - const endpoint = `/collection/${collectionId}`; - responseData = await raindropApiRequest.call(this, 'DELETE', endpoint, {}, {}); - - } else if (operation === 'get') { - - // ---------------------------------- - // collection: get - // ---------------------------------- - - const collectionId = this.getNodeParameter('collectionId', i); - const endpoint = `/collection/${collectionId}`; - responseData = await raindropApiRequest.call(this, 'GET', endpoint, {}, {}); - responseData = responseData.item; - - } else if (operation === 'getAll') { - - // ---------------------------------- - // collection: getAll - // ---------------------------------- - - const returnAll = this.getNodeParameter('returnAll', 0) as boolean; - - const endpoint = this.getNodeParameter('type', i) === 'parent' - ? '/collections' - : '/collections/childrens'; - - responseData = await raindropApiRequest.call(this, 'GET', endpoint, {}, {}); - responseData = responseData.items; - - if (returnAll === false) { - const limit = this.getNodeParameter('limit', 0) as number; - responseData = responseData.slice(0, limit); - } - - } else if (operation === 'update') { - - // ---------------------------------- - // collection: update - // ---------------------------------- - - const collectionId = this.getNodeParameter('collectionId', i); - - const body = {} as IDataObject; - - const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; - - if (isEmpty(updateFields)) { - throw new NodeOperationError(this.getNode(), `Please enter at least one field to update for the ${resource}.`); - } - - if (updateFields.parentId) { - body['parent.$id'] = parseInt(updateFields.parentId as string, 10) as number; - delete updateFields.parentId; - } - - Object.assign(body, omit(updateFields, 'binaryPropertyName')); - - const endpoint = `/collection/${collectionId}`; - responseData = await raindropApiRequest.call(this, 'PUT', endpoint, {}, body); - responseData = responseData.item; - - // cover-specific endpoint - - if (updateFields.cover) { - - if (!items[i].binary) { - throw new NodeOperationError(this.getNode(), 'No binary data exists on item!'); - } - - if (!updateFields.cover) { - throw new NodeOperationError(this.getNode(), 'Please enter a binary property to upload a cover image.'); - } - - const binaryPropertyName = updateFields.cover as string; - - const binaryData = items[i].binary![binaryPropertyName] as IBinaryData; - - const formData = { - cover: { - value: Buffer.from(binaryData.data, BINARY_ENCODING), - options: { - filename: binaryData.fileName, - contentType: binaryData.mimeType, - }, + const body: IDataObject = { + link: this.getNodeParameter('link', i), + collection: { + '$id': this.getNodeParameter('collectionId', i), }, }; - const endpoint = `/collection/${collectionId}/cover`; - responseData = await raindropApiRequest.call(this, 'PUT', endpoint, {}, {}, { 'Content-Type': 'multipart/form-data', formData }); + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + + if (!isEmpty(additionalFields)) { + Object.assign(body, additionalFields); + } + + if (additionalFields.pleaseParse === true) { + body.pleaseParse = {}; + delete additionalFields.pleaseParse; + } + + if (additionalFields.tags) { + body.tags = (additionalFields.tags as string).split(',').map(tag => tag.trim()) as string[]; + } + + const endpoint = `/raindrop`; + responseData = await raindropApiRequest.call(this, 'POST', endpoint, {}, body); + responseData = responseData.item; + + } else if (operation === 'delete') { + + // ---------------------------------- + // bookmark: delete + // ---------------------------------- + + const bookmarkId = this.getNodeParameter('bookmarkId', i); + const endpoint = `/raindrop/${bookmarkId}`; + responseData = await raindropApiRequest.call(this, 'DELETE', endpoint, {}, {}); + + } else if (operation === 'get') { + + // ---------------------------------- + // bookmark: get + // ---------------------------------- + + const bookmarkId = this.getNodeParameter('bookmarkId', i); + const endpoint = `/raindrop/${bookmarkId}`; + responseData = await raindropApiRequest.call(this, 'GET', endpoint, {}, {}); + responseData = responseData.item; + + } else if (operation === 'getAll') { + + // ---------------------------------- + // bookmark: getAll + // ---------------------------------- + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + + const collectionId = this.getNodeParameter('collectionId', i); + const endpoint = `/raindrops/${collectionId}`; + responseData = await raindropApiRequest.call(this, 'GET', endpoint, {}, {}); + responseData = responseData.items; + + + if (returnAll === false) { + const limit = this.getNodeParameter('limit', 0) as number; + responseData = responseData.slice(0, limit); + } + + } else if (operation === 'update') { + + // ---------------------------------- + // bookmark: update + // ---------------------------------- + + const bookmarkId = this.getNodeParameter('bookmarkId', i); + + const body = {} as IDataObject; + + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + + if (isEmpty(updateFields)) { + throw new NodeOperationError(this.getNode(), `Please enter at least one field to update for the ${resource}.`); + } + + Object.assign(body, updateFields); + + if (updateFields.collectionId) { + body.collection = { + '$id': updateFields.collectionId, + }; + delete updateFields.collectionId; + } + + if (updateFields.tags) { + body.tags = (updateFields.tags as string).split(',').map(tag => tag.trim()) as string[]; + } + + const endpoint = `/raindrop/${bookmarkId}`; + responseData = await raindropApiRequest.call(this, 'PUT', endpoint, {}, body); responseData = responseData.item; } - } + } else if (resource === 'collection') { - } else if (resource === 'user') { + // ********************************************************************* + // collection + // ********************************************************************* - // ********************************************************************* - // user - // ********************************************************************* + // https://developer.raindrop.io/v1/collections/methods - // https://developer.raindrop.io/v1/user + if (operation === 'create') { - if (operation === 'get') { + // ---------------------------------- + // collection: create + // ---------------------------------- - // ---------------------------------- - // user: get - // ---------------------------------- + const body = { + title: this.getNodeParameter('title', i), + } as IDataObject; - const self = this.getNodeParameter('self', i); - let endpoint = '/user'; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - if (self === false) { - const userId = this.getNodeParameter('userId', i); - endpoint += `/${userId}`; + if (!isEmpty(additionalFields)) { + Object.assign(body, additionalFields); + } + + if (additionalFields.cover) { + body.cover = [body.cover]; + } + + if (additionalFields.parentId) { + body['parent.$id'] = parseInt(additionalFields.parentId as string, 10) as number; + delete additionalFields.parentId; + } + + responseData = await raindropApiRequest.call(this, 'POST', `/collection`, {}, body); + responseData = responseData.item; + + } else if (operation === 'delete') { + + // ---------------------------------- + // collection: delete + // ---------------------------------- + + const collectionId = this.getNodeParameter('collectionId', i); + const endpoint = `/collection/${collectionId}`; + responseData = await raindropApiRequest.call(this, 'DELETE', endpoint, {}, {}); + + } else if (operation === 'get') { + + // ---------------------------------- + // collection: get + // ---------------------------------- + + const collectionId = this.getNodeParameter('collectionId', i); + const endpoint = `/collection/${collectionId}`; + responseData = await raindropApiRequest.call(this, 'GET', endpoint, {}, {}); + responseData = responseData.item; + + } else if (operation === 'getAll') { + + // ---------------------------------- + // collection: getAll + // ---------------------------------- + + const returnAll = this.getNodeParameter('returnAll', 0) as boolean; + + const endpoint = this.getNodeParameter('type', i) === 'parent' + ? '/collections' + : '/collections/childrens'; + + responseData = await raindropApiRequest.call(this, 'GET', endpoint, {}, {}); + responseData = responseData.items; + + if (returnAll === false) { + const limit = this.getNodeParameter('limit', 0) as number; + responseData = responseData.slice(0, limit); + } + + } else if (operation === 'update') { + + // ---------------------------------- + // collection: update + // ---------------------------------- + + const collectionId = this.getNodeParameter('collectionId', i); + + const body = {} as IDataObject; + + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + + if (isEmpty(updateFields)) { + throw new NodeOperationError(this.getNode(), `Please enter at least one field to update for the ${resource}.`); + } + + if (updateFields.parentId) { + body['parent.$id'] = parseInt(updateFields.parentId as string, 10) as number; + delete updateFields.parentId; + } + + Object.assign(body, omit(updateFields, 'binaryPropertyName')); + + const endpoint = `/collection/${collectionId}`; + responseData = await raindropApiRequest.call(this, 'PUT', endpoint, {}, body); + responseData = responseData.item; + + // cover-specific endpoint + + if (updateFields.cover) { + + if (!items[i].binary) { + throw new NodeOperationError(this.getNode(), 'No binary data exists on item!'); + } + + if (!updateFields.cover) { + throw new NodeOperationError(this.getNode(), 'Please enter a binary property to upload a cover image.'); + } + + const binaryPropertyName = updateFields.cover as string; + + const binaryData = items[i].binary![binaryPropertyName] as IBinaryData; + + const formData = { + cover: { + value: Buffer.from(binaryData.data, BINARY_ENCODING), + options: { + filename: binaryData.fileName, + contentType: binaryData.mimeType, + }, + }, + }; + + const endpoint = `/collection/${collectionId}/cover`; + responseData = await raindropApiRequest.call(this, 'PUT', endpoint, {}, {}, { 'Content-Type': 'multipart/form-data', formData }); + responseData = responseData.item; + } } - responseData = await raindropApiRequest.call(this, 'GET', endpoint, {}, {}); - responseData = responseData.user; + } else if (resource === 'user') { - } + // ********************************************************************* + // user + // ********************************************************************* - } else if (resource === 'tag') { + // https://developer.raindrop.io/v1/user - // ********************************************************************* - // tag - // ********************************************************************* + if (operation === 'get') { - // https://developer.raindrop.io/v1/tags + // ---------------------------------- + // user: get + // ---------------------------------- - if (operation === 'delete') { + const self = this.getNodeParameter('self', i); + let endpoint = '/user'; - // ---------------------------------- - // tag: delete - // ---------------------------------- + if (self === false) { + const userId = this.getNodeParameter('userId', i); + endpoint += `/${userId}`; + } - let endpoint = `/tags`; + responseData = await raindropApiRequest.call(this, 'GET', endpoint, {}, {}); + responseData = responseData.user; - const body: IDataObject = { - tags: (this.getNodeParameter('tags', i) as string).split(',') as string[], - }; - - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - - if (additionalFields.collectionId) { - endpoint += `/${additionalFields.collectionId}`; } - responseData = await raindropApiRequest.call(this, 'DELETE', endpoint, {}, body); + } else if (resource === 'tag') { - } else if (operation === 'getAll') { + // ********************************************************************* + // tag + // ********************************************************************* - // ---------------------------------- - // tag: getAll - // ---------------------------------- + // https://developer.raindrop.io/v1/tags - let endpoint = `/tags`; + if (operation === 'delete') { - const returnAll = this.getNodeParameter('returnAll', i) as boolean; + // ---------------------------------- + // tag: delete + // ---------------------------------- - const filter = this.getNodeParameter('filters', i) as IDataObject; + let endpoint = `/tags`; - if (filter.collectionId) { - endpoint += `/${filter.collectionId}`; - } + const body: IDataObject = { + tags: (this.getNodeParameter('tags', i) as string).split(',') as string[], + }; - responseData = await raindropApiRequest.call(this, 'GET', endpoint, {}, {}); - responseData = responseData.items; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - if (returnAll === false) { - const limit = this.getNodeParameter('limit', 0) as number; - responseData = responseData.slice(0, limit); + if (additionalFields.collectionId) { + endpoint += `/${additionalFields.collectionId}`; + } + + responseData = await raindropApiRequest.call(this, 'DELETE', endpoint, {}, body); + + } else if (operation === 'getAll') { + + // ---------------------------------- + // tag: getAll + // ---------------------------------- + + let endpoint = `/tags`; + + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + + const filter = this.getNodeParameter('filters', i) as IDataObject; + + if (filter.collectionId) { + endpoint += `/${filter.collectionId}`; + } + + responseData = await raindropApiRequest.call(this, 'GET', endpoint, {}, {}); + responseData = responseData.items; + + if (returnAll === false) { + const limit = this.getNodeParameter('limit', 0) as number; + responseData = responseData.slice(0, limit); + } } } + + Array.isArray(responseData) + ? returnData.push(...responseData) + : returnData.push(responseData); + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } - - Array.isArray(responseData) - ? returnData.push(...responseData) - : returnData.push(responseData); } return [this.helpers.returnJsonArray(returnData)]; diff --git a/packages/nodes-base/nodes/ReadBinaryFile.node.ts b/packages/nodes-base/nodes/ReadBinaryFile.node.ts index fe5a3d8bce..e84f19a023 100644 --- a/packages/nodes-base/nodes/ReadBinaryFile.node.ts +++ b/packages/nodes-base/nodes/ReadBinaryFile.node.ts @@ -55,35 +55,46 @@ export class ReadBinaryFile implements INodeType { let item: INodeExecutionData; for (let itemIndex = 0; itemIndex < length; itemIndex++) { - item = items[itemIndex]; - const dataPropertyName = this.getNodeParameter('dataPropertyName', itemIndex) as string; - const filePath = this.getNodeParameter('filePath', itemIndex) as string; - let data; try { - data = await fsReadFile(filePath) as Buffer; - } catch (error) { - if (error.code === 'ENOENT') { - throw new NodeOperationError(this.getNode(), `The file "${filePath}" could not be found.`); + + item = items[itemIndex]; + const dataPropertyName = this.getNodeParameter('dataPropertyName', itemIndex) as string; + const filePath = this.getNodeParameter('filePath', itemIndex) as string; + + let data; + try { + data = await fsReadFile(filePath) as Buffer; + } catch (error) { + if (error.code === 'ENOENT') { + throw new NodeOperationError(this.getNode(), `The file "${filePath}" could not be found.`); + } + + throw error; } + const newItem: INodeExecutionData = { + json: item.json, + binary: {}, + }; + + if (item.binary !== undefined) { + // Create a shallow copy of the binary data so that the old + // data references which do not get changed still stay behind + // but the incoming data does not get changed. + Object.assign(newItem.binary, item.binary); + } + + newItem.binary![dataPropertyName] = await this.helpers.prepareBinaryData(data, filePath); + returnData.push(newItem); + + } catch (error) { + if (this.continueOnFail()) { + returnData.push({json:{ error: error.message }}); + continue; + } throw error; } - - const newItem: INodeExecutionData = { - json: item.json, - binary: {}, - }; - - if (item.binary !== undefined) { - // Create a shallow copy of the binary data so that the old - // data references which do not get changed still stay behind - // but the incoming data does not get changed. - Object.assign(newItem.binary, item.binary); - } - - newItem.binary![dataPropertyName] = await this.helpers.prepareBinaryData(data, filePath); - returnData.push(newItem); } return this.prepareOutputData(returnData); diff --git a/packages/nodes-base/nodes/ReadPdf.node.ts b/packages/nodes-base/nodes/ReadPdf.node.ts index 953f912c42..c4e1ee0972 100644 --- a/packages/nodes-base/nodes/ReadPdf.node.ts +++ b/packages/nodes-base/nodes/ReadPdf.node.ts @@ -46,19 +46,28 @@ export class ReadPdf implements INodeType { for (let itemIndex = 0; itemIndex < length; itemIndex++) { - item = items[itemIndex]; - const binaryPropertyName = this.getNodeParameter('binaryPropertyName', itemIndex) as string; + try{ - if (item.binary === undefined) { - item.binary = {}; + item = items[itemIndex]; + const binaryPropertyName = this.getNodeParameter('binaryPropertyName', itemIndex) as string; + + if (item.binary === undefined) { + item.binary = {}; + } + + const binaryData = Buffer.from(item.binary[binaryPropertyName].data, BINARY_ENCODING); + returnData.push({ + binary: item.binary, + json: await pdf(binaryData), + }); + + } catch (error) { + if (this.continueOnFail()) { + returnData.push({json:{ error: error.message }}); + continue; + } + throw error; } - - const binaryData = Buffer.from(item.binary[binaryPropertyName].data, BINARY_ENCODING); - returnData.push({ - binary: item.binary, - json: await pdf(binaryData), - }); - } return this.prepareOutputData(returnData); } diff --git a/packages/nodes-base/nodes/Reddit/Reddit.node.ts b/packages/nodes-base/nodes/Reddit/Reddit.node.ts index 2d5257bf33..922f8ddec6 100644 --- a/packages/nodes-base/nodes/Reddit/Reddit.node.ts +++ b/packages/nodes-base/nodes/Reddit/Reddit.node.ts @@ -123,354 +123,361 @@ export class Reddit implements INodeType { const returnData: IDataObject[] = []; for (let i = 0; i < items.length; i++) { + try { + // ********************************************************************* + // post + // ********************************************************************* - // ********************************************************************* - // post - // ********************************************************************* + if (resource === 'post') { - if (resource === 'post') { + if (operation === 'create') { - if (operation === 'create') { + // ---------------------------------- + // post: create + // ---------------------------------- - // ---------------------------------- - // post: create - // ---------------------------------- + // https://www.reddit.com/dev/api/#POST_api_submit - // https://www.reddit.com/dev/api/#POST_api_submit + const qs: IDataObject = { + title: this.getNodeParameter('title', i), + sr: this.getNodeParameter('subreddit', i), + kind: this.getNodeParameter('kind', i), + }; - const qs: IDataObject = { - title: this.getNodeParameter('title', i), - sr: this.getNodeParameter('subreddit', i), - kind: this.getNodeParameter('kind', i), - }; + qs.kind === 'self' + ? qs.text = this.getNodeParameter('text', i) + : qs.url = this.getNodeParameter('url', i); - qs.kind === 'self' - ? qs.text = this.getNodeParameter('text', i) - : qs.url = this.getNodeParameter('url', i); + if (qs.url) { + qs.resubmit = this.getNodeParameter('resubmit', i); + } - if (qs.url) { - qs.resubmit = this.getNodeParameter('resubmit', i); - } + responseData = await redditApiRequest.call(this, 'POST', 'api/submit', qs); - responseData = await redditApiRequest.call(this, 'POST', 'api/submit', qs); + responseData = responseData.json.data; - responseData = responseData.json.data; + } else if (operation === 'delete') { - } else if (operation === 'delete') { + // ---------------------------------- + // post: delete + // ---------------------------------- - // ---------------------------------- - // post: delete - // ---------------------------------- + // https://www.reddit.com/dev/api/#POST_api_del - // https://www.reddit.com/dev/api/#POST_api_del + const postTypePrefix = 't3_'; - const postTypePrefix = 't3_'; + const qs: IDataObject = { + id: postTypePrefix + this.getNodeParameter('postId', i), + }; - const qs: IDataObject = { - id: postTypePrefix + this.getNodeParameter('postId', i), - }; + await redditApiRequest.call(this, 'POST', 'api/del', qs); - await redditApiRequest.call(this, 'POST', 'api/del', qs); + responseData = { success: true }; - responseData = { success: true }; + } else if (operation === 'get') { - } else if (operation === 'get') { + // ---------------------------------- + // post: get + // ---------------------------------- - // ---------------------------------- - // post: get - // ---------------------------------- - - const subreddit = this.getNodeParameter('subreddit', i); - const postId = this.getNodeParameter('postId', i) as string; - const endpoint = `r/${subreddit}/comments/${postId}.json`; - - responseData = await redditApiRequest.call(this, 'GET', endpoint, {}); - responseData = responseData[0].data.children[0].data; - - } else if (operation === 'getAll') { - - // ---------------------------------- - // post: getAll - // ---------------------------------- - - // https://www.reddit.com/dev/api/#GET_hot - // https://www.reddit.com/dev/api/#GET_new - // https://www.reddit.com/dev/api/#GET_rising - // https://www.reddit.com/dev/api/#GET_{sort} - - const subreddit = this.getNodeParameter('subreddit', i); - let endpoint = `r/${subreddit}.json`; - - const { category } = this.getNodeParameter('filters', i) as { category: string }; - if (category) { - endpoint = `r/${subreddit}/${category}.json`; - } - - responseData = await handleListing.call(this, i, endpoint); - - } else if (operation === 'search') { - - // ---------------------------------- - // post: search - // ---------------------------------- - - // https://www.reddit.com/dev/api/#GET_search - - const location = this.getNodeParameter('location', i); - - const qs = { - q: this.getNodeParameter('keyword', i), - restrict_sr: location === 'subreddit', - } as IDataObject; - - const { sort } = this.getNodeParameter('additionalFields', i) as IDataObject; - - if (sort) { - qs.sort = sort; - } - - let endpoint = ''; - - if (location === 'allReddit') { - endpoint = 'search.json'; - } else { const subreddit = this.getNodeParameter('subreddit', i); - endpoint = `r/${subreddit}/search.json`; - } + const postId = this.getNodeParameter('postId', i) as string; + const endpoint = `r/${subreddit}/comments/${postId}.json`; - responseData = await handleListing.call(this, i, endpoint, qs); - - const returnAll = this.getNodeParameter('returnAll', 0) as boolean; - - if (!returnAll) { - const limit = this.getNodeParameter('limit', 0) as number; - responseData = responseData.splice(0, limit); - } - - } - - } else if (resource === 'postComment') { - - // ********************************************************************* - // postComment - // ********************************************************************* - - if (operation === 'create') { - - // ---------------------------------- - // postComment: create - // ---------------------------------- - - // https://www.reddit.com/dev/api/#POST_api_comment - - const postTypePrefix = 't3_'; - - const qs: IDataObject = { - text: this.getNodeParameter('commentText', i), - thing_id: postTypePrefix + this.getNodeParameter('postId', i), - }; - - responseData = await redditApiRequest.call(this, 'POST', 'api/comment', qs); - responseData = responseData.json.data.things[0].data; - - } else if (operation === 'getAll') { - - // ---------------------------------- - // postComment: getAll - // ---------------------------------- - - // https://www.reddit.com/r/{subrreddit}/comments/{postId}.json - - const subreddit = this.getNodeParameter('subreddit', i); - const postId = this.getNodeParameter('postId', i) as string; - const endpoint = `r/${subreddit}/comments/${postId}.json`; - - responseData = await handleListing.call(this, i, endpoint); - - } else if (operation === 'delete') { - - // ---------------------------------- - // postComment: delete - // ---------------------------------- - - // https://www.reddit.com/dev/api/#POST_api_del - - const commentTypePrefix = 't1_'; - - const qs: IDataObject = { - id: commentTypePrefix + this.getNodeParameter('commentId', i), - }; - - await redditApiRequest.call(this, 'POST', 'api/del', qs); - - responseData = { success: true }; - - } else if (operation === 'reply') { - - // ---------------------------------- - // postComment: reply - // ---------------------------------- - - // https://www.reddit.com/dev/api/#POST_api_comment - - const commentTypePrefix = 't1_'; - - const qs: IDataObject = { - text: this.getNodeParameter('replyText', i), - thing_id: commentTypePrefix + this.getNodeParameter('commentId', i), - }; - - responseData = await redditApiRequest.call(this, 'POST', 'api/comment', qs); - responseData = responseData.json.data.things[0].data; - } - - } else if (resource === 'profile') { - - // ********************************************************************* - // profile - // ********************************************************************* - - if (operation === 'get') { - - // ---------------------------------- - // profile: get - // ---------------------------------- - - // https://www.reddit.com/dev/api/#GET_api_v1_me - // https://www.reddit.com/dev/api/#GET_api_v1_me_karma - // https://www.reddit.com/dev/api/#GET_api_v1_me_prefs - // https://www.reddit.com/dev/api/#GET_api_v1_me_trophies - // https://www.reddit.com/dev/api/#GET_prefs_{where} - - const endpoints: { [key: string]: string } = { - identity: 'me', - blockedUsers: 'me/blocked', - friends: 'me/friends', - karma: 'me/karma', - prefs: 'me/prefs', - trophies: 'me/trophies', - }; - - const details = this.getNodeParameter('details', i) as string; - const endpoint = `api/v1/${endpoints[details]}`; - responseData = await redditApiRequest.call(this, 'GET', endpoint, {}); - - if (details === 'identity') { - responseData = responseData.features; - } else if (details === 'friends') { - responseData = responseData.data.children; - if (!responseData.length) { - throw new NodeApiError(this.getNode(), responseData); - } - } else if (details === 'karma') { - responseData = responseData.data; - if (!responseData.length) { - throw new NodeApiError(this.getNode(), responseData); - } - } else if (details === 'trophies') { - responseData = responseData.data.trophies.map((trophy: IDataObject) => trophy.data); - } - } - - } else if (resource === 'subreddit') { - - // ********************************************************************* - // subreddit - // ********************************************************************* - - if (operation === 'get') { - - // ---------------------------------- - // subreddit: get - // ---------------------------------- - - // https://www.reddit.com/dev/api/#GET_r_{subreddit}_about - // https://www.reddit.com/dev/api/#GET_r_{subreddit}_about_rules - - const subreddit = this.getNodeParameter('subreddit', i); - const content = this.getNodeParameter('content', i) as string; - const endpoint = `r/${subreddit}/about/${content}.json`; - - responseData = await redditApiRequest.call(this, 'GET', endpoint, {}); - - if (content === 'rules') { - responseData = responseData.rules; - } else if (content === 'about') { - responseData = responseData.data; - } - - } else if (operation === 'getAll') { - - // ---------------------------------- - // subreddit: getAll - // ---------------------------------- - - // https://www.reddit.com/dev/api/#GET_api_trending_subreddits - // https://www.reddit.com/dev/api/#POST_api_search_subreddits - // https://www.reddit.com/r/subreddits.json - - const filters = this.getNodeParameter('filters', i) as IDataObject; - - if (filters.trending) { - const returnAll = this.getNodeParameter('returnAll', 0) as boolean; - const endpoint = 'api/trending_subreddits.json'; responseData = await redditApiRequest.call(this, 'GET', endpoint, {}); - responseData = responseData.subreddit_names.map((name: string) => ({ name })); - if (returnAll === false) { + responseData = responseData[0].data.children[0].data; + + } else if (operation === 'getAll') { + + // ---------------------------------- + // post: getAll + // ---------------------------------- + + // https://www.reddit.com/dev/api/#GET_hot + // https://www.reddit.com/dev/api/#GET_new + // https://www.reddit.com/dev/api/#GET_rising + // https://www.reddit.com/dev/api/#GET_{sort} + + const subreddit = this.getNodeParameter('subreddit', i); + let endpoint = `r/${subreddit}.json`; + + const { category } = this.getNodeParameter('filters', i) as { category: string }; + if (category) { + endpoint = `r/${subreddit}/${category}.json`; + } + + responseData = await handleListing.call(this, i, endpoint); + + } else if (operation === 'search') { + + // ---------------------------------- + // post: search + // ---------------------------------- + + // https://www.reddit.com/dev/api/#GET_search + + const location = this.getNodeParameter('location', i); + + const qs = { + q: this.getNodeParameter('keyword', i), + restrict_sr: location === 'subreddit', + } as IDataObject; + + const { sort } = this.getNodeParameter('additionalFields', i) as IDataObject; + + if (sort) { + qs.sort = sort; + } + + let endpoint = ''; + + if (location === 'allReddit') { + endpoint = 'search.json'; + } else { + const subreddit = this.getNodeParameter('subreddit', i); + endpoint = `r/${subreddit}/search.json`; + } + + responseData = await handleListing.call(this, i, endpoint, qs); + + const returnAll = this.getNodeParameter('returnAll', 0) as boolean; + + if (!returnAll) { const limit = this.getNodeParameter('limit', 0) as number; responseData = responseData.splice(0, limit); } - } else if (filters.keyword) { - const qs: IDataObject = {}; - qs.query = filters.keyword; + } - const endpoint = 'api/search_subreddits.json'; - responseData = await redditApiRequest.call(this, 'POST', endpoint, qs); + } else if (resource === 'postComment') { - const returnAll = this.getNodeParameter('returnAll', 0) as boolean; + // ********************************************************************* + // postComment + // ********************************************************************* + + if (operation === 'create') { + + // ---------------------------------- + // postComment: create + // ---------------------------------- + + // https://www.reddit.com/dev/api/#POST_api_comment + + const postTypePrefix = 't3_'; + + const qs: IDataObject = { + text: this.getNodeParameter('commentText', i), + thing_id: postTypePrefix + this.getNodeParameter('postId', i), + }; + + responseData = await redditApiRequest.call(this, 'POST', 'api/comment', qs); + responseData = responseData.json.data.things[0].data; + + } else if (operation === 'getAll') { + + // ---------------------------------- + // postComment: getAll + // ---------------------------------- + + // https://www.reddit.com/r/{subrreddit}/comments/{postId}.json + + const subreddit = this.getNodeParameter('subreddit', i); + const postId = this.getNodeParameter('postId', i) as string; + const endpoint = `r/${subreddit}/comments/${postId}.json`; - if (returnAll === false) { - const limit = this.getNodeParameter('limit', 0) as number; - responseData = responseData.subreddits.splice(0, limit); - } - } else { - const endpoint = 'r/subreddits.json'; responseData = await handleListing.call(this, i, endpoint); + + } else if (operation === 'delete') { + + // ---------------------------------- + // postComment: delete + // ---------------------------------- + + // https://www.reddit.com/dev/api/#POST_api_del + + const commentTypePrefix = 't1_'; + + const qs: IDataObject = { + id: commentTypePrefix + this.getNodeParameter('commentId', i), + }; + + await redditApiRequest.call(this, 'POST', 'api/del', qs); + + responseData = { success: true }; + + } else if (operation === 'reply') { + + // ---------------------------------- + // postComment: reply + // ---------------------------------- + + // https://www.reddit.com/dev/api/#POST_api_comment + + const commentTypePrefix = 't1_'; + + const qs: IDataObject = { + text: this.getNodeParameter('replyText', i), + thing_id: commentTypePrefix + this.getNodeParameter('commentId', i), + }; + + responseData = await redditApiRequest.call(this, 'POST', 'api/comment', qs); + responseData = responseData.json.data.things[0].data; + } + + } else if (resource === 'profile') { + + // ********************************************************************* + // profile + // ********************************************************************* + + if (operation === 'get') { + + // ---------------------------------- + // profile: get + // ---------------------------------- + + // https://www.reddit.com/dev/api/#GET_api_v1_me + // https://www.reddit.com/dev/api/#GET_api_v1_me_karma + // https://www.reddit.com/dev/api/#GET_api_v1_me_prefs + // https://www.reddit.com/dev/api/#GET_api_v1_me_trophies + // https://www.reddit.com/dev/api/#GET_prefs_{where} + + const endpoints: { [key: string]: string } = { + identity: 'me', + blockedUsers: 'me/blocked', + friends: 'me/friends', + karma: 'me/karma', + prefs: 'me/prefs', + trophies: 'me/trophies', + }; + + const details = this.getNodeParameter('details', i) as string; + const endpoint = `api/v1/${endpoints[details]}`; + responseData = await redditApiRequest.call(this, 'GET', endpoint, {}); + + if (details === 'identity') { + responseData = responseData.features; + } else if (details === 'friends') { + responseData = responseData.data.children; + if (!responseData.length) { + throw new NodeApiError(this.getNode(), responseData); + } + } else if (details === 'karma') { + responseData = responseData.data; + if (!responseData.length) { + throw new NodeApiError(this.getNode(), responseData); + } + } else if (details === 'trophies') { + responseData = responseData.data.trophies.map((trophy: IDataObject) => trophy.data); + } + } + + } else if (resource === 'subreddit') { + + // ********************************************************************* + // subreddit + // ********************************************************************* + + if (operation === 'get') { + + // ---------------------------------- + // subreddit: get + // ---------------------------------- + + // https://www.reddit.com/dev/api/#GET_r_{subreddit}_about + // https://www.reddit.com/dev/api/#GET_r_{subreddit}_about_rules + + const subreddit = this.getNodeParameter('subreddit', i); + const content = this.getNodeParameter('content', i) as string; + const endpoint = `r/${subreddit}/about/${content}.json`; + + responseData = await redditApiRequest.call(this, 'GET', endpoint, {}); + + if (content === 'rules') { + responseData = responseData.rules; + } else if (content === 'about') { + responseData = responseData.data; + } + + } else if (operation === 'getAll') { + + // ---------------------------------- + // subreddit: getAll + // ---------------------------------- + + // https://www.reddit.com/dev/api/#GET_api_trending_subreddits + // https://www.reddit.com/dev/api/#POST_api_search_subreddits + // https://www.reddit.com/r/subreddits.json + + const filters = this.getNodeParameter('filters', i) as IDataObject; + + if (filters.trending) { + const returnAll = this.getNodeParameter('returnAll', 0) as boolean; + const endpoint = 'api/trending_subreddits.json'; + responseData = await redditApiRequest.call(this, 'GET', endpoint, {}); + responseData = responseData.subreddit_names.map((name: string) => ({ name })); + if (returnAll === false) { + const limit = this.getNodeParameter('limit', 0) as number; + responseData = responseData.splice(0, limit); + } + + } else if (filters.keyword) { + const qs: IDataObject = {}; + qs.query = filters.keyword; + + const endpoint = 'api/search_subreddits.json'; + responseData = await redditApiRequest.call(this, 'POST', endpoint, qs); + + const returnAll = this.getNodeParameter('returnAll', 0) as boolean; + + if (returnAll === false) { + const limit = this.getNodeParameter('limit', 0) as number; + responseData = responseData.subreddits.splice(0, limit); + } + } else { + const endpoint = 'r/subreddits.json'; + responseData = await handleListing.call(this, i, endpoint); + } + } + + } else if (resource === 'user') { + + // ********************************************************************* + // user + // ********************************************************************* + + if (operation === 'get') { + + // ---------------------------------- + // user: get + // ---------------------------------- + + // https://www.reddit.com/dev/api/#GET_user_{username}_{where} + + const username = this.getNodeParameter('username', i) as string; + const details = this.getNodeParameter('details', i) as string; + const endpoint = `user/${username}/${details}.json`; + + responseData = details === 'about' + ? await redditApiRequest.call(this, 'GET', endpoint, {}) + : await handleListing.call(this, i, endpoint); + + if (details === 'about') { + responseData = responseData.data; + } } } - } else if (resource === 'user') { - - // ********************************************************************* - // user - // ********************************************************************* - - if (operation === 'get') { - - // ---------------------------------- - // user: get - // ---------------------------------- - - // https://www.reddit.com/dev/api/#GET_user_{username}_{where} - - const username = this.getNodeParameter('username', i) as string; - const details = this.getNodeParameter('details', i) as string; - const endpoint = `user/${username}/${details}.json`; - - responseData = details === 'about' - ? await redditApiRequest.call(this, 'GET', endpoint, {}) - : await handleListing.call(this, i, endpoint); - - if (details === 'about') { - responseData = responseData.data; - } + Array.isArray(responseData) + ? returnData.push(...responseData) + : returnData.push(responseData); + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; } + throw error; } - - Array.isArray(responseData) - ? returnData.push(...responseData) - : returnData.push(responseData); } return [this.helpers.returnJsonArray(returnData)]; diff --git a/packages/nodes-base/nodes/Rocketchat/Rocketchat.node.ts b/packages/nodes-base/nodes/Rocketchat/Rocketchat.node.ts index f027fdc1db..a705c378ba 100644 --- a/packages/nodes-base/nodes/Rocketchat/Rocketchat.node.ts +++ b/packages/nodes-base/nodes/Rocketchat/Rocketchat.node.ts @@ -405,102 +405,110 @@ export class Rocketchat implements INodeType { 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 === 'chat') { - //https://rocket.chat/docs/developer-guides/rest-api/chat/postmessage - if (operation === 'postMessage') { - const channel = this.getNodeParameter('channel', i) as string; - const text = this.getNodeParameter('text', i) as string; - const options = this.getNodeParameter('options', i) as IDataObject; - const jsonActive = this.getNodeParameter('jsonParameters', i) as boolean; + try { + if (resource === 'chat') { + //https://rocket.chat/docs/developer-guides/rest-api/chat/postmessage + if (operation === 'postMessage') { + const channel = this.getNodeParameter('channel', i) as string; + const text = this.getNodeParameter('text', i) as string; + const options = this.getNodeParameter('options', i) as IDataObject; + const jsonActive = this.getNodeParameter('jsonParameters', i) as boolean; - const body: IPostMessageBody = { - channel, - text, - }; + const body: IPostMessageBody = { + channel, + text, + }; - if (options.alias) { - body.alias = options.alias as string; - } - if (options.avatar) { - body.avatar = options.avatar as string; - } - if (options.emoji) { - body.emoji = options.emoji as string; - } + if (options.alias) { + body.alias = options.alias as string; + } + if (options.avatar) { + body.avatar = options.avatar as string; + } + if (options.emoji) { + body.emoji = options.emoji as string; + } - if (!jsonActive) { - const optionsAttachments = this.getNodeParameter('attachments', i) as IDataObject[]; - if (optionsAttachments.length > 0) { - const attachments: IAttachment[] = []; - for (let i = 0; i < optionsAttachments.length; i++) { - const attachment: IAttachment = {}; - for (const option of Object.keys(optionsAttachments[i])) { - if (option === 'color') { - attachment.color = optionsAttachments[i][option] as string; - } else if (option === 'text') { - attachment.text = optionsAttachments[i][option] as string; - } else if (option === 'ts') { - attachment.ts = optionsAttachments[i][option] as string; - } else if (option === 'messageLinks') { - attachment.message_link = optionsAttachments[i][option] as string; - } else if (option === 'thumbUrl') { - attachment.thumb_url = optionsAttachments[i][option] as string; - } else if (option === 'collapsed') { - attachment.collapsed = optionsAttachments[i][option] as boolean; - } else if (option === 'authorName') { - attachment.author_name = optionsAttachments[i][option] as string; - } else if (option === 'authorLink') { - attachment.author_link = optionsAttachments[i][option] as string; - } else if (option === 'authorIcon') { - attachment.author_icon = optionsAttachments[i][option] as string; - } else if (option === 'title') { - attachment.title = optionsAttachments[i][option] as string; - } else if (option === 'titleLink') { - attachment.title_link = optionsAttachments[i][option] as string; - } else if (option === 'titleLinkDownload') { - attachment.title_link_download = optionsAttachments[i][option] as boolean; - } else if (option === 'imageUrl') { - attachment.image_url = optionsAttachments[i][option] as string; - } else if (option === 'audioUrl') { - attachment.audio_url = optionsAttachments[i][option] as string; - } else if (option === 'videoUrl') { - attachment.video_url = optionsAttachments[i][option] as string; - } else if (option === 'fields') { - const fieldsValues = (optionsAttachments[i][option] as IDataObject).fieldsValues as IDataObject[]; - if (fieldsValues.length > 0) { - const fields: IField[] = []; - for (let i = 0; i < fieldsValues.length; i++) { - const field: IField = {}; - for (const key of Object.keys(fieldsValues[i])) { - if (key === 'short') { - field.short = fieldsValues[i][key] as boolean; - } else if (key === 'title') { - field.title = fieldsValues[i][key] as string; - } else if (key === 'value') { - field.value = fieldsValues[i][key] as string; + if (!jsonActive) { + const optionsAttachments = this.getNodeParameter('attachments', i) as IDataObject[]; + if (optionsAttachments.length > 0) { + const attachments: IAttachment[] = []; + for (let i = 0; i < optionsAttachments.length; i++) { + const attachment: IAttachment = {}; + for (const option of Object.keys(optionsAttachments[i])) { + if (option === 'color') { + attachment.color = optionsAttachments[i][option] as string; + } else if (option === 'text') { + attachment.text = optionsAttachments[i][option] as string; + } else if (option === 'ts') { + attachment.ts = optionsAttachments[i][option] as string; + } else if (option === 'messageLinks') { + attachment.message_link = optionsAttachments[i][option] as string; + } else if (option === 'thumbUrl') { + attachment.thumb_url = optionsAttachments[i][option] as string; + } else if (option === 'collapsed') { + attachment.collapsed = optionsAttachments[i][option] as boolean; + } else if (option === 'authorName') { + attachment.author_name = optionsAttachments[i][option] as string; + } else if (option === 'authorLink') { + attachment.author_link = optionsAttachments[i][option] as string; + } else if (option === 'authorIcon') { + attachment.author_icon = optionsAttachments[i][option] as string; + } else if (option === 'title') { + attachment.title = optionsAttachments[i][option] as string; + } else if (option === 'titleLink') { + attachment.title_link = optionsAttachments[i][option] as string; + } else if (option === 'titleLinkDownload') { + attachment.title_link_download = optionsAttachments[i][option] as boolean; + } else if (option === 'imageUrl') { + attachment.image_url = optionsAttachments[i][option] as string; + } else if (option === 'audioUrl') { + attachment.audio_url = optionsAttachments[i][option] as string; + } else if (option === 'videoUrl') { + attachment.video_url = optionsAttachments[i][option] as string; + } else if (option === 'fields') { + const fieldsValues = (optionsAttachments[i][option] as IDataObject).fieldsValues as IDataObject[]; + if (fieldsValues.length > 0) { + const fields: IField[] = []; + for (let i = 0; i < fieldsValues.length; i++) { + const field: IField = {}; + for (const key of Object.keys(fieldsValues[i])) { + if (key === 'short') { + field.short = fieldsValues[i][key] as boolean; + } else if (key === 'title') { + field.title = fieldsValues[i][key] as string; + } else if (key === 'value') { + field.value = fieldsValues[i][key] as string; + } } + fields.push(field); + attachment.fields = fields; } - fields.push(field); - attachment.fields = fields; } } } + attachments.push(attachment); } - attachments.push(attachment); + body.attachments = attachments; } - body.attachments = attachments; + } else { + body.attachments = validateJSON(this.getNodeParameter('attachmentsJson', i) as string); } - } else { - body.attachments = validateJSON(this.getNodeParameter('attachmentsJson', i) as string); - } - responseData = await rocketchatApiRequest.call(this, '/chat', 'POST', 'postMessage', body); + responseData = await rocketchatApiRequest.call(this, '/chat', 'POST', 'postMessage', body); + } } - } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else if (responseData !== undefined) { - returnData.push(responseData as IDataObject); + if (Array.isArray(responseData)) { + returnData.push.apply(returnData, responseData as IDataObject[]); + } else if (responseData !== undefined) { + returnData.push(responseData as IDataObject); + } + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } } diff --git a/packages/nodes-base/nodes/RssFeedRead.node.ts b/packages/nodes-base/nodes/RssFeedRead.node.ts index 03e13dc822..be78360244 100644 --- a/packages/nodes-base/nodes/RssFeedRead.node.ts +++ b/packages/nodes-base/nodes/RssFeedRead.node.ts @@ -8,6 +8,7 @@ import { } from 'n8n-workflow'; import * as Parser from 'rss-parser'; +import { URL } from 'url'; export class RssFeedRead implements INodeType { description: INodeTypeDescription = { @@ -38,37 +39,60 @@ export class RssFeedRead implements INodeType { async execute(this: IExecuteFunctions): Promise { - const url = this.getNodeParameter('url', 0) as string; + try{ - if (!url) { - throw new NodeOperationError(this.getNode(), 'The parameter "URL" has to be set!'); - } - // TODO: Later add also check if the url has a valid format + const url = this.getNodeParameter('url', 0) as string; - const parser = new Parser(); - - let feed: Parser.Output; - try { - feed = await parser.parseURL(url); - } catch (error) { - if (error.code === 'ECONNREFUSED') { - throw new NodeOperationError(this.getNode(), `It was not possible to connect to the URL. Please make sure the URL "${url}" it is valid!`); + if (!url) { + throw new NodeOperationError(this.getNode(), 'The parameter "URL" has to be set!'); } - throw new NodeOperationError(this.getNode(), error); + if (!validateURL(url)){ + throw new NodeOperationError(this.getNode(), 'The provided "URL" is not valid!'); + } + + const parser = new Parser(); + + let feed: Parser.Output; + try { + feed = await parser.parseURL(url); + } catch (error) { + if (error.code === 'ECONNREFUSED') { + throw new NodeOperationError(this.getNode(), `It was not possible to connect to the URL. Please make sure the URL "${url}" it is valid!`); + } + + throw new NodeOperationError(this.getNode(), error); + } + + + const returnData: IDataObject[] = []; + + // For now we just take the items and ignore everything else + if (feed.items) { + feed.items.forEach((item) => { + // @ts-ignore + returnData.push(item); + }); + } + + return [this.helpers.returnJsonArray(returnData)]; + + } catch (error) { + if (this.continueOnFail()) { + return this.prepareOutputData([{json:{ error: error.message }}]); + } + throw error; } - - - const returnData: IDataObject[] = []; - - // For now we just take the items and ignore everything else - if (feed.items) { - feed.items.forEach((item) => { - // @ts-ignore - returnData.push(item); - }); - } - - return [this.helpers.returnJsonArray(returnData)]; + } +} + +// Utility function + +function validateURL (url: string) { + try { + const parseUrl = new URL(url); + return true; + } catch (err) { + return false; } } diff --git a/packages/nodes-base/nodes/S3/S3.node.ts b/packages/nodes-base/nodes/S3/S3.node.ts index 70c7f3dbd3..4b44ff810e 100644 --- a/packages/nodes-base/nodes/S3/S3.node.ts +++ b/packages/nodes-base/nodes/S3/S3.node.ts @@ -111,525 +111,537 @@ export class S3 implements INodeType { const resource = this.getNodeParameter('resource', 0) as string; const operation = this.getNodeParameter('operation', 0) as string; for (let i = 0; i < items.length; i++) { - const headers: IDataObject = {}; - if (resource === 'bucket') { - //https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateBucket.html - if (operation === 'create') { + try { + const headers: IDataObject = {}; + if (resource === 'bucket') { + //https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateBucket.html + if (operation === 'create') { - let credentials; + let credentials; - try { - credentials = this.getCredentials('s3'); - } catch (error) { - throw new NodeApiError(this.getNode(), error); - } + try { + credentials = this.getCredentials('s3'); + } catch (error) { + throw new NodeApiError(this.getNode(), error); + } - const name = this.getNodeParameter('name', i) as string; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - if (additionalFields.acl) { - headers['x-amz-acl'] = paramCase(additionalFields.acl as string); - } - if (additionalFields.bucketObjectLockEnabled) { - headers['x-amz-bucket-object-lock-enabled'] = additionalFields.bucketObjectLockEnabled as boolean; - } - if (additionalFields.grantFullControl) { - headers['x-amz-grant-full-control'] = ''; - } - if (additionalFields.grantRead) { - headers['x-amz-grant-read'] = ''; - } - if (additionalFields.grantReadAcp) { - headers['x-amz-grant-read-acp'] = ''; - } - if (additionalFields.grantWrite) { - headers['x-amz-grant-write'] = ''; - } - if (additionalFields.grantWriteAcp) { - headers['x-amz-grant-write-acp'] = ''; - } - let region = credentials!.region as string; + const name = this.getNodeParameter('name', i) as string; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + if (additionalFields.acl) { + headers['x-amz-acl'] = paramCase(additionalFields.acl as string); + } + if (additionalFields.bucketObjectLockEnabled) { + headers['x-amz-bucket-object-lock-enabled'] = additionalFields.bucketObjectLockEnabled as boolean; + } + if (additionalFields.grantFullControl) { + headers['x-amz-grant-full-control'] = ''; + } + if (additionalFields.grantRead) { + headers['x-amz-grant-read'] = ''; + } + if (additionalFields.grantReadAcp) { + headers['x-amz-grant-read-acp'] = ''; + } + if (additionalFields.grantWrite) { + headers['x-amz-grant-write'] = ''; + } + if (additionalFields.grantWriteAcp) { + headers['x-amz-grant-write-acp'] = ''; + } + let region = credentials!.region as string; - if (additionalFields.region) { - region = additionalFields.region as string; - } + if (additionalFields.region) { + region = additionalFields.region as string; + } - const body: IDataObject = { - CreateBucketConfiguration: { - '$': { - xmlns: 'http://s3.amazonaws.com/doc/2006-03-01/', - }, - }, - }; - let data = ''; - // if credentials has the S3 defaul region (us-east-1) the body (XML) does not have to be sent. - if (region !== 'us-east-1') { - // @ts-ignore - body.CreateBucketConfiguration.LocationConstraint = [region]; - const builder = new Builder(); - data = builder.buildObject(body); - } - responseData = await s3ApiRequestSOAP.call(this, `${name}`, 'PUT', '', data, qs, headers); - - returnData.push({ success: true }); - } - //https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListBuckets.html - if (operation === 'getAll') { - const returnAll = this.getNodeParameter('returnAll', 0) as boolean; - if (returnAll) { - responseData = await s3ApiRequestSOAPAllItems.call(this, 'ListAllMyBucketsResult.Buckets.Bucket', '', 'GET', ''); - } else { - qs.limit = this.getNodeParameter('limit', 0) as number; - responseData = await s3ApiRequestSOAPAllItems.call(this, 'ListAllMyBucketsResult.Buckets.Bucket', '', 'GET', '', '', qs); - responseData = responseData.slice(0, qs.limit); - } - returnData.push.apply(returnData, responseData); - } - - //https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListObjectsV2.html - if (operation === 'search') { - const bucketName = this.getNodeParameter('bucketName', i) as string; - const returnAll = this.getNodeParameter('returnAll', 0) as boolean; - const additionalFields = this.getNodeParameter('additionalFields', 0) as IDataObject; - - if (additionalFields.prefix) { - qs['prefix'] = additionalFields.prefix as string; - } - - if (additionalFields.encodingType) { - qs['encoding-type'] = additionalFields.encodingType as string; - } - - if (additionalFields.delmiter) { - qs['delimiter'] = additionalFields.delmiter as string; - } - - if (additionalFields.fetchOwner) { - qs['fetch-owner'] = additionalFields.fetchOwner as string; - } - - if (additionalFields.startAfter) { - qs['start-after'] = additionalFields.startAfter as string; - } - - if (additionalFields.requesterPays) { - qs['x-amz-request-payer'] = 'requester'; - } - - qs['list-type'] = 2; - - - responseData = await s3ApiRequestSOAP.call(this, bucketName, 'GET', '', '', { location: '' }); - - const region = responseData.LocationConstraint._ as string; - - if (returnAll) { - responseData = await s3ApiRequestSOAPAllItems.call(this, 'ListBucketResult.Contents', bucketName, 'GET', '', '', qs, {}, {}, region); - } else { - qs['max-keys'] = this.getNodeParameter('limit', 0) as number; - responseData = await s3ApiRequestSOAP.call(this, bucketName, 'GET', '', '', qs, {}, {}, region); - responseData = responseData.ListBucketResult.Contents; - } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData); - } else { - returnData.push(responseData); - } - } - } - if (resource === 'folder') { - //https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html - if (operation === 'create') { - const bucketName = this.getNodeParameter('bucketName', i) as string; - const folderName = this.getNodeParameter('folderName', i) as string; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - let path = `/${folderName}/`; - - if (additionalFields.requesterPays) { - headers['x-amz-request-payer'] = 'requester'; - } - if (additionalFields.parentFolderKey) { - path = `/${additionalFields.parentFolderKey}${folderName}/`; - } - if (additionalFields.storageClass) { - headers['x-amz-storage-class'] = (snakeCase(additionalFields.storageClass as string)).toUpperCase(); - } - responseData = await s3ApiRequestSOAP.call(this, bucketName, 'GET', '', '', { location: '' }); - - const region = responseData.LocationConstraint._; - - responseData = await s3ApiRequestSOAP.call(this, bucketName, 'PUT', path, '', qs, headers, {}, region); - returnData.push({ success: true }); - } - //https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteObjects.html - if (operation === 'delete') { - const bucketName = this.getNodeParameter('bucketName', i) as string; - const folderKey = this.getNodeParameter('folderKey', i) as string; - - responseData = await s3ApiRequestSOAP.call(this, bucketName, 'GET', '', '', { location: '' }); - - const region = responseData.LocationConstraint._; - - responseData = await s3ApiRequestSOAPAllItems.call(this, 'ListBucketResult.Contents', bucketName, 'GET', '/', '', { 'list-type': 2, prefix: folderKey }, {}, {}, region); - - // folder empty then just delete it - if (responseData.length === 0) { - - responseData = await s3ApiRequestSOAP.call(this, bucketName, 'DELETE', `/${folderKey}`, '', qs, {}, {}, region); - - responseData = { deleted: [{ 'Key': folderKey }] }; - - } else { - // delete everything inside the folder const body: IDataObject = { - Delete: { + CreateBucketConfiguration: { '$': { xmlns: 'http://s3.amazonaws.com/doc/2006-03-01/', }, - Object: [], }, }; - - for (const childObject of responseData) { - //@ts-ignore - (body.Delete.Object as IDataObject[]).push({ - Key: childObject.Key as string, - }); + let data = ''; + // if credentials has the S3 defaul region (us-east-1) the body (XML) does not have to be sent. + if (region !== 'us-east-1') { + // @ts-ignore + body.CreateBucketConfiguration.LocationConstraint = [region]; + const builder = new Builder(); + data = builder.buildObject(body); } + responseData = await s3ApiRequestSOAP.call(this, `${name}`, 'PUT', '', data, qs, headers); - const builder = new Builder(); - const data = builder.buildObject(body); - - headers['Content-MD5'] = createHash('md5').update(data).digest('base64'); - - headers['Content-Type'] = 'application/xml'; - - responseData = await s3ApiRequestSOAP.call(this, bucketName, 'POST', '/', data, { delete: '' }, headers, {}, region); - - responseData = { deleted: responseData.DeleteResult.Deleted }; + returnData.push({ success: true }); } - returnData.push(responseData); - } - //https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListObjectsV2.html - if (operation === 'getAll') { - const bucketName = this.getNodeParameter('bucketName', i) as string; - const returnAll = this.getNodeParameter('returnAll', 0) as boolean; - const options = this.getNodeParameter('options', 0) as IDataObject; - - if (options.folderKey) { - qs['prefix'] = options.folderKey as string; - } - - if (options.fetchOwner) { - qs['fetch-owner'] = options.fetchOwner as string; - } - - qs['list-type'] = 2; - - responseData = await s3ApiRequestSOAP.call(this, bucketName, 'GET', '', '', { location: '' }); - - const region = responseData.LocationConstraint._; - - if (returnAll) { - responseData = await s3ApiRequestSOAPAllItems.call(this, 'ListBucketResult.Contents', bucketName, 'GET', '', '', qs, {}, {}, region); - } else { - qs.limit = this.getNodeParameter('limit', 0) as number; - responseData = await s3ApiRequestSOAPAllItems.call(this, 'ListBucketResult.Contents', bucketName, 'GET', '', '', qs, {}, {}, region); - } - if (Array.isArray(responseData)) { - responseData = responseData.filter((e: IDataObject) => (e.Key as string).endsWith('/') && e.Size === '0' && e.Key !== options.folderKey); - if (qs.limit) { - responseData = responseData.splice(0, qs.limit as number); + //https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListBuckets.html + if (operation === 'getAll') { + const returnAll = this.getNodeParameter('returnAll', 0) as boolean; + if (returnAll) { + responseData = await s3ApiRequestSOAPAllItems.call(this, 'ListAllMyBucketsResult.Buckets.Bucket', '', 'GET', ''); + } else { + qs.limit = this.getNodeParameter('limit', 0) as number; + responseData = await s3ApiRequestSOAPAllItems.call(this, 'ListAllMyBucketsResult.Buckets.Bucket', '', 'GET', '', '', qs); + responseData = responseData.slice(0, qs.limit); } returnData.push.apply(returnData, responseData); } - } - } - if (resource === 'file') { - //https://docs.aws.amazon.com/AmazonS3/latest/API/API_CopyObject.html - if (operation === 'copy') { - const sourcePath = this.getNodeParameter('sourcePath', i) as string; - const destinationPath = this.getNodeParameter('destinationPath', i) as string; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - headers['x-amz-copy-source'] = sourcePath; + //https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListObjectsV2.html + if (operation === 'search') { + const bucketName = this.getNodeParameter('bucketName', i) as string; + const returnAll = this.getNodeParameter('returnAll', 0) as boolean; + const additionalFields = this.getNodeParameter('additionalFields', 0) as IDataObject; - if (additionalFields.requesterPays) { - headers['x-amz-request-payer'] = 'requester'; - } - if (additionalFields.storageClass) { - headers['x-amz-storage-class'] = (snakeCase(additionalFields.storageClass as string)).toUpperCase(); - } - if (additionalFields.acl) { - headers['x-amz-acl'] = paramCase(additionalFields.acl as string); - } - if (additionalFields.grantFullControl) { - headers['x-amz-grant-full-control'] = ''; - } - if (additionalFields.grantRead) { - headers['x-amz-grant-read'] = ''; - } - if (additionalFields.grantReadAcp) { - headers['x-amz-grant-read-acp'] = ''; - } - if (additionalFields.grantWriteAcp) { - headers['x-amz-grant-write-acp'] = ''; - } - if (additionalFields.lockLegalHold) { - headers['x-amz-object-lock-legal-hold'] = (additionalFields.lockLegalHold as boolean) ? 'ON' : 'OFF'; - } - if (additionalFields.lockMode) { - headers['x-amz-object-lock-mode'] = (additionalFields.lockMode as string).toUpperCase(); - } - if (additionalFields.lockRetainUntilDate) { - headers['x-amz-object-lock-retain-until-date'] = additionalFields.lockRetainUntilDate as string; - } - if (additionalFields.serverSideEncryption) { - headers['x-amz-server-side-encryption'] = additionalFields.serverSideEncryption as string; - } - if (additionalFields.encryptionAwsKmsKeyId) { - headers['x-amz-server-side-encryption-aws-kms-key-id'] = additionalFields.encryptionAwsKmsKeyId as string; - } - if (additionalFields.serverSideEncryptionContext) { - headers['x-amz-server-side-encryption-context'] = additionalFields.serverSideEncryptionContext as string; - } - if (additionalFields.serversideEncryptionCustomerAlgorithm) { - headers['x-amz-server-side-encryption-customer-algorithm'] = additionalFields.serversideEncryptionCustomerAlgorithm as string; - } - if (additionalFields.serversideEncryptionCustomerKey) { - headers['x-amz-server-side-encryption-customer-key'] = additionalFields.serversideEncryptionCustomerKey as string; - } - if (additionalFields.serversideEncryptionCustomerKeyMD5) { - headers['x-amz-server-side-encryption-customer-key-MD5'] = additionalFields.serversideEncryptionCustomerKeyMD5 as string; - } - if (additionalFields.taggingDirective) { - headers['x-amz-tagging-directive'] = (additionalFields.taggingDirective as string).toUpperCase(); - } - if (additionalFields.metadataDirective) { - headers['x-amz-metadata-directive'] = (additionalFields.metadataDirective as string).toUpperCase(); - } - - const destinationParts = destinationPath.split('/'); - - const bucketName = destinationParts[1]; - - const destination = `/${destinationParts.slice(2, destinationParts.length).join('/')}`; - - responseData = await s3ApiRequestSOAP.call(this, bucketName, 'GET', '', '', { location: '' }); - - const region = responseData.LocationConstraint._; - - responseData = await s3ApiRequestSOAP.call(this, bucketName, 'PUT', destination, '', qs, headers, {}, region); - returnData.push(responseData.CopyObjectResult); - - } - //https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObject.html - if (operation === 'download') { - - const bucketName = this.getNodeParameter('bucketName', i) as string; - - const fileKey = this.getNodeParameter('fileKey', i) as string; - - const fileName = fileKey.split('/')[fileKey.split('/').length - 1]; - - if (fileKey.substring(fileKey.length - 1) === '/') { - throw new NodeOperationError(this.getNode(), 'Downloding a whole directory is not yet supported, please provide a file key'); - } - - let region = await s3ApiRequestSOAP.call(this, bucketName, 'GET', '', '', { location: '' }); - - region = region.LocationConstraint._; - - const response = await s3ApiRequestREST.call(this, bucketName, 'GET', `/${fileKey}`, '', qs, {}, { encoding: null, resolveWithFullResponse: true }, region); - - let mimeType: string | undefined; - if (response.headers['content-type']) { - mimeType = response.headers['content-type']; - } - - const newItem: INodeExecutionData = { - json: items[i].json, - binary: {}, - }; - - if (items[i].binary !== undefined) { - // Create a shallow copy of the binary data so that the old - // data references which do not get changed still stay behind - // but the incoming data does not get changed. - Object.assign(newItem.binary, items[i].binary); - } - - items[i] = newItem; - - const dataPropertyNameDownload = this.getNodeParameter('binaryPropertyName', i) as string; - - const data = Buffer.from(response.body as string, 'utf8'); - - items[i].binary![dataPropertyNameDownload] = await this.helpers.prepareBinaryData(data as unknown as Buffer, fileName, mimeType); - } - //https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteObject.html - if (operation === 'delete') { - const bucketName = this.getNodeParameter('bucketName', i) as string; - - const fileKey = this.getNodeParameter('fileKey', i) as string; - - const options = this.getNodeParameter('options', i) as IDataObject; - - if (options.versionId) { - qs.versionId = options.versionId as string; - } - - responseData = await s3ApiRequestSOAP.call(this, bucketName, 'GET', '', '', { location: '' }); - - const region = responseData.LocationConstraint._; - - responseData = await s3ApiRequestSOAP.call(this, bucketName, 'DELETE', `/${fileKey}`, '', qs, {}, {}, region); - - returnData.push({ success: true }); - } - //https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListObjectsV2.html - if (operation === 'getAll') { - const bucketName = this.getNodeParameter('bucketName', i) as string; - const returnAll = this.getNodeParameter('returnAll', 0) as boolean; - const options = this.getNodeParameter('options', 0) as IDataObject; - - if (options.folderKey) { - qs['prefix'] = options.folderKey as string; - } - - if (options.fetchOwner) { - qs['fetch-owner'] = options.fetchOwner as string; - } - - qs['delimiter'] = '/'; - - qs['list-type'] = 2; - - responseData = await s3ApiRequestSOAP.call(this, bucketName, 'GET', '', '', { location: '' }); - - const region = responseData.LocationConstraint._; - - if (returnAll) { - responseData = await s3ApiRequestSOAPAllItems.call(this, 'ListBucketResult.Contents', bucketName, 'GET', '', '', qs, {}, {}, region); - } else { - qs.limit = this.getNodeParameter('limit', 0) as number; - responseData = await s3ApiRequestSOAPAllItems.call(this, 'ListBucketResult.Contents', bucketName, 'GET', '', '', qs, {}, {}, region); - responseData = responseData.splice(0, qs.limit); - } - if (Array.isArray(responseData)) { - responseData = responseData.filter((e: IDataObject) => !(e.Key as string).endsWith('/') && e.Size !== '0'); - if (qs.limit) { - responseData = responseData.splice(0, qs.limit as number); - } - returnData.push.apply(returnData, responseData); - } - } - //https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html - if (operation === 'upload') { - const bucketName = this.getNodeParameter('bucketName', i) as string; - const fileName = this.getNodeParameter('fileName', i) as string; - const isBinaryData = this.getNodeParameter('binaryData', i) as boolean; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const tagsValues = (this.getNodeParameter('tagsUi', i) as IDataObject).tagsValues as IDataObject[]; - let path = '/'; - let body; - - if (additionalFields.requesterPays) { - headers['x-amz-request-payer'] = 'requester'; - } - - if (additionalFields.parentFolderKey) { - path = `/${additionalFields.parentFolderKey}/`; - } - if (additionalFields.storageClass) { - headers['x-amz-storage-class'] = (snakeCase(additionalFields.storageClass as string)).toUpperCase(); - } - if (additionalFields.acl) { - headers['x-amz-acl'] = paramCase(additionalFields.acl as string); - } - if (additionalFields.grantFullControl) { - headers['x-amz-grant-full-control'] = ''; - } - if (additionalFields.grantRead) { - headers['x-amz-grant-read'] = ''; - } - if (additionalFields.grantReadAcp) { - headers['x-amz-grant-read-acp'] = ''; - } - if (additionalFields.grantWriteAcp) { - headers['x-amz-grant-write-acp'] = ''; - } - if (additionalFields.lockLegalHold) { - headers['x-amz-object-lock-legal-hold'] = (additionalFields.lockLegalHold as boolean) ? 'ON' : 'OFF'; - } - if (additionalFields.lockMode) { - headers['x-amz-object-lock-mode'] = (additionalFields.lockMode as string).toUpperCase(); - } - if (additionalFields.lockRetainUntilDate) { - headers['x-amz-object-lock-retain-until-date'] = additionalFields.lockRetainUntilDate as string; - } - if (additionalFields.serverSideEncryption) { - headers['x-amz-server-side-encryption'] = additionalFields.serverSideEncryption as string; - } - if (additionalFields.encryptionAwsKmsKeyId) { - headers['x-amz-server-side-encryption-aws-kms-key-id'] = additionalFields.encryptionAwsKmsKeyId as string; - } - if (additionalFields.serverSideEncryptionContext) { - headers['x-amz-server-side-encryption-context'] = additionalFields.serverSideEncryptionContext as string; - } - if (additionalFields.serversideEncryptionCustomerAlgorithm) { - headers['x-amz-server-side-encryption-customer-algorithm'] = additionalFields.serversideEncryptionCustomerAlgorithm as string; - } - if (additionalFields.serversideEncryptionCustomerKey) { - headers['x-amz-server-side-encryption-customer-key'] = additionalFields.serversideEncryptionCustomerKey as string; - } - if (additionalFields.serversideEncryptionCustomerKeyMD5) { - headers['x-amz-server-side-encryption-customer-key-MD5'] = additionalFields.serversideEncryptionCustomerKeyMD5 as string; - } - if (tagsValues) { - const tags: string[] = []; - tagsValues.forEach((o: IDataObject) => { tags.push(`${o.key}=${o.value}`); }); - headers['x-amz-tagging'] = tags.join('&'); - } - - responseData = await s3ApiRequestSOAP.call(this, bucketName, 'GET', '', '', { location: '' }); - - const region = responseData.LocationConstraint._; - - if (isBinaryData) { - const binaryPropertyName = this.getNodeParameter('binaryPropertyName', 0) as string; - - if (items[i].binary === undefined) { - throw new NodeOperationError(this.getNode(), 'No binary data exists on item!'); + if (additionalFields.prefix) { + qs['prefix'] = additionalFields.prefix as string; } - if ((items[i].binary as IBinaryKeyData)[binaryPropertyName] === undefined) { - throw new NodeOperationError(this.getNode(), `No binary data property "${binaryPropertyName}" does not exists on item!`); + if (additionalFields.encodingType) { + qs['encoding-type'] = additionalFields.encodingType as string; } - const binaryData = (items[i].binary as IBinaryKeyData)[binaryPropertyName]; + if (additionalFields.delmiter) { + qs['delimiter'] = additionalFields.delmiter as string; + } - body = Buffer.from(binaryData.data, BINARY_ENCODING) as Buffer; + if (additionalFields.fetchOwner) { + qs['fetch-owner'] = additionalFields.fetchOwner as string; + } - headers['Content-Type'] = binaryData.mimeType; + if (additionalFields.startAfter) { + qs['start-after'] = additionalFields.startAfter as string; + } - headers['Content-MD5'] = createHash('md5').update(body).digest('base64'); + if (additionalFields.requesterPays) { + qs['x-amz-request-payer'] = 'requester'; + } - responseData = await s3ApiRequestSOAP.call(this, bucketName, 'PUT', `${path}${fileName || binaryData.fileName}`, body, qs, headers, {}, region); + qs['list-type'] = 2; - } else { - const fileContent = this.getNodeParameter('fileContent', i) as string; + responseData = await s3ApiRequestSOAP.call(this, bucketName, 'GET', '', '', { location: '' }); - body = Buffer.from(fileContent, 'utf8'); + const region = responseData.LocationConstraint._ as string; - headers['Content-Type'] = 'text/html'; - - headers['Content-MD5'] = createHash('md5').update(fileContent).digest('base64'); - - responseData = await s3ApiRequestSOAP.call(this, bucketName, 'PUT', `${path}${fileName}`, body, qs, headers, {}, region); + if (returnAll) { + responseData = await s3ApiRequestSOAPAllItems.call(this, 'ListBucketResult.Contents', bucketName, 'GET', '', '', qs, {}, {}, region); + } else { + qs['max-keys'] = this.getNodeParameter('limit', 0) as number; + responseData = await s3ApiRequestSOAP.call(this, bucketName, 'GET', '', '', qs, {}, {}, region); + responseData = responseData.ListBucketResult.Contents; + } + if (Array.isArray(responseData)) { + returnData.push.apply(returnData, responseData); + } else { + returnData.push(responseData); + } } - returnData.push({ success: true }); } + if (resource === 'folder') { + //https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html + if (operation === 'create') { + const bucketName = this.getNodeParameter('bucketName', i) as string; + const folderName = this.getNodeParameter('folderName', i) as string; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + let path = `/${folderName}/`; + + if (additionalFields.requesterPays) { + headers['x-amz-request-payer'] = 'requester'; + } + if (additionalFields.parentFolderKey) { + path = `/${additionalFields.parentFolderKey}${folderName}/`; + } + if (additionalFields.storageClass) { + headers['x-amz-storage-class'] = (snakeCase(additionalFields.storageClass as string)).toUpperCase(); + } + responseData = await s3ApiRequestSOAP.call(this, bucketName, 'GET', '', '', { location: '' }); + + const region = responseData.LocationConstraint._; + + responseData = await s3ApiRequestSOAP.call(this, bucketName, 'PUT', path, '', qs, headers, {}, region); + returnData.push({ success: true }); + } + //https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteObjects.html + if (operation === 'delete') { + const bucketName = this.getNodeParameter('bucketName', i) as string; + const folderKey = this.getNodeParameter('folderKey', i) as string; + + responseData = await s3ApiRequestSOAP.call(this, bucketName, 'GET', '', '', { location: '' }); + + const region = responseData.LocationConstraint._; + + responseData = await s3ApiRequestSOAPAllItems.call(this, 'ListBucketResult.Contents', bucketName, 'GET', '/', '', { 'list-type': 2, prefix: folderKey }, {}, {}, region); + + // folder empty then just delete it + if (responseData.length === 0) { + + responseData = await s3ApiRequestSOAP.call(this, bucketName, 'DELETE', `/${folderKey}`, '', qs, {}, {}, region); + + responseData = { deleted: [{ 'Key': folderKey }] }; + + } else { + // delete everything inside the folder + const body: IDataObject = { + Delete: { + '$': { + xmlns: 'http://s3.amazonaws.com/doc/2006-03-01/', + }, + Object: [], + }, + }; + + for (const childObject of responseData) { + //@ts-ignore + (body.Delete.Object as IDataObject[]).push({ + Key: childObject.Key as string, + }); + } + + const builder = new Builder(); + const data = builder.buildObject(body); + + headers['Content-MD5'] = createHash('md5').update(data).digest('base64'); + + headers['Content-Type'] = 'application/xml'; + + responseData = await s3ApiRequestSOAP.call(this, bucketName, 'POST', '/', data, { delete: '' }, headers, {}, region); + + responseData = { deleted: responseData.DeleteResult.Deleted }; + } + returnData.push(responseData); + } + //https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListObjectsV2.html + if (operation === 'getAll') { + const bucketName = this.getNodeParameter('bucketName', i) as string; + const returnAll = this.getNodeParameter('returnAll', 0) as boolean; + const options = this.getNodeParameter('options', 0) as IDataObject; + + if (options.folderKey) { + qs['prefix'] = options.folderKey as string; + } + + if (options.fetchOwner) { + qs['fetch-owner'] = options.fetchOwner as string; + } + + qs['list-type'] = 2; + + responseData = await s3ApiRequestSOAP.call(this, bucketName, 'GET', '', '', { location: '' }); + + const region = responseData.LocationConstraint._; + + if (returnAll) { + responseData = await s3ApiRequestSOAPAllItems.call(this, 'ListBucketResult.Contents', bucketName, 'GET', '', '', qs, {}, {}, region); + } else { + qs.limit = this.getNodeParameter('limit', 0) as number; + responseData = await s3ApiRequestSOAPAllItems.call(this, 'ListBucketResult.Contents', bucketName, 'GET', '', '', qs, {}, {}, region); + } + if (Array.isArray(responseData)) { + responseData = responseData.filter((e: IDataObject) => (e.Key as string).endsWith('/') && e.Size === '0' && e.Key !== options.folderKey); + if (qs.limit) { + responseData = responseData.splice(0, qs.limit as number); + } + returnData.push.apply(returnData, responseData); + } + } + } + if (resource === 'file') { + //https://docs.aws.amazon.com/AmazonS3/latest/API/API_CopyObject.html + if (operation === 'copy') { + const sourcePath = this.getNodeParameter('sourcePath', i) as string; + const destinationPath = this.getNodeParameter('destinationPath', i) as string; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + + headers['x-amz-copy-source'] = sourcePath; + + if (additionalFields.requesterPays) { + headers['x-amz-request-payer'] = 'requester'; + } + if (additionalFields.storageClass) { + headers['x-amz-storage-class'] = (snakeCase(additionalFields.storageClass as string)).toUpperCase(); + } + if (additionalFields.acl) { + headers['x-amz-acl'] = paramCase(additionalFields.acl as string); + } + if (additionalFields.grantFullControl) { + headers['x-amz-grant-full-control'] = ''; + } + if (additionalFields.grantRead) { + headers['x-amz-grant-read'] = ''; + } + if (additionalFields.grantReadAcp) { + headers['x-amz-grant-read-acp'] = ''; + } + if (additionalFields.grantWriteAcp) { + headers['x-amz-grant-write-acp'] = ''; + } + if (additionalFields.lockLegalHold) { + headers['x-amz-object-lock-legal-hold'] = (additionalFields.lockLegalHold as boolean) ? 'ON' : 'OFF'; + } + if (additionalFields.lockMode) { + headers['x-amz-object-lock-mode'] = (additionalFields.lockMode as string).toUpperCase(); + } + if (additionalFields.lockRetainUntilDate) { + headers['x-amz-object-lock-retain-until-date'] = additionalFields.lockRetainUntilDate as string; + } + if (additionalFields.serverSideEncryption) { + headers['x-amz-server-side-encryption'] = additionalFields.serverSideEncryption as string; + } + if (additionalFields.encryptionAwsKmsKeyId) { + headers['x-amz-server-side-encryption-aws-kms-key-id'] = additionalFields.encryptionAwsKmsKeyId as string; + } + if (additionalFields.serverSideEncryptionContext) { + headers['x-amz-server-side-encryption-context'] = additionalFields.serverSideEncryptionContext as string; + } + if (additionalFields.serversideEncryptionCustomerAlgorithm) { + headers['x-amz-server-side-encryption-customer-algorithm'] = additionalFields.serversideEncryptionCustomerAlgorithm as string; + } + if (additionalFields.serversideEncryptionCustomerKey) { + headers['x-amz-server-side-encryption-customer-key'] = additionalFields.serversideEncryptionCustomerKey as string; + } + if (additionalFields.serversideEncryptionCustomerKeyMD5) { + headers['x-amz-server-side-encryption-customer-key-MD5'] = additionalFields.serversideEncryptionCustomerKeyMD5 as string; + } + if (additionalFields.taggingDirective) { + headers['x-amz-tagging-directive'] = (additionalFields.taggingDirective as string).toUpperCase(); + } + if (additionalFields.metadataDirective) { + headers['x-amz-metadata-directive'] = (additionalFields.metadataDirective as string).toUpperCase(); + } + + const destinationParts = destinationPath.split('/'); + + const bucketName = destinationParts[1]; + + const destination = `/${destinationParts.slice(2, destinationParts.length).join('/')}`; + + responseData = await s3ApiRequestSOAP.call(this, bucketName, 'GET', '', '', { location: '' }); + + const region = responseData.LocationConstraint._; + + responseData = await s3ApiRequestSOAP.call(this, bucketName, 'PUT', destination, '', qs, headers, {}, region); + returnData.push(responseData.CopyObjectResult); + + } + //https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObject.html + if (operation === 'download') { + + const bucketName = this.getNodeParameter('bucketName', i) as string; + + const fileKey = this.getNodeParameter('fileKey', i) as string; + + const fileName = fileKey.split('/')[fileKey.split('/').length - 1]; + + if (fileKey.substring(fileKey.length - 1) === '/') { + throw new NodeOperationError(this.getNode(), 'Downloding a whole directory is not yet supported, please provide a file key'); + } + + let region = await s3ApiRequestSOAP.call(this, bucketName, 'GET', '', '', { location: '' }); + + region = region.LocationConstraint._; + + const response = await s3ApiRequestREST.call(this, bucketName, 'GET', `/${fileKey}`, '', qs, {}, { encoding: null, resolveWithFullResponse: true }, region); + + let mimeType: string | undefined; + if (response.headers['content-type']) { + mimeType = response.headers['content-type']; + } + + const newItem: INodeExecutionData = { + json: items[i].json, + binary: {}, + }; + + if (items[i].binary !== undefined) { + // Create a shallow copy of the binary data so that the old + // data references which do not get changed still stay behind + // but the incoming data does not get changed. + Object.assign(newItem.binary, items[i].binary); + } + + items[i] = newItem; + + const dataPropertyNameDownload = this.getNodeParameter('binaryPropertyName', i) as string; + + const data = Buffer.from(response.body as string, 'utf8'); + + items[i].binary![dataPropertyNameDownload] = await this.helpers.prepareBinaryData(data as unknown as Buffer, fileName, mimeType); + } + //https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteObject.html + if (operation === 'delete') { + const bucketName = this.getNodeParameter('bucketName', i) as string; + + const fileKey = this.getNodeParameter('fileKey', i) as string; + + const options = this.getNodeParameter('options', i) as IDataObject; + + if (options.versionId) { + qs.versionId = options.versionId as string; + } + + responseData = await s3ApiRequestSOAP.call(this, bucketName, 'GET', '', '', { location: '' }); + + const region = responseData.LocationConstraint._; + + responseData = await s3ApiRequestSOAP.call(this, bucketName, 'DELETE', `/${fileKey}`, '', qs, {}, {}, region); + + returnData.push({ success: true }); + } + //https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListObjectsV2.html + if (operation === 'getAll') { + const bucketName = this.getNodeParameter('bucketName', i) as string; + const returnAll = this.getNodeParameter('returnAll', 0) as boolean; + const options = this.getNodeParameter('options', 0) as IDataObject; + + if (options.folderKey) { + qs['prefix'] = options.folderKey as string; + } + + if (options.fetchOwner) { + qs['fetch-owner'] = options.fetchOwner as string; + } + + qs['delimiter'] = '/'; + + qs['list-type'] = 2; + + responseData = await s3ApiRequestSOAP.call(this, bucketName, 'GET', '', '', { location: '' }); + + const region = responseData.LocationConstraint._; + + if (returnAll) { + responseData = await s3ApiRequestSOAPAllItems.call(this, 'ListBucketResult.Contents', bucketName, 'GET', '', '', qs, {}, {}, region); + } else { + qs.limit = this.getNodeParameter('limit', 0) as number; + responseData = await s3ApiRequestSOAPAllItems.call(this, 'ListBucketResult.Contents', bucketName, 'GET', '', '', qs, {}, {}, region); + responseData = responseData.splice(0, qs.limit); + } + if (Array.isArray(responseData)) { + responseData = responseData.filter((e: IDataObject) => !(e.Key as string).endsWith('/') && e.Size !== '0'); + if (qs.limit) { + responseData = responseData.splice(0, qs.limit as number); + } + returnData.push.apply(returnData, responseData); + } + } + //https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html + if (operation === 'upload') { + const bucketName = this.getNodeParameter('bucketName', i) as string; + const fileName = this.getNodeParameter('fileName', i) as string; + const isBinaryData = this.getNodeParameter('binaryData', i) as boolean; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const tagsValues = (this.getNodeParameter('tagsUi', i) as IDataObject).tagsValues as IDataObject[]; + let path = '/'; + let body; + + if (additionalFields.requesterPays) { + headers['x-amz-request-payer'] = 'requester'; + } + + if (additionalFields.parentFolderKey) { + path = `/${additionalFields.parentFolderKey}/`; + } + if (additionalFields.storageClass) { + headers['x-amz-storage-class'] = (snakeCase(additionalFields.storageClass as string)).toUpperCase(); + } + if (additionalFields.acl) { + headers['x-amz-acl'] = paramCase(additionalFields.acl as string); + } + if (additionalFields.grantFullControl) { + headers['x-amz-grant-full-control'] = ''; + } + if (additionalFields.grantRead) { + headers['x-amz-grant-read'] = ''; + } + if (additionalFields.grantReadAcp) { + headers['x-amz-grant-read-acp'] = ''; + } + if (additionalFields.grantWriteAcp) { + headers['x-amz-grant-write-acp'] = ''; + } + if (additionalFields.lockLegalHold) { + headers['x-amz-object-lock-legal-hold'] = (additionalFields.lockLegalHold as boolean) ? 'ON' : 'OFF'; + } + if (additionalFields.lockMode) { + headers['x-amz-object-lock-mode'] = (additionalFields.lockMode as string).toUpperCase(); + } + if (additionalFields.lockRetainUntilDate) { + headers['x-amz-object-lock-retain-until-date'] = additionalFields.lockRetainUntilDate as string; + } + if (additionalFields.serverSideEncryption) { + headers['x-amz-server-side-encryption'] = additionalFields.serverSideEncryption as string; + } + if (additionalFields.encryptionAwsKmsKeyId) { + headers['x-amz-server-side-encryption-aws-kms-key-id'] = additionalFields.encryptionAwsKmsKeyId as string; + } + if (additionalFields.serverSideEncryptionContext) { + headers['x-amz-server-side-encryption-context'] = additionalFields.serverSideEncryptionContext as string; + } + if (additionalFields.serversideEncryptionCustomerAlgorithm) { + headers['x-amz-server-side-encryption-customer-algorithm'] = additionalFields.serversideEncryptionCustomerAlgorithm as string; + } + if (additionalFields.serversideEncryptionCustomerKey) { + headers['x-amz-server-side-encryption-customer-key'] = additionalFields.serversideEncryptionCustomerKey as string; + } + if (additionalFields.serversideEncryptionCustomerKeyMD5) { + headers['x-amz-server-side-encryption-customer-key-MD5'] = additionalFields.serversideEncryptionCustomerKeyMD5 as string; + } + if (tagsValues) { + const tags: string[] = []; + tagsValues.forEach((o: IDataObject) => { tags.push(`${o.key}=${o.value}`); }); + headers['x-amz-tagging'] = tags.join('&'); + } + + responseData = await s3ApiRequestSOAP.call(this, bucketName, 'GET', '', '', { location: '' }); + + const region = responseData.LocationConstraint._; + + if (isBinaryData) { + const binaryPropertyName = this.getNodeParameter('binaryPropertyName', 0) as string; + + if (items[i].binary === undefined) { + throw new NodeOperationError(this.getNode(), 'No binary data exists on item!'); + } + + if ((items[i].binary as IBinaryKeyData)[binaryPropertyName] === undefined) { + throw new NodeOperationError(this.getNode(), `No binary data property "${binaryPropertyName}" does not exists on item!`); + } + + const binaryData = (items[i].binary as IBinaryKeyData)[binaryPropertyName]; + + body = Buffer.from(binaryData.data, BINARY_ENCODING) as Buffer; + + headers['Content-Type'] = binaryData.mimeType; + + headers['Content-MD5'] = createHash('md5').update(body).digest('base64'); + + responseData = await s3ApiRequestSOAP.call(this, bucketName, 'PUT', `${path}${fileName || binaryData.fileName}`, body, qs, headers, {}, region); + + } else { + + const fileContent = this.getNodeParameter('fileContent', i) as string; + + body = Buffer.from(fileContent, 'utf8'); + + headers['Content-Type'] = 'text/html'; + + headers['Content-MD5'] = createHash('md5').update(fileContent).digest('base64'); + + responseData = await s3ApiRequestSOAP.call(this, bucketName, 'PUT', `${path}${fileName}`, body, qs, headers, {}, region); + } + returnData.push({ success: true }); + } + } + } catch (error) { + if (this.continueOnFail()) { + if (resource === 'file' && operation === 'download') { + items[i].json = { error: error.message }; + }else { + returnData.push({ error: error.message }); + } + continue; + } + throw error; } } if (resource === 'file' && operation === 'download') { diff --git a/packages/nodes-base/nodes/Salesforce/Salesforce.node.ts b/packages/nodes-base/nodes/Salesforce/Salesforce.node.ts index 08269b0ca7..f9b41623bc 100644 --- a/packages/nodes-base/nodes/Salesforce/Salesforce.node.ts +++ b/packages/nodes-base/nodes/Salesforce/Salesforce.node.ts @@ -950,1631 +950,1642 @@ export class Salesforce implements INodeType { Logger.debug(`Running "Salesforce" node named "${this.getNode.name}" resource "${resource}" operation "${operation}"`); for (let i = 0; i < items.length; i++) { - if (resource === 'lead') { - //https://developer.salesforce.com/docs/api-explorer/sobject/Lead/post-lead - if (operation === 'create' || operation === 'upsert') { - const company = this.getNodeParameter('company', i) as string; - const lastname = this.getNodeParameter('lastname', i) as string; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const body: ILead = { - Company: company, - LastName: lastname, - }; - if (additionalFields.email !== undefined) { - body.Email = additionalFields.email as string; - } - if (additionalFields.city !== undefined) { - body.City = additionalFields.city as string; - } - if (additionalFields.phone !== undefined) { - body.Phone = additionalFields.phone as string; - } - if (additionalFields.state !== undefined) { - body.State = additionalFields.state as string; - } - if (additionalFields.title !== undefined) { - body.Title = additionalFields.title as string; - } - if (additionalFields.jigsaw !== undefined) { - body.Jigsaw = additionalFields.jigsaw as string; - } - if (additionalFields.rating !== undefined) { - body.Rating = additionalFields.rating as string; - } - if (additionalFields.status !== undefined) { - body.Status = additionalFields.status as string; - } - if (additionalFields.street !== undefined) { - body.Street = additionalFields.street as string; - } - if (additionalFields.country !== undefined) { - body.Country = additionalFields.country as string; - } - if (additionalFields.owner !== undefined) { - body.OwnerId = additionalFields.owner as string; - } - if (additionalFields.website !== undefined) { - body.Website = additionalFields.website as string; - } - if (additionalFields.industry !== undefined) { - body.Industry = additionalFields.industry as string; - } - if (additionalFields.firstname !== undefined) { - body.FirstName = additionalFields.firstname as string; - } - if (additionalFields.leadSource !== undefined) { - body.LeadSource = additionalFields.leadSource as string; - } - if (additionalFields.postalCode !== undefined) { - body.PostalCode = additionalFields.postalCode as string; - } - if (additionalFields.salutation !== undefined) { - body.Salutation = additionalFields.salutation as string; - } - if (additionalFields.description !== undefined) { - body.Description = additionalFields.description as string; - } - if (additionalFields.annualRevenue !== undefined) { - body.AnnualRevenue = additionalFields.annualRevenue as number; - } - if (additionalFields.isUnreadByOwner !== undefined) { - body.IsUnreadByOwner = additionalFields.isUnreadByOwner as boolean; - } - if (additionalFields.numberOfEmployees !== undefined) { - body.NumberOfEmployees = additionalFields.numberOfEmployees as number; - } - if (additionalFields.mobilePhone !== undefined) { - body.MobilePhone = additionalFields.mobilePhone 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; + try { + if (resource === 'lead') { + //https://developer.salesforce.com/docs/api-explorer/sobject/Lead/post-lead + if (operation === 'create' || operation === 'upsert') { + const company = this.getNodeParameter('company', i) as string; + const lastname = this.getNodeParameter('lastname', i) as string; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const body: ILead = { + Company: company, + LastName: lastname, + }; + if (additionalFields.email !== undefined) { + body.Email = additionalFields.email as string; + } + if (additionalFields.city !== undefined) { + body.City = additionalFields.city as string; + } + if (additionalFields.phone !== undefined) { + body.Phone = additionalFields.phone as string; + } + if (additionalFields.state !== undefined) { + body.State = additionalFields.state as string; + } + if (additionalFields.title !== undefined) { + body.Title = additionalFields.title as string; + } + if (additionalFields.jigsaw !== undefined) { + body.Jigsaw = additionalFields.jigsaw as string; + } + if (additionalFields.rating !== undefined) { + body.Rating = additionalFields.rating as string; + } + if (additionalFields.status !== undefined) { + body.Status = additionalFields.status as string; + } + if (additionalFields.street !== undefined) { + body.Street = additionalFields.street as string; + } + if (additionalFields.country !== undefined) { + body.Country = additionalFields.country as string; + } + if (additionalFields.owner !== undefined) { + body.OwnerId = additionalFields.owner as string; + } + if (additionalFields.website !== undefined) { + body.Website = additionalFields.website as string; + } + if (additionalFields.industry !== undefined) { + body.Industry = additionalFields.industry as string; + } + if (additionalFields.firstname !== undefined) { + body.FirstName = additionalFields.firstname as string; + } + if (additionalFields.leadSource !== undefined) { + body.LeadSource = additionalFields.leadSource as string; + } + if (additionalFields.postalCode !== undefined) { + body.PostalCode = additionalFields.postalCode as string; + } + if (additionalFields.salutation !== undefined) { + body.Salutation = additionalFields.salutation as string; + } + if (additionalFields.description !== undefined) { + body.Description = additionalFields.description as string; + } + if (additionalFields.annualRevenue !== undefined) { + body.AnnualRevenue = additionalFields.annualRevenue as number; + } + if (additionalFields.isUnreadByOwner !== undefined) { + body.IsUnreadByOwner = additionalFields.isUnreadByOwner as boolean; + } + if (additionalFields.numberOfEmployees !== undefined) { + body.NumberOfEmployees = additionalFields.numberOfEmployees as number; + } + if (additionalFields.mobilePhone !== undefined) { + body.MobilePhone = additionalFields.mobilePhone 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; + } } } - } - let endpoint = '/sobjects/lead'; - let method = 'POST'; - if (operation === 'upsert') { - method = 'PATCH'; - const externalId = this.getNodeParameter('externalId', 0) as string; - const externalIdValue = this.getNodeParameter('externalIdValue', i) as string; - endpoint = `/sobjects/lead/${externalId}/${externalIdValue}`; - if (body[externalId] !== undefined) { - delete body[externalId]; - } - } - responseData = await salesforceApiRequest.call(this, method, endpoint, body); - } - //https://developer.salesforce.com/docs/api-explorer/sobject/Lead/patch-lead-id - if (operation === 'update') { - const leadId = this.getNodeParameter('leadId', i) as string; - const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; - const body: ILead = {}; - if (!Object.keys(updateFields).length) { - throw new NodeOperationError(this.getNode(), 'You must add at least one update field'); - } - if (updateFields.lastname !== undefined) { - body.LastName = updateFields.lastname as string; - } - if (updateFields.company !== undefined) { - body.Company = updateFields.company as string; - } - if (updateFields.email !== undefined) { - body.Email = updateFields.email as string; - } - if (updateFields.city !== undefined) { - body.City = updateFields.city as string; - } - if (updateFields.phone !== undefined) { - body.Phone = updateFields.phone as string; - } - if (updateFields.state !== undefined) { - body.State = updateFields.state as string; - } - if (updateFields.title !== undefined) { - body.Title = updateFields.title as string; - } - if (updateFields.jigsaw !== undefined) { - body.Jigsaw = updateFields.jigsaw as string; - } - if (updateFields.rating !== undefined) { - body.Rating = updateFields.rating as string; - } - if (updateFields.status !== undefined) { - body.Status = updateFields.status as string; - } - if (updateFields.street !== undefined) { - body.Street = updateFields.street as string; - } - if (updateFields.country !== undefined) { - body.Country = updateFields.country as string; - } - if (updateFields.owner !== undefined) { - body.OwnerId = updateFields.owner as string; - } - if (updateFields.website !== undefined) { - body.Website = updateFields.website as string; - } - if (updateFields.industry !== undefined) { - body.Industry = updateFields.industry as string; - } - if (updateFields.firstname !== undefined) { - body.FirstName = updateFields.firstname as string; - } - if (updateFields.leadSource !== undefined) { - body.LeadSource = updateFields.leadSource as string; - } - if (updateFields.postalCode !== undefined) { - body.PostalCode = updateFields.postalCode as string; - } - if (updateFields.salutation !== undefined) { - body.Salutation = updateFields.salutation as string; - } - if (updateFields.description !== undefined) { - body.Description = updateFields.description as string; - } - if (updateFields.annualRevenue !== undefined) { - body.AnnualRevenue = updateFields.annualRevenue as number; - } - if (updateFields.isUnreadByOwner !== undefined) { - body.IsUnreadByOwner = updateFields.isUnreadByOwner as boolean; - } - if (updateFields.numberOfEmployees !== undefined) { - body.NumberOfEmployees = updateFields.numberOfEmployees as number; - } - if (updateFields.mobilePhone !== undefined) { - body.MobilePhone = updateFields.mobilePhone 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; + let endpoint = '/sobjects/lead'; + let method = 'POST'; + if (operation === 'upsert') { + method = 'PATCH'; + const externalId = this.getNodeParameter('externalId', 0) as string; + const externalIdValue = this.getNodeParameter('externalIdValue', i) as string; + endpoint = `/sobjects/lead/${externalId}/${externalIdValue}`; + if (body[externalId] !== undefined) { + delete body[externalId]; } } + responseData = await salesforceApiRequest.call(this, method, endpoint, body); } - responseData = await salesforceApiRequest.call(this, 'PATCH', `/sobjects/lead/${leadId}`, body); - } - //https://developer.salesforce.com/docs/api-explorer/sobject/Lead/get-lead-id - if (operation === 'get') { - const leadId = this.getNodeParameter('leadId', i) as string; - responseData = await salesforceApiRequest.call(this, 'GET', `/sobjects/lead/${leadId}`); - } - //https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/resources_query.htm - if (operation === 'getAll') { - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - const options = this.getNodeParameter('options', i) as IDataObject; - try { - if (returnAll) { - qs.q = getQuery(options, 'Lead', returnAll) as string; - responseData = await salesforceApiRequestAllItems.call(this, 'records', 'GET', '/query', {}, qs); - } else { - const limit = this.getNodeParameter('limit', i) as number; - qs.q = getQuery(options, 'Lead', returnAll, limit) as string; - responseData = await salesforceApiRequestAllItems.call(this, 'records', 'GET', '/query', {}, qs); + //https://developer.salesforce.com/docs/api-explorer/sobject/Lead/patch-lead-id + if (operation === 'update') { + const leadId = this.getNodeParameter('leadId', i) as string; + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + const body: ILead = {}; + if (!Object.keys(updateFields).length) { + throw new NodeOperationError(this.getNode(), 'You must add at least one update field'); } - } catch (error) { - throw new NodeApiError(this.getNode(), error); - } - } - //https://developer.salesforce.com/docs/api-explorer/sobject/Lead/delete-lead-id - if (operation === 'delete') { - const leadId = this.getNodeParameter('leadId', i) as string; - try { - responseData = await salesforceApiRequest.call(this, 'DELETE', `/sobjects/lead/${leadId}`); - } catch (error) { - throw new NodeApiError(this.getNode(), error); - } - } - //https://developer.salesforce.com/docs/api-explorer/sobject/Lead/get-lead - if (operation === 'getSummary') { - responseData = await salesforceApiRequest.call(this, 'GET', '/sobjects/lead'); - } - //https://developer.salesforce.com/docs/api-explorer/sobject/CampaignMember - if (operation === 'addToCampaign') { - const leadId = this.getNodeParameter('leadId', i) as string; - const campaignId = this.getNodeParameter('campaignId', i) as string; - const options = this.getNodeParameter('options', i) as IDataObject; - const body: ICampaignMember = { - LeadId: leadId, - CampaignId: campaignId, - }; - if (options.status) { - body.Status = options.status as string; - } - responseData = await salesforceApiRequest.call(this, 'POST', '/sobjects/CampaignMember', body); - } - //https://developer.salesforce.com/docs/api-explorer/sobject/Note/post-note - if (operation === 'addNote') { - const leadId = this.getNodeParameter('leadId', i) as string; - const title = this.getNodeParameter('title', i) as string; - const options = this.getNodeParameter('options', i) as IDataObject; - const body: INote = { - Title: title, - ParentId: leadId, - }; - if (options.body) { - body.Body = options.body as string; - } - if (options.owner) { - body.OwnerId = options.owner as string; - } - if (options.isPrivate) { - body.IsPrivate = options.isPrivate as boolean; - } - responseData = await salesforceApiRequest.call(this, 'POST', '/sobjects/note', body); - } - } - if (resource === 'contact') { - //https://developer.salesforce.com/docs/api-explorer/sobject/Contact/post-contact - if (operation === 'create' || operation === 'upsert') { - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const lastname = this.getNodeParameter('lastname', i) as string; - const body: IContact = { - LastName: lastname, - }; - if (additionalFields.fax !== undefined) { - body.Fax = additionalFields.fax as string; - } - if (additionalFields.email !== undefined) { - body.Email = additionalFields.email as string; - } - if (additionalFields.phone !== undefined) { - body.Phone = additionalFields.phone as string; - } - if (additionalFields.title !== undefined) { - body.Title = additionalFields.title as string; - } - if (additionalFields.jigsaw !== undefined) { - body.Jigsaw = additionalFields.jigsaw as string; - } - if (additionalFields.owner !== undefined) { - body.OwnerId = additionalFields.owner as string; - } - if (additionalFields.acconuntId !== undefined) { - body.AccountId = additionalFields.acconuntId as string; - } - if (additionalFields.birthdate !== undefined) { - body.Birthdate = additionalFields.birthdate as string; - } - if (additionalFields.firstName !== undefined) { - body.FirstName = additionalFields.firstName as string; - } - if (additionalFields.homePhone !== undefined) { - body.HomePhone = additionalFields.homePhone as string; - } - if (additionalFields.otherCity !== undefined) { - body.OtherCity = additionalFields.otherCity as string; - } - if (additionalFields.department !== undefined) { - body.Department = additionalFields.department as string; - } - if (additionalFields.leadSource !== undefined) { - body.LeadSource = additionalFields.leadSource as string; - } - if (additionalFields.otherPhone !== undefined) { - body.OtherPhone = additionalFields.otherPhone as string; - } - if (additionalFields.otherState !== undefined) { - body.OtherState = additionalFields.otherState as string; - } - if (additionalFields.salutation !== undefined) { - body.Salutation = additionalFields.salutation as string; - } - if (additionalFields.description !== undefined) { - body.Description = additionalFields.description as string; - } - if (additionalFields.mailingCity !== undefined) { - body.MailingCity = additionalFields.mailingCity as string; - } - if (additionalFields.mobilePhone !== undefined) { - body.MobilePhone = additionalFields.mobilePhone as string; - } - if (additionalFields.otherStreet !== undefined) { - body.OtherStreet = additionalFields.otherStreet as string; - } - if (additionalFields.mailingState !== undefined) { - body.MailingState = additionalFields.mailingState as string; - } - if (additionalFields.otherCountry !== undefined) { - body.OtherCountry = additionalFields.otherCountry as string; - } - if (additionalFields.assistantName !== undefined) { - body.AssistantName = additionalFields.assistantName as string; - } - if (additionalFields.mailingStreet !== undefined) { - body.MailingStreet = additionalFields.mailingStreet as string; - } - if (additionalFields.assistantPhone !== undefined) { - body.AssistantPhone = additionalFields.assistantPhone as string; - } - if (additionalFields.mailingCountry !== undefined) { - body.MailingCountry = additionalFields.mailingCountry as string; - } - if (additionalFields.otherPostalCode !== undefined) { - body.OtherPostalCode = additionalFields.otherPostalCode as string; - } - if (additionalFields.emailBouncedDate !== undefined) { - body.EmailBouncedDate = additionalFields.emailBouncedDate as string; - } - if (additionalFields.mailingPostalCode !== undefined) { - body.MailingPostalCode = additionalFields.mailingPostalCode as string; - } - 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; + if (updateFields.lastname !== undefined) { + body.LastName = updateFields.lastname as string; + } + if (updateFields.company !== undefined) { + body.Company = updateFields.company as string; + } + if (updateFields.email !== undefined) { + body.Email = updateFields.email as string; + } + if (updateFields.city !== undefined) { + body.City = updateFields.city as string; + } + if (updateFields.phone !== undefined) { + body.Phone = updateFields.phone as string; + } + if (updateFields.state !== undefined) { + body.State = updateFields.state as string; + } + if (updateFields.title !== undefined) { + body.Title = updateFields.title as string; + } + if (updateFields.jigsaw !== undefined) { + body.Jigsaw = updateFields.jigsaw as string; + } + if (updateFields.rating !== undefined) { + body.Rating = updateFields.rating as string; + } + if (updateFields.status !== undefined) { + body.Status = updateFields.status as string; + } + if (updateFields.street !== undefined) { + body.Street = updateFields.street as string; + } + if (updateFields.country !== undefined) { + body.Country = updateFields.country as string; + } + if (updateFields.owner !== undefined) { + body.OwnerId = updateFields.owner as string; + } + if (updateFields.website !== undefined) { + body.Website = updateFields.website as string; + } + if (updateFields.industry !== undefined) { + body.Industry = updateFields.industry as string; + } + if (updateFields.firstname !== undefined) { + body.FirstName = updateFields.firstname as string; + } + if (updateFields.leadSource !== undefined) { + body.LeadSource = updateFields.leadSource as string; + } + if (updateFields.postalCode !== undefined) { + body.PostalCode = updateFields.postalCode as string; + } + if (updateFields.salutation !== undefined) { + body.Salutation = updateFields.salutation as string; + } + if (updateFields.description !== undefined) { + body.Description = updateFields.description as string; + } + if (updateFields.annualRevenue !== undefined) { + body.AnnualRevenue = updateFields.annualRevenue as number; + } + if (updateFields.isUnreadByOwner !== undefined) { + body.IsUnreadByOwner = updateFields.isUnreadByOwner as boolean; + } + if (updateFields.numberOfEmployees !== undefined) { + body.NumberOfEmployees = updateFields.numberOfEmployees as number; + } + if (updateFields.mobilePhone !== undefined) { + body.MobilePhone = updateFields.mobilePhone 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/lead/${leadId}`, body); } - let endpoint = '/sobjects/contact'; - let method = 'POST'; - if (operation === 'upsert') { - method = 'PATCH'; - const externalId = this.getNodeParameter('externalId', 0) as string; - const externalIdValue = this.getNodeParameter('externalIdValue', i) as string; - endpoint = `/sobjects/contact/${externalId}/${externalIdValue}`; - if (body[externalId] !== undefined) { - delete body[externalId]; + //https://developer.salesforce.com/docs/api-explorer/sobject/Lead/get-lead-id + if (operation === 'get') { + const leadId = this.getNodeParameter('leadId', i) as string; + responseData = await salesforceApiRequest.call(this, 'GET', `/sobjects/lead/${leadId}`); + } + //https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/resources_query.htm + if (operation === 'getAll') { + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + const options = this.getNodeParameter('options', i) as IDataObject; + try { + if (returnAll) { + qs.q = getQuery(options, 'Lead', returnAll) as string; + responseData = await salesforceApiRequestAllItems.call(this, 'records', 'GET', '/query', {}, qs); + } else { + const limit = this.getNodeParameter('limit', i) as number; + qs.q = getQuery(options, 'Lead', returnAll, limit) as string; + responseData = await salesforceApiRequestAllItems.call(this, 'records', 'GET', '/query', {}, qs); + } + } catch (error) { + throw new NodeApiError(this.getNode(), error); } } - responseData = await salesforceApiRequest.call(this, method, endpoint, body); + //https://developer.salesforce.com/docs/api-explorer/sobject/Lead/delete-lead-id + if (operation === 'delete') { + const leadId = this.getNodeParameter('leadId', i) as string; + try { + responseData = await salesforceApiRequest.call(this, 'DELETE', `/sobjects/lead/${leadId}`); + } catch (error) { + throw new NodeApiError(this.getNode(), error); + } + } + //https://developer.salesforce.com/docs/api-explorer/sobject/Lead/get-lead + if (operation === 'getSummary') { + responseData = await salesforceApiRequest.call(this, 'GET', '/sobjects/lead'); + } + //https://developer.salesforce.com/docs/api-explorer/sobject/CampaignMember + if (operation === 'addToCampaign') { + const leadId = this.getNodeParameter('leadId', i) as string; + const campaignId = this.getNodeParameter('campaignId', i) as string; + const options = this.getNodeParameter('options', i) as IDataObject; + const body: ICampaignMember = { + LeadId: leadId, + CampaignId: campaignId, + }; + if (options.status) { + body.Status = options.status as string; + } + responseData = await salesforceApiRequest.call(this, 'POST', '/sobjects/CampaignMember', body); + } + //https://developer.salesforce.com/docs/api-explorer/sobject/Note/post-note + if (operation === 'addNote') { + const leadId = this.getNodeParameter('leadId', i) as string; + const title = this.getNodeParameter('title', i) as string; + const options = this.getNodeParameter('options', i) as IDataObject; + const body: INote = { + Title: title, + ParentId: leadId, + }; + if (options.body) { + body.Body = options.body as string; + } + if (options.owner) { + body.OwnerId = options.owner as string; + } + if (options.isPrivate) { + body.IsPrivate = options.isPrivate as boolean; + } + responseData = await salesforceApiRequest.call(this, 'POST', '/sobjects/note', body); + } } - //https://developer.salesforce.com/docs/api-explorer/sobject/Contact/patch-contact-id - if (operation === 'update') { - const contactId = this.getNodeParameter('contactId', i) as string; - const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; - const body: IContact = {}; - if (!Object.keys(updateFields).length) { - throw new NodeOperationError(this.getNode(), 'You must add at least one update field'); - } - if (updateFields.lastName !== undefined) { - body.LastName = updateFields.lastName as string; - } - if (updateFields.fax !== undefined) { - body.Fax = updateFields.fax as string; - } - if (updateFields.email !== undefined) { - body.Email = updateFields.email as string; - } - if (updateFields.phone !== undefined) { - body.Phone = updateFields.phone as string; - } - if (updateFields.title !== undefined) { - body.Title = updateFields.title as string; - } - if (updateFields.jigsaw !== undefined) { - body.Jigsaw = updateFields.jigsaw as string; - } - if (updateFields.owner !== undefined) { - body.OwnerId = updateFields.owner as string; - } - if (updateFields.acconuntId !== undefined) { - body.AccountId = updateFields.acconuntId as string; - } - if (updateFields.birthdate !== undefined) { - body.Birthdate = updateFields.birthdate as string; - } - if (updateFields.firstName !== undefined) { - body.FirstName = updateFields.firstName as string; - } - if (updateFields.homePhone !== undefined) { - body.HomePhone = updateFields.homePhone as string; - } - if (updateFields.otherCity !== undefined) { - body.OtherCity = updateFields.otherCity as string; - } - if (updateFields.department !== undefined) { - body.Department = updateFields.department as string; - } - if (updateFields.leadSource !== undefined) { - body.LeadSource = updateFields.leadSource as string; - } - if (updateFields.otherPhone !== undefined) { - body.OtherPhone = updateFields.otherPhone as string; - } - if (updateFields.otherState !== undefined) { - body.OtherState = updateFields.otherState as string; - } - if (updateFields.salutation !== undefined) { - body.Salutation = updateFields.salutation as string; - } - if (updateFields.description !== undefined) { - body.Description = updateFields.description as string; - } - if (updateFields.mailingCity !== undefined) { - body.MailingCity = updateFields.mailingCity as string; - } - if (updateFields.mobilePhone !== undefined) { - body.MobilePhone = updateFields.mobilePhone as string; - } - if (updateFields.otherStreet !== undefined) { - body.OtherStreet = updateFields.otherStreet as string; - } - if (updateFields.mailingState !== undefined) { - body.MailingState = updateFields.mailingState as string; - } - if (updateFields.otherCountry !== undefined) { - body.OtherCountry = updateFields.otherCountry as string; - } - if (updateFields.assistantName !== undefined) { - body.AssistantName = updateFields.assistantName as string; - } - if (updateFields.mailingStreet !== undefined) { - body.MailingStreet = updateFields.mailingStreet as string; - } - if (updateFields.assistantPhone !== undefined) { - body.AssistantPhone = updateFields.assistantPhone as string; - } - if (updateFields.mailingCountry !== undefined) { - body.MailingCountry = updateFields.mailingCountry as string; - } - if (updateFields.otherPostalCode !== undefined) { - body.OtherPostalCode = updateFields.otherPostalCode as string; - } - if (updateFields.emailBouncedDate !== undefined) { - body.EmailBouncedDate = updateFields.emailBouncedDate as string; - } - if (updateFields.mailingPostalCode !== undefined) { - body.MailingPostalCode = updateFields.mailingPostalCode as string; - } - 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; + if (resource === 'contact') { + //https://developer.salesforce.com/docs/api-explorer/sobject/Contact/post-contact + if (operation === 'create' || operation === 'upsert') { + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const lastname = this.getNodeParameter('lastname', i) as string; + const body: IContact = { + LastName: lastname, + }; + if (additionalFields.fax !== undefined) { + body.Fax = additionalFields.fax as string; + } + if (additionalFields.email !== undefined) { + body.Email = additionalFields.email as string; + } + if (additionalFields.phone !== undefined) { + body.Phone = additionalFields.phone as string; + } + if (additionalFields.title !== undefined) { + body.Title = additionalFields.title as string; + } + if (additionalFields.jigsaw !== undefined) { + body.Jigsaw = additionalFields.jigsaw as string; + } + if (additionalFields.owner !== undefined) { + body.OwnerId = additionalFields.owner as string; + } + if (additionalFields.acconuntId !== undefined) { + body.AccountId = additionalFields.acconuntId as string; + } + if (additionalFields.birthdate !== undefined) { + body.Birthdate = additionalFields.birthdate as string; + } + if (additionalFields.firstName !== undefined) { + body.FirstName = additionalFields.firstName as string; + } + if (additionalFields.homePhone !== undefined) { + body.HomePhone = additionalFields.homePhone as string; + } + if (additionalFields.otherCity !== undefined) { + body.OtherCity = additionalFields.otherCity as string; + } + if (additionalFields.department !== undefined) { + body.Department = additionalFields.department as string; + } + if (additionalFields.leadSource !== undefined) { + body.LeadSource = additionalFields.leadSource as string; + } + if (additionalFields.otherPhone !== undefined) { + body.OtherPhone = additionalFields.otherPhone as string; + } + if (additionalFields.otherState !== undefined) { + body.OtherState = additionalFields.otherState as string; + } + if (additionalFields.salutation !== undefined) { + body.Salutation = additionalFields.salutation as string; + } + if (additionalFields.description !== undefined) { + body.Description = additionalFields.description as string; + } + if (additionalFields.mailingCity !== undefined) { + body.MailingCity = additionalFields.mailingCity as string; + } + if (additionalFields.mobilePhone !== undefined) { + body.MobilePhone = additionalFields.mobilePhone as string; + } + if (additionalFields.otherStreet !== undefined) { + body.OtherStreet = additionalFields.otherStreet as string; + } + if (additionalFields.mailingState !== undefined) { + body.MailingState = additionalFields.mailingState as string; + } + if (additionalFields.otherCountry !== undefined) { + body.OtherCountry = additionalFields.otherCountry as string; + } + if (additionalFields.assistantName !== undefined) { + body.AssistantName = additionalFields.assistantName as string; + } + if (additionalFields.mailingStreet !== undefined) { + body.MailingStreet = additionalFields.mailingStreet as string; + } + if (additionalFields.assistantPhone !== undefined) { + body.AssistantPhone = additionalFields.assistantPhone as string; + } + if (additionalFields.mailingCountry !== undefined) { + body.MailingCountry = additionalFields.mailingCountry as string; + } + if (additionalFields.otherPostalCode !== undefined) { + body.OtherPostalCode = additionalFields.otherPostalCode as string; + } + if (additionalFields.emailBouncedDate !== undefined) { + body.EmailBouncedDate = additionalFields.emailBouncedDate as string; + } + if (additionalFields.mailingPostalCode !== undefined) { + body.MailingPostalCode = additionalFields.mailingPostalCode as string; + } + 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, 'PATCH', `/sobjects/contact/${contactId}`, body); - } - //https://developer.salesforce.com/docs/api-explorer/sobject/Contact/get-contact-id - if (operation === 'get') { - const contactId = this.getNodeParameter('contactId', i) as string; - responseData = await salesforceApiRequest.call(this, 'GET', `/sobjects/contact/${contactId}`); - } - //https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/resources_query.htm - if (operation === 'getAll') { - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - const options = this.getNodeParameter('options', i) as IDataObject; - try { - if (returnAll) { - qs.q = getQuery(options, 'Contact', returnAll) as string; - responseData = await salesforceApiRequestAllItems.call(this, 'records', 'GET', '/query', {}, qs); - } else { - const limit = this.getNodeParameter('limit', i) as number; - qs.q = getQuery(options, 'Contact', returnAll, limit) as string; - responseData = await salesforceApiRequestAllItems.call(this, 'records', 'GET', '/query', {}, qs); + let endpoint = '/sobjects/contact'; + let method = 'POST'; + if (operation === 'upsert') { + method = 'PATCH'; + const externalId = this.getNodeParameter('externalId', 0) as string; + const externalIdValue = this.getNodeParameter('externalIdValue', i) as string; + endpoint = `/sobjects/contact/${externalId}/${externalIdValue}`; + if (body[externalId] !== undefined) { + delete body[externalId]; + } } - } catch (error) { - throw new NodeApiError(this.getNode(), error); + responseData = await salesforceApiRequest.call(this, method, endpoint, body); } - } - //https://developer.salesforce.com/docs/api-explorer/sobject/Contact/delete-contact-id - if (operation === 'delete') { - const contactId = this.getNodeParameter('contactId', i) as string; - try { - responseData = await salesforceApiRequest.call(this, 'DELETE', `/sobjects/contact/${contactId}`); - } catch (error) { - throw new NodeApiError(this.getNode(), error); + //https://developer.salesforce.com/docs/api-explorer/sobject/Contact/patch-contact-id + if (operation === 'update') { + const contactId = this.getNodeParameter('contactId', i) as string; + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + const body: IContact = {}; + if (!Object.keys(updateFields).length) { + throw new NodeOperationError(this.getNode(), 'You must add at least one update field'); + } + if (updateFields.lastName !== undefined) { + body.LastName = updateFields.lastName as string; + } + if (updateFields.fax !== undefined) { + body.Fax = updateFields.fax as string; + } + if (updateFields.email !== undefined) { + body.Email = updateFields.email as string; + } + if (updateFields.phone !== undefined) { + body.Phone = updateFields.phone as string; + } + if (updateFields.title !== undefined) { + body.Title = updateFields.title as string; + } + if (updateFields.jigsaw !== undefined) { + body.Jigsaw = updateFields.jigsaw as string; + } + if (updateFields.owner !== undefined) { + body.OwnerId = updateFields.owner as string; + } + if (updateFields.acconuntId !== undefined) { + body.AccountId = updateFields.acconuntId as string; + } + if (updateFields.birthdate !== undefined) { + body.Birthdate = updateFields.birthdate as string; + } + if (updateFields.firstName !== undefined) { + body.FirstName = updateFields.firstName as string; + } + if (updateFields.homePhone !== undefined) { + body.HomePhone = updateFields.homePhone as string; + } + if (updateFields.otherCity !== undefined) { + body.OtherCity = updateFields.otherCity as string; + } + if (updateFields.department !== undefined) { + body.Department = updateFields.department as string; + } + if (updateFields.leadSource !== undefined) { + body.LeadSource = updateFields.leadSource as string; + } + if (updateFields.otherPhone !== undefined) { + body.OtherPhone = updateFields.otherPhone as string; + } + if (updateFields.otherState !== undefined) { + body.OtherState = updateFields.otherState as string; + } + if (updateFields.salutation !== undefined) { + body.Salutation = updateFields.salutation as string; + } + if (updateFields.description !== undefined) { + body.Description = updateFields.description as string; + } + if (updateFields.mailingCity !== undefined) { + body.MailingCity = updateFields.mailingCity as string; + } + if (updateFields.mobilePhone !== undefined) { + body.MobilePhone = updateFields.mobilePhone as string; + } + if (updateFields.otherStreet !== undefined) { + body.OtherStreet = updateFields.otherStreet as string; + } + if (updateFields.mailingState !== undefined) { + body.MailingState = updateFields.mailingState as string; + } + if (updateFields.otherCountry !== undefined) { + body.OtherCountry = updateFields.otherCountry as string; + } + if (updateFields.assistantName !== undefined) { + body.AssistantName = updateFields.assistantName as string; + } + if (updateFields.mailingStreet !== undefined) { + body.MailingStreet = updateFields.mailingStreet as string; + } + if (updateFields.assistantPhone !== undefined) { + body.AssistantPhone = updateFields.assistantPhone as string; + } + if (updateFields.mailingCountry !== undefined) { + body.MailingCountry = updateFields.mailingCountry as string; + } + if (updateFields.otherPostalCode !== undefined) { + body.OtherPostalCode = updateFields.otherPostalCode as string; + } + if (updateFields.emailBouncedDate !== undefined) { + body.EmailBouncedDate = updateFields.emailBouncedDate as string; + } + if (updateFields.mailingPostalCode !== undefined) { + body.MailingPostalCode = updateFields.mailingPostalCode as string; + } + 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 - if (operation === 'getSummary') { - responseData = await salesforceApiRequest.call(this, 'GET', '/sobjects/contact'); - } - //https://developer.salesforce.com/docs/api-explorer/sobject/CampaignMember - if (operation === 'addToCampaign') { - const contactId = this.getNodeParameter('contactId', i) as string; - const campaignId = this.getNodeParameter('campaignId', i) as string; - const options = this.getNodeParameter('options', i) as IDataObject; - const body: ICampaignMember = { - ContactId: contactId, - CampaignId: campaignId, - }; - if (options.status) { - body.Status = options.status as string; + //https://developer.salesforce.com/docs/api-explorer/sobject/Contact/get-contact-id + if (operation === 'get') { + const contactId = this.getNodeParameter('contactId', i) as string; + responseData = await salesforceApiRequest.call(this, 'GET', `/sobjects/contact/${contactId}`); } - responseData = await salesforceApiRequest.call(this, 'POST', '/sobjects/CampaignMember', body); - } - //https://developer.salesforce.com/docs/api-explorer/sobject/Note/post-note - if (operation === 'addNote') { - const contactId = this.getNodeParameter('contactId', i) as string; - const title = this.getNodeParameter('title', i) as string; - const options = this.getNodeParameter('options', i) as IDataObject; - const body: INote = { - Title: title, - ParentId: contactId, - }; - if (options.body !== undefined) { - body.Body = options.body as string; + //https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/resources_query.htm + if (operation === 'getAll') { + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + const options = this.getNodeParameter('options', i) as IDataObject; + try { + if (returnAll) { + qs.q = getQuery(options, 'Contact', returnAll) as string; + responseData = await salesforceApiRequestAllItems.call(this, 'records', 'GET', '/query', {}, qs); + } else { + const limit = this.getNodeParameter('limit', i) as number; + qs.q = getQuery(options, 'Contact', returnAll, limit) as string; + responseData = await salesforceApiRequestAllItems.call(this, 'records', 'GET', '/query', {}, qs); + } + } catch (error) { + throw new NodeApiError(this.getNode(), error); + } } - if (options.owner !== undefined) { - body.OwnerId = options.owner as string; + //https://developer.salesforce.com/docs/api-explorer/sobject/Contact/delete-contact-id + if (operation === 'delete') { + const contactId = this.getNodeParameter('contactId', i) as string; + try { + responseData = await salesforceApiRequest.call(this, 'DELETE', `/sobjects/contact/${contactId}`); + } catch (error) { + throw new NodeApiError(this.getNode(), error); + } } - if (options.isPrivate !== undefined) { - body.IsPrivate = options.isPrivate as boolean; + //https://developer.salesforce.com/docs/api-explorer/sobject/Contact/get-contact + if (operation === 'getSummary') { + responseData = await salesforceApiRequest.call(this, 'GET', '/sobjects/contact'); } + //https://developer.salesforce.com/docs/api-explorer/sobject/CampaignMember + if (operation === 'addToCampaign') { + const contactId = this.getNodeParameter('contactId', i) as string; + const campaignId = this.getNodeParameter('campaignId', i) as string; + const options = this.getNodeParameter('options', i) as IDataObject; + const body: ICampaignMember = { + ContactId: contactId, + CampaignId: campaignId, + }; + if (options.status) { + body.Status = options.status as string; + } + responseData = await salesforceApiRequest.call(this, 'POST', '/sobjects/CampaignMember', body); + } + //https://developer.salesforce.com/docs/api-explorer/sobject/Note/post-note + if (operation === 'addNote') { + const contactId = this.getNodeParameter('contactId', i) as string; + const title = this.getNodeParameter('title', i) as string; + const options = this.getNodeParameter('options', i) as IDataObject; + const body: INote = { + Title: title, + ParentId: contactId, + }; + if (options.body !== undefined) { + body.Body = options.body as string; + } + if (options.owner !== undefined) { + body.OwnerId = options.owner as string; + } + if (options.isPrivate !== undefined) { + body.IsPrivate = options.isPrivate as boolean; + } - responseData = await salesforceApiRequest.call(this, 'POST', '/sobjects/note', body); + responseData = await salesforceApiRequest.call(this, 'POST', '/sobjects/note', body); + } } - } - if (resource === 'customObject') { - if (operation === 'create' || operation === 'upsert') { - 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; + if (resource === 'customObject') { + if (operation === 'create' || operation === 'upsert') { + 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; + } } } - } - let endpoint = `/sobjects/${customObject}`; - let method = 'POST'; - if (operation === 'upsert') { - method = 'PATCH'; - const externalId = this.getNodeParameter('externalId', 0) as string; - const externalIdValue = this.getNodeParameter('externalIdValue', i) as string; - endpoint = `/sobjects/${customObject}/${externalId}/${externalIdValue}`; - if (body[externalId] !== undefined) { - delete body[externalId]; - } - } - responseData = await salesforceApiRequest.call(this, method, endpoint, 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; + let endpoint = `/sobjects/${customObject}`; + let method = 'POST'; + if (operation === 'upsert') { + method = 'PATCH'; + const externalId = this.getNodeParameter('externalId', 0) as string; + const externalIdValue = this.getNodeParameter('externalIdValue', i) as string; + endpoint = `/sobjects/${customObject}/${externalId}/${externalIdValue}`; + if (body[externalId] !== undefined) { + delete body[externalId]; } } + responseData = await salesforceApiRequest.call(this, method, endpoint, body); } - 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; - try { - if (returnAll) { - qs.q = getQuery(options, customObject, returnAll) as string; - responseData = await salesforceApiRequestAllItems.call(this, 'records', 'GET', '/query', {}, qs); - } else { - const limit = this.getNodeParameter('limit', i) as number; - qs.q = getQuery(options, customObject, returnAll, limit) as string; - responseData = await salesforceApiRequestAllItems.call(this, 'records', 'GET', '/query', {}, qs); - } - } catch (error) { - throw new NodeApiError(this.getNode(), error); - } - } - 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 (error) { - throw new NodeApiError(this.getNode(), error); - } - } - } - if (resource === 'opportunity') { - //https://developer.salesforce.com/docs/api-explorer/sobject/Opportunity/post-opportunity - if (operation === 'create' || operation === 'upsert') { - const name = this.getNodeParameter('name', i) as string; - const closeDate = this.getNodeParameter('closeDate', i) as string; - const stageName = this.getNodeParameter('stageName', i) as string; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const body: IOpportunity = { - Name: name, - CloseDate: closeDate, - StageName: stageName, - }; - if (additionalFields.type !== undefined) { - body.Type = additionalFields.type as string; - } - if (additionalFields.ammount !== undefined) { - body.Amount = additionalFields.ammount as number; - } - if (additionalFields.owner !== undefined) { - body.OwnerId = additionalFields.owner as string; - } - if (additionalFields.nextStep !== undefined) { - body.NextStep = additionalFields.nextStep as string; - } - if (additionalFields.accountId !== undefined) { - body.AccountId = additionalFields.accountId as string; - } - if (additionalFields.campaignId !== undefined) { - body.CampaignId = additionalFields.campaignId as string; - } - if (additionalFields.leadSource !== undefined) { - body.LeadSource = additionalFields.leadSource as string; - } - if (additionalFields.description !== undefined) { - body.Description = additionalFields.description as string; - } - if (additionalFields.probability !== undefined) { - body.Probability = additionalFields.probability as number; - } - if (additionalFields.pricebook2Id !== undefined) { - body.Pricebook2Id = additionalFields.pricebook2Id as string; - } - 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; + 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); } - let endpoint = '/sobjects/opportunity'; - let method = 'POST'; - if (operation === 'upsert') { - method = 'PATCH'; - const externalId = this.getNodeParameter('externalId', 0) as string; - const externalIdValue = this.getNodeParameter('externalIdValue', i) as string; - endpoint = `/sobjects/opportunity/${externalId}/${externalIdValue}`; - if (body[externalId] !== undefined) { - delete body[externalId]; + 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; + try { + if (returnAll) { + qs.q = getQuery(options, customObject, returnAll) as string; + responseData = await salesforceApiRequestAllItems.call(this, 'records', 'GET', '/query', {}, qs); + } else { + const limit = this.getNodeParameter('limit', i) as number; + qs.q = getQuery(options, customObject, returnAll, limit) as string; + responseData = await salesforceApiRequestAllItems.call(this, 'records', 'GET', '/query', {}, qs); + } + } catch (error) { + throw new NodeApiError(this.getNode(), error); + } + } + 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 (error) { + throw new NodeApiError(this.getNode(), error); } } - responseData = await salesforceApiRequest.call(this, method, endpoint, body); } - //https://developer.salesforce.com/docs/api-explorer/sobject/Opportunity/post-opportunity - if (operation === 'update') { - const opportunityId = this.getNodeParameter('opportunityId', i) as string; - const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; - const body: IOpportunity = {}; - if (updateFields.name !== undefined) { - body.Name = updateFields.name as string; - } - if (updateFields.closeDate !== undefined) { - body.CloseDate = updateFields.closeDate as string; - } - if (updateFields.stageName !== undefined) { - body.StageName = updateFields.stageName as string; - } - if (updateFields.type !== undefined) { - body.Type = updateFields.type as string; - } - if (updateFields.ammount !== undefined) { - body.Amount = updateFields.ammount as number; - } - if (updateFields.owner !== undefined) { - body.OwnerId = updateFields.owner as string; - } - if (updateFields.nextStep !== undefined) { - body.NextStep = updateFields.nextStep as string; - } - if (updateFields.accountId !== undefined) { - body.AccountId = updateFields.accountId as string; - } - if (updateFields.campaignId !== undefined) { - body.CampaignId = updateFields.campaignId as string; - } - if (updateFields.leadSource !== undefined) { - body.LeadSource = updateFields.leadSource as string; - } - if (updateFields.description !== undefined) { - body.Description = updateFields.description as string; - } - if (updateFields.probability !== undefined) { - body.Probability = updateFields.probability as number; - } - if (updateFields.pricebook2Id !== undefined) { - body.Pricebook2Id = updateFields.pricebook2Id as string; - } - 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; + if (resource === 'opportunity') { + //https://developer.salesforce.com/docs/api-explorer/sobject/Opportunity/post-opportunity + if (operation === 'create' || operation === 'upsert') { + const name = this.getNodeParameter('name', i) as string; + const closeDate = this.getNodeParameter('closeDate', i) as string; + const stageName = this.getNodeParameter('stageName', i) as string; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const body: IOpportunity = { + Name: name, + CloseDate: closeDate, + StageName: stageName, + }; + if (additionalFields.type !== undefined) { + body.Type = additionalFields.type as string; + } + if (additionalFields.ammount !== undefined) { + body.Amount = additionalFields.ammount as number; + } + if (additionalFields.owner !== undefined) { + body.OwnerId = additionalFields.owner as string; + } + if (additionalFields.nextStep !== undefined) { + body.NextStep = additionalFields.nextStep as string; + } + if (additionalFields.accountId !== undefined) { + body.AccountId = additionalFields.accountId as string; + } + if (additionalFields.campaignId !== undefined) { + body.CampaignId = additionalFields.campaignId as string; + } + if (additionalFields.leadSource !== undefined) { + body.LeadSource = additionalFields.leadSource as string; + } + if (additionalFields.description !== undefined) { + body.Description = additionalFields.description as string; + } + if (additionalFields.probability !== undefined) { + body.Probability = additionalFields.probability as number; + } + if (additionalFields.pricebook2Id !== undefined) { + body.Pricebook2Id = additionalFields.pricebook2Id as string; + } + 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, 'PATCH', `/sobjects/opportunity/${opportunityId}`, body); - } - //https://developer.salesforce.com/docs/api-explorer/sobject/Opportunity/get-opportunity-id - if (operation === 'get') { - const opportunityId = this.getNodeParameter('opportunityId', i) as string; - responseData = await salesforceApiRequest.call(this, 'GET', `/sobjects/opportunity/${opportunityId}`); - } - //https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/resources_query.htm - if (operation === 'getAll') { - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - const options = this.getNodeParameter('options', i) as IDataObject; - try { - if (returnAll) { - qs.q = getQuery(options, 'Opportunity', returnAll) as string; - responseData = await salesforceApiRequestAllItems.call(this, 'records', 'GET', '/query', {}, qs); - } else { - const limit = this.getNodeParameter('limit', i) as number; - qs.q = getQuery(options, 'Opportunity', returnAll, limit) as string; - responseData = await salesforceApiRequestAllItems.call(this, 'records', 'GET', '/query', {}, qs); - } - } catch (error) { - throw new NodeApiError(this.getNode(), error); - } - } - //https://developer.salesforce.com/docs/api-explorer/sobject/Opportunity/delete-opportunity-id - if (operation === 'delete') { - const opportunityId = this.getNodeParameter('opportunityId', i) as string; - try { - responseData = await salesforceApiRequest.call(this, 'DELETE', `/sobjects/opportunity/${opportunityId}`); - } catch (error) { - throw new NodeApiError(this.getNode(), error); - } - } - //https://developer.salesforce.com/docs/api-explorer/sobject/Opportunity/get-opportunity - if (operation === 'getSummary') { - responseData = await salesforceApiRequest.call(this, 'GET', '/sobjects/opportunity'); - } - //https://developer.salesforce.com/docs/api-explorer/sobject/Note/post-note - if (operation === 'addNote') { - const opportunityId = this.getNodeParameter('opportunityId', i) as string; - const title = this.getNodeParameter('title', i) as string; - const options = this.getNodeParameter('options', i) as IDataObject; - const body: INote = { - Title: title, - ParentId: opportunityId, - }; - if (options.body !== undefined) { - body.Body = options.body as string; - } - if (options.owner !== undefined) { - body.OwnerId = options.owner as string; - } - if (options.isPrivate !== undefined) { - body.IsPrivate = options.isPrivate as boolean; - } - responseData = await salesforceApiRequest.call(this, 'POST', '/sobjects/note', body); - } - } - if (resource === 'account') { - //https://developer.salesforce.com/docs/api-explorer/sobject/Account/post-account - if (operation === 'create' || operation === 'upsert') { - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const name = this.getNodeParameter('name', i) as string; - const body: IAccount = { - Name: name, - }; - if (additionalFields.fax !== undefined) { - body.Fax = additionalFields.fax as string; - } - if (additionalFields.type !== undefined) { - body.Type = additionalFields.type as string; - } - if (additionalFields.jigsaw !== undefined) { - body.Jigsaw = additionalFields.jigsaw as string; - } - if (additionalFields.phone !== undefined) { - body.Phone = additionalFields.phone as string; - } - if (additionalFields.owner !== undefined) { - body.OwnerId = additionalFields.owner as string; - } - if (additionalFields.sicDesc !== undefined) { - body.SicDesc = additionalFields.sicDesc as string; - } - if (additionalFields.website !== undefined) { - body.Website = additionalFields.website as string; - } - if (additionalFields.industry !== undefined) { - body.Industry = additionalFields.industry as string; - } - if (additionalFields.parentId !== undefined) { - body.ParentId = additionalFields.parentId as string; - } - if (additionalFields.billingCity !== undefined) { - body.BillingCity = additionalFields.billingCity as string; - } - if (additionalFields.description !== undefined) { - body.Description = additionalFields.description as string; - } - if (additionalFields.billingState !== undefined) { - body.BillingState = additionalFields.billingState as string; - } - if (additionalFields.shippingCity !== undefined) { - body.ShippingCity = additionalFields.shippingCity as string; - } - if (additionalFields.accountSource !== undefined) { - body.AccountSource = additionalFields.accountSource as string; - } - if (additionalFields.annualRevenue !== undefined) { - body.AnnualRevenue = additionalFields.annualRevenue as number; - } - if (additionalFields.billingStreet !== undefined) { - body.BillingStreet = additionalFields.billingStreet as string; - } - if (additionalFields.shippingState !== undefined) { - body.ShippingState = additionalFields.shippingState as string; - } - if (additionalFields.billingCountry !== undefined) { - body.BillingCountry = additionalFields.billingCountry as string; - } - if (additionalFields.shippingStreet !== undefined) { - body.ShippingStreet = additionalFields.shippingStreet as string; - } - if (additionalFields.shippingCountry !== undefined) { - body.ShippingCountry = additionalFields.shippingCountry as string; - } - if (additionalFields.billingPostalCode !== undefined) { - body.BillingPostalCode = additionalFields.billingPostalCode as string; - } - if (additionalFields.numberOfEmployees !== undefined) { - body.NumberOfEmployees = additionalFields.numberOfEmployees as string; - } - if (additionalFields.shippingPostalCode !== undefined) { - body.ShippingPostalCode = additionalFields.shippingPostalCode as string; - } - 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; + let endpoint = '/sobjects/opportunity'; + let method = 'POST'; + if (operation === 'upsert') { + method = 'PATCH'; + const externalId = this.getNodeParameter('externalId', 0) as string; + const externalIdValue = this.getNodeParameter('externalIdValue', i) as string; + endpoint = `/sobjects/opportunity/${externalId}/${externalIdValue}`; + if (body[externalId] !== undefined) { + delete body[externalId]; } } + responseData = await salesforceApiRequest.call(this, method, endpoint, body); } - let endpoint = '/sobjects/account'; - let method = 'POST'; - if (operation === 'upsert') { - method = 'PATCH'; - const externalId = this.getNodeParameter('externalId', 0) as string; - const externalIdValue = this.getNodeParameter('externalIdValue', i) as string; - endpoint = `/sobjects/account/${externalId}/${externalIdValue}`; - if (body[externalId] !== undefined) { - delete body[externalId]; + //https://developer.salesforce.com/docs/api-explorer/sobject/Opportunity/post-opportunity + if (operation === 'update') { + const opportunityId = this.getNodeParameter('opportunityId', i) as string; + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + const body: IOpportunity = {}; + if (updateFields.name !== undefined) { + body.Name = updateFields.name as string; } - } - responseData = await salesforceApiRequest.call(this, method, endpoint, body); - } - //https://developer.salesforce.com/docs/api-explorer/sobject/Account/patch-account-id - if (operation === 'update') { - const accountId = this.getNodeParameter('accountId', i) as string; - const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; - const body: IAccount = {}; - if (updateFields.name !== undefined) { - body.Name = updateFields.name as string; - } - if (updateFields.fax !== undefined) { - body.Fax = updateFields.fax as string; - } - if (updateFields.type !== undefined) { - body.Type = updateFields.type as string; - } - if (updateFields.jigsaw !== undefined) { - body.Jigsaw = updateFields.jigsaw as string; - } - if (updateFields.phone !== undefined) { - body.Phone = updateFields.phone as string; - } - if (updateFields.owner !== undefined) { - body.OwnerId = updateFields.owner as string; - } - if (updateFields.sicDesc !== undefined) { - body.SicDesc = updateFields.sicDesc as string; - } - if (updateFields.website !== undefined) { - body.Website = updateFields.website as string; - } - if (updateFields.industry !== undefined) { - body.Industry = updateFields.industry as string; - } - if (updateFields.parentId !== undefined) { - body.ParentId = updateFields.parentId as string; - } - if (updateFields.billingCity !== undefined) { - body.BillingCity = updateFields.billingCity as string; - } - if (updateFields.description !== undefined) { - body.Description = updateFields.description as string; - } - if (updateFields.billingState !== undefined) { - body.BillingState = updateFields.billingState as string; - } - if (updateFields.shippingCity !== undefined) { - body.ShippingCity = updateFields.shippingCity as string; - } - if (updateFields.accountSource !== undefined) { - body.AccountSource = updateFields.accountSource as string; - } - if (updateFields.annualRevenue !== undefined) { - body.AnnualRevenue = updateFields.annualRevenue as number; - } - if (updateFields.billingStreet !== undefined) { - body.BillingStreet = updateFields.billingStreet as string; - } - if (updateFields.shippingState !== undefined) { - body.ShippingState = updateFields.shippingState as string; - } - if (updateFields.billingCountry !== undefined) { - body.BillingCountry = updateFields.billingCountry as string; - } - if (updateFields.shippingStreet !== undefined) { - body.ShippingStreet = updateFields.shippingStreet as string; - } - if (updateFields.shippingCountry !== undefined) { - body.ShippingCountry = updateFields.shippingCountry as string; - } - if (updateFields.billingPostalCode !== undefined) { - body.BillingPostalCode = updateFields.billingPostalCode as string; - } - if (updateFields.numberOfEmployees !== undefined) { - body.NumberOfEmployees = updateFields.numberOfEmployees as string; - } - if (updateFields.shippingPostalCode !== undefined) { - body.ShippingPostalCode = updateFields.shippingPostalCode as string; - } - 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; + if (updateFields.closeDate !== undefined) { + body.CloseDate = updateFields.closeDate as string; + } + if (updateFields.stageName !== undefined) { + body.StageName = updateFields.stageName as string; + } + if (updateFields.type !== undefined) { + body.Type = updateFields.type as string; + } + if (updateFields.ammount !== undefined) { + body.Amount = updateFields.ammount as number; + } + if (updateFields.owner !== undefined) { + body.OwnerId = updateFields.owner as string; + } + if (updateFields.nextStep !== undefined) { + body.NextStep = updateFields.nextStep as string; + } + if (updateFields.accountId !== undefined) { + body.AccountId = updateFields.accountId as string; + } + if (updateFields.campaignId !== undefined) { + body.CampaignId = updateFields.campaignId as string; + } + if (updateFields.leadSource !== undefined) { + body.LeadSource = updateFields.leadSource as string; + } + if (updateFields.description !== undefined) { + body.Description = updateFields.description as string; + } + if (updateFields.probability !== undefined) { + body.Probability = updateFields.probability as number; + } + if (updateFields.pricebook2Id !== undefined) { + body.Pricebook2Id = updateFields.pricebook2Id as string; + } + 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); } - responseData = await salesforceApiRequest.call(this, 'PATCH', `/sobjects/account/${accountId}`, body); - } - //https://developer.salesforce.com/docs/api-explorer/sobject/Account/get-account-id - if (operation === 'get') { - const accountId = this.getNodeParameter('accountId', i) as string; - responseData = await salesforceApiRequest.call(this, 'GET', `/sobjects/account/${accountId}`); - } - //https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/resources_query.htm - if (operation === 'getAll') { - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - const options = this.getNodeParameter('options', i) as IDataObject; - try { - if (returnAll) { - qs.q = getQuery(options, 'Account', returnAll) as string; - responseData = await salesforceApiRequestAllItems.call(this, 'records', 'GET', '/query', {}, qs); - } else { - const limit = this.getNodeParameter('limit', i) as number; - qs.q = getQuery(options, 'Account', returnAll, limit) as string; - responseData = await salesforceApiRequestAllItems.call(this, 'records', 'GET', '/query', {}, qs); + //https://developer.salesforce.com/docs/api-explorer/sobject/Opportunity/get-opportunity-id + if (operation === 'get') { + const opportunityId = this.getNodeParameter('opportunityId', i) as string; + responseData = await salesforceApiRequest.call(this, 'GET', `/sobjects/opportunity/${opportunityId}`); + } + //https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/resources_query.htm + if (operation === 'getAll') { + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + const options = this.getNodeParameter('options', i) as IDataObject; + try { + if (returnAll) { + qs.q = getQuery(options, 'Opportunity', returnAll) as string; + responseData = await salesforceApiRequestAllItems.call(this, 'records', 'GET', '/query', {}, qs); + } else { + const limit = this.getNodeParameter('limit', i) as number; + qs.q = getQuery(options, 'Opportunity', returnAll, limit) as string; + responseData = await salesforceApiRequestAllItems.call(this, 'records', 'GET', '/query', {}, qs); + } + } catch (error) { + throw new NodeApiError(this.getNode(), error); } - } catch (error) { - throw new NodeApiError(this.getNode(), error); + } + //https://developer.salesforce.com/docs/api-explorer/sobject/Opportunity/delete-opportunity-id + if (operation === 'delete') { + const opportunityId = this.getNodeParameter('opportunityId', i) as string; + try { + responseData = await salesforceApiRequest.call(this, 'DELETE', `/sobjects/opportunity/${opportunityId}`); + } catch (error) { + throw new NodeApiError(this.getNode(), error); + } + } + //https://developer.salesforce.com/docs/api-explorer/sobject/Opportunity/get-opportunity + if (operation === 'getSummary') { + responseData = await salesforceApiRequest.call(this, 'GET', '/sobjects/opportunity'); + } + //https://developer.salesforce.com/docs/api-explorer/sobject/Note/post-note + if (operation === 'addNote') { + const opportunityId = this.getNodeParameter('opportunityId', i) as string; + const title = this.getNodeParameter('title', i) as string; + const options = this.getNodeParameter('options', i) as IDataObject; + const body: INote = { + Title: title, + ParentId: opportunityId, + }; + if (options.body !== undefined) { + body.Body = options.body as string; + } + if (options.owner !== undefined) { + body.OwnerId = options.owner as string; + } + if (options.isPrivate !== undefined) { + body.IsPrivate = options.isPrivate as boolean; + } + responseData = await salesforceApiRequest.call(this, 'POST', '/sobjects/note', body); } } - //https://developer.salesforce.com/docs/api-explorer/sobject/Account/delete-account-id - if (operation === 'delete') { - const accountId = this.getNodeParameter('accountId', i) as string; - try { - responseData = await salesforceApiRequest.call(this, 'DELETE', `/sobjects/account/${accountId}`); - } catch (error) { - throw new NodeApiError(this.getNode(), error); - } - } - //https://developer.salesforce.com/docs/api-explorer/sobject/Account/get-account - if (operation === 'getSummary') { - responseData = await salesforceApiRequest.call(this, 'GET', '/sobjects/account'); - } - //https://developer.salesforce.com/docs/api-explorer/sobject/Note/post-note - if (operation === 'addNote') { - const accountId = this.getNodeParameter('accountId', i) as string; - const title = this.getNodeParameter('title', i) as string; - const options = this.getNodeParameter('options', i) as IDataObject; - const body: INote = { - Title: title, - ParentId: accountId, - }; - if (options.body !== undefined) { - body.Body = options.body as string; - } - if (options.owner !== undefined) { - body.OwnerId = options.owner as string; - } - if (options.isPrivate !== undefined) { - body.IsPrivate = options.isPrivate as boolean; - } - responseData = await salesforceApiRequest.call(this, 'POST', '/sobjects/note', body); - } - } - if (resource === 'case') { - //https://developer.salesforce.com/docs/api-explorer/sobject/Case/post-case - if (operation === 'create') { - const type = this.getNodeParameter('type', i) as string; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const body: ICase = { - Type: type, - }; - if (additionalFields.origin !== undefined) { - body.Origin = additionalFields.origin as string; - } - if (additionalFields.reason !== undefined) { - body.Reason = additionalFields.reason as string; - } - if (additionalFields.owner !== undefined) { - body.OwnerId = additionalFields.owner as string; - } - if (additionalFields.subject !== undefined) { - body.Subject = additionalFields.subject as string; - } - if (additionalFields.parentId !== undefined) { - body.ParentId = additionalFields.parentId as string; - } - if (additionalFields.priority !== undefined) { - body.Priority = additionalFields.priority as string; - } - if (additionalFields.accountId !== undefined) { - body.AccountId = additionalFields.accountId as string; - } - if (additionalFields.contactId !== undefined) { - body.ContactId = additionalFields.contactId as string; - } - if (additionalFields.description !== undefined) { - body.Description = additionalFields.description as string; - } - if (additionalFields.isEscalated !== undefined) { - body.IsEscalated = additionalFields.isEscalated as boolean; - } - if (additionalFields.suppliedName !== undefined) { - body.SuppliedName = additionalFields.suppliedName as string; - } - if (additionalFields.suppliedEmail !== undefined) { - body.SuppliedEmail = additionalFields.suppliedEmail as string; - } - if (additionalFields.suppliedPhone !== undefined) { - body.SuppliedPhone = additionalFields.suppliedPhone as string; - } - if (additionalFields.suppliedCompany !== undefined) { - body.SuppliedCompany = additionalFields.suppliedCompany 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; + if (resource === 'account') { + //https://developer.salesforce.com/docs/api-explorer/sobject/Account/post-account + if (operation === 'create' || operation === 'upsert') { + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const name = this.getNodeParameter('name', i) as string; + const body: IAccount = { + Name: name, + }; + if (additionalFields.fax !== undefined) { + body.Fax = additionalFields.fax as string; + } + if (additionalFields.type !== undefined) { + body.Type = additionalFields.type as string; + } + if (additionalFields.jigsaw !== undefined) { + body.Jigsaw = additionalFields.jigsaw as string; + } + if (additionalFields.phone !== undefined) { + body.Phone = additionalFields.phone as string; + } + if (additionalFields.owner !== undefined) { + body.OwnerId = additionalFields.owner as string; + } + if (additionalFields.sicDesc !== undefined) { + body.SicDesc = additionalFields.sicDesc as string; + } + if (additionalFields.website !== undefined) { + body.Website = additionalFields.website as string; + } + if (additionalFields.industry !== undefined) { + body.Industry = additionalFields.industry as string; + } + if (additionalFields.parentId !== undefined) { + body.ParentId = additionalFields.parentId as string; + } + if (additionalFields.billingCity !== undefined) { + body.BillingCity = additionalFields.billingCity as string; + } + if (additionalFields.description !== undefined) { + body.Description = additionalFields.description as string; + } + if (additionalFields.billingState !== undefined) { + body.BillingState = additionalFields.billingState as string; + } + if (additionalFields.shippingCity !== undefined) { + body.ShippingCity = additionalFields.shippingCity as string; + } + if (additionalFields.accountSource !== undefined) { + body.AccountSource = additionalFields.accountSource as string; + } + if (additionalFields.annualRevenue !== undefined) { + body.AnnualRevenue = additionalFields.annualRevenue as number; + } + if (additionalFields.billingStreet !== undefined) { + body.BillingStreet = additionalFields.billingStreet as string; + } + if (additionalFields.shippingState !== undefined) { + body.ShippingState = additionalFields.shippingState as string; + } + if (additionalFields.billingCountry !== undefined) { + body.BillingCountry = additionalFields.billingCountry as string; + } + if (additionalFields.shippingStreet !== undefined) { + body.ShippingStreet = additionalFields.shippingStreet as string; + } + if (additionalFields.shippingCountry !== undefined) { + body.ShippingCountry = additionalFields.shippingCountry as string; + } + if (additionalFields.billingPostalCode !== undefined) { + body.BillingPostalCode = additionalFields.billingPostalCode as string; + } + if (additionalFields.numberOfEmployees !== undefined) { + body.NumberOfEmployees = additionalFields.numberOfEmployees as string; + } + if (additionalFields.shippingPostalCode !== undefined) { + body.ShippingPostalCode = additionalFields.shippingPostalCode as string; + } + 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/case', body); - } - //https://developer.salesforce.com/docs/api-explorer/sobject/Case/patch-case-id - if (operation === 'update') { - const caseId = this.getNodeParameter('caseId', i) as string; - const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; - const body: ICase = {}; - if (updateFields.type !== undefined) { - body.Type = updateFields.type as string; - } - if (updateFields.origin !== undefined) { - body.Origin = updateFields.origin as string; - } - if (updateFields.reason !== undefined) { - body.Reason = updateFields.reason as string; - } - if (updateFields.owner !== undefined) { - body.OwnerId = updateFields.owner as string; - } - if (updateFields.subject !== undefined) { - body.Subject = updateFields.subject as string; - } - if (updateFields.parentId !== undefined) { - body.ParentId = updateFields.parentId as string; - } - if (updateFields.priority !== undefined) { - body.Priority = updateFields.priority as string; - } - if (updateFields.accountId !== undefined) { - body.AccountId = updateFields.accountId as string; - } - if (updateFields.contactId !== undefined) { - body.ContactId = updateFields.contactId as string; - } - if (updateFields.description !== undefined) { - body.Description = updateFields.description as string; - } - if (updateFields.isEscalated !== undefined) { - body.IsEscalated = updateFields.isEscalated as boolean; - } - if (updateFields.suppliedName !== undefined) { - body.SuppliedName = updateFields.suppliedName as string; - } - if (updateFields.suppliedEmail !== undefined) { - body.SuppliedEmail = updateFields.suppliedEmail as string; - } - if (updateFields.suppliedPhone !== undefined) { - body.SuppliedPhone = updateFields.suppliedPhone as string; - } - if (updateFields.suppliedCompany !== undefined) { - body.SuppliedCompany = updateFields.suppliedCompany 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; + let endpoint = '/sobjects/account'; + let method = 'POST'; + if (operation === 'upsert') { + method = 'PATCH'; + const externalId = this.getNodeParameter('externalId', 0) as string; + const externalIdValue = this.getNodeParameter('externalIdValue', i) as string; + endpoint = `/sobjects/account/${externalId}/${externalIdValue}`; + if (body[externalId] !== undefined) { + delete body[externalId]; } } + responseData = await salesforceApiRequest.call(this, method, endpoint, body); } - responseData = await salesforceApiRequest.call(this, 'PATCH', `/sobjects/case/${caseId}`, body); - } - //https://developer.salesforce.com/docs/api-explorer/sobject/Case/get-case-id - if (operation === 'get') { - const caseId = this.getNodeParameter('caseId', i) as string; - responseData = await salesforceApiRequest.call(this, 'GET', `/sobjects/case/${caseId}`); - } - //https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/resources_query.htm - if (operation === 'getAll') { - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - const options = this.getNodeParameter('options', i) as IDataObject; - try { - if (returnAll) { - qs.q = getQuery(options, 'Case', returnAll) as string; - responseData = await salesforceApiRequestAllItems.call(this, 'records', 'GET', '/query', {}, qs); - } else { - const limit = this.getNodeParameter('limit', i) as number; - qs.q = getQuery(options, 'Case', returnAll, limit) as string; - responseData = await salesforceApiRequestAllItems.call(this, 'records', 'GET', '/query', {}, qs); + //https://developer.salesforce.com/docs/api-explorer/sobject/Account/patch-account-id + if (operation === 'update') { + const accountId = this.getNodeParameter('accountId', i) as string; + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + const body: IAccount = {}; + if (updateFields.name !== undefined) { + body.Name = updateFields.name as string; } - } catch (error) { - throw new NodeApiError(this.getNode(), error); - } - } - //https://developer.salesforce.com/docs/api-explorer/sobject/Case/delete-case-id - if (operation === 'delete') { - const caseId = this.getNodeParameter('caseId', i) as string; - try { - responseData = await salesforceApiRequest.call(this, 'DELETE', `/sobjects/case/${caseId}`); - } catch (error) { - throw new NodeApiError(this.getNode(), error); - } - } - //https://developer.salesforce.com/docs/api-explorer/sobject/Case/get-case - if (operation === 'getSummary') { - responseData = await salesforceApiRequest.call(this, 'GET', '/sobjects/case'); - } - //https://developer.salesforce.com/docs/api-explorer/sobject/CaseComment/post-casecomment - if (operation === 'addComment') { - const caseId = this.getNodeParameter('caseId', i) as string; - const options = this.getNodeParameter('options', i) as IDataObject; - const body: ICaseComment = { - ParentId: caseId, - }; - if (options.commentBody !== undefined) { - body.CommentBody = options.commentBody as string; - } - if (options.isPublished !== undefined) { - body.IsPublished = options.isPublished as boolean; - } - responseData = await salesforceApiRequest.call(this, 'POST', '/sobjects/casecomment', body); - } - } - if (resource === 'task') { - //https://developer.salesforce.com/docs/api-explorer/sobject/Task/post-task - if (operation === 'create') { - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const status = this.getNodeParameter('status', i) as string; - const body: ITask = { - Status: status, - }; - if (additionalFields.whoId !== undefined) { - body.WhoId = additionalFields.whoId as string; - } - if (additionalFields.whatId !== undefined) { - body.WhatId = additionalFields.whatId as string; - } - if (additionalFields.owner !== undefined) { - body.OwnerId = additionalFields.owner as string; - } - if (additionalFields.subject !== undefined) { - body.Subject = additionalFields.subject as string; - } - if (additionalFields.callType !== undefined) { - body.CallType = additionalFields.callType as string; - } - if (additionalFields.priority !== undefined) { - body.Priority = additionalFields.priority as string; - } - if (additionalFields.callObject !== undefined) { - body.CallObject = additionalFields.callObject as string; - } - if (additionalFields.description !== undefined) { - body.Description = additionalFields.description as string; - } - if (additionalFields.activityDate !== undefined) { - body.ActivityDate = additionalFields.activityDate as string; - } - if (additionalFields.isReminderSet !== undefined) { - body.IsReminderSet = additionalFields.isReminderSet as boolean; - } - if (additionalFields.recurrenceType !== undefined) { - body.RecurrenceType = additionalFields.recurrenceType as string; - } - if (additionalFields.callDisposition !== undefined) { - body.CallDisposition = additionalFields.callDisposition as string; - } - if (additionalFields.reminderDateTime !== undefined) { - body.ReminderDateTime = additionalFields.reminderDateTime as string; - } - if (additionalFields.recurrenceInstance !== undefined) { - body.RecurrenceInstance = additionalFields.recurrenceInstance as string; - } - if (additionalFields.recurrenceInterval !== undefined) { - body.RecurrenceInterval = additionalFields.recurrenceInterval as number; - } - if (additionalFields.recurrenceDayOfMonth !== undefined) { - body.RecurrenceDayOfMonth = additionalFields.recurrenceDayOfMonth as number; - } - if (additionalFields.callDurationInSeconds !== undefined) { - body.CallDurationInSeconds = additionalFields.callDurationInSeconds as number; - } - if (additionalFields.recurrenceEndDateOnly !== undefined) { - body.RecurrenceEndDateOnly = additionalFields.recurrenceEndDateOnly as string; - } - if (additionalFields.recurrenceMonthOfYear !== undefined) { - body.RecurrenceMonthOfYear = additionalFields.recurrenceMonthOfYear as string; - } - if (additionalFields.recurrenceDayOfWeekMask !== undefined) { - body.RecurrenceDayOfWeekMask = additionalFields.recurrenceDayOfWeekMask as string; - } - if (additionalFields.recurrenceStartDateOnly !== undefined) { - body.RecurrenceStartDateOnly = additionalFields.recurrenceStartDateOnly as string; - } - if (additionalFields.recurrenceTimeZoneSidKey !== undefined) { - body.RecurrenceTimeZoneSidKey = additionalFields.recurrenceTimeZoneSidKey as string; - } - 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; + if (updateFields.fax !== undefined) { + body.Fax = updateFields.fax as string; + } + if (updateFields.type !== undefined) { + body.Type = updateFields.type as string; + } + if (updateFields.jigsaw !== undefined) { + body.Jigsaw = updateFields.jigsaw as string; + } + if (updateFields.phone !== undefined) { + body.Phone = updateFields.phone as string; + } + if (updateFields.owner !== undefined) { + body.OwnerId = updateFields.owner as string; + } + if (updateFields.sicDesc !== undefined) { + body.SicDesc = updateFields.sicDesc as string; + } + if (updateFields.website !== undefined) { + body.Website = updateFields.website as string; + } + if (updateFields.industry !== undefined) { + body.Industry = updateFields.industry as string; + } + if (updateFields.parentId !== undefined) { + body.ParentId = updateFields.parentId as string; + } + if (updateFields.billingCity !== undefined) { + body.BillingCity = updateFields.billingCity as string; + } + if (updateFields.description !== undefined) { + body.Description = updateFields.description as string; + } + if (updateFields.billingState !== undefined) { + body.BillingState = updateFields.billingState as string; + } + if (updateFields.shippingCity !== undefined) { + body.ShippingCity = updateFields.shippingCity as string; + } + if (updateFields.accountSource !== undefined) { + body.AccountSource = updateFields.accountSource as string; + } + if (updateFields.annualRevenue !== undefined) { + body.AnnualRevenue = updateFields.annualRevenue as number; + } + if (updateFields.billingStreet !== undefined) { + body.BillingStreet = updateFields.billingStreet as string; + } + if (updateFields.shippingState !== undefined) { + body.ShippingState = updateFields.shippingState as string; + } + if (updateFields.billingCountry !== undefined) { + body.BillingCountry = updateFields.billingCountry as string; + } + if (updateFields.shippingStreet !== undefined) { + body.ShippingStreet = updateFields.shippingStreet as string; + } + if (updateFields.shippingCountry !== undefined) { + body.ShippingCountry = updateFields.shippingCountry as string; + } + if (updateFields.billingPostalCode !== undefined) { + body.BillingPostalCode = updateFields.billingPostalCode as string; + } + if (updateFields.numberOfEmployees !== undefined) { + body.NumberOfEmployees = updateFields.numberOfEmployees as string; + } + if (updateFields.shippingPostalCode !== undefined) { + body.ShippingPostalCode = updateFields.shippingPostalCode as string; + } + 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 + if (operation === 'get') { + const accountId = this.getNodeParameter('accountId', i) as string; + responseData = await salesforceApiRequest.call(this, 'GET', `/sobjects/account/${accountId}`); + } + //https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/resources_query.htm + if (operation === 'getAll') { + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + const options = this.getNodeParameter('options', i) as IDataObject; + try { + if (returnAll) { + qs.q = getQuery(options, 'Account', returnAll) as string; + responseData = await salesforceApiRequestAllItems.call(this, 'records', 'GET', '/query', {}, qs); + } else { + const limit = this.getNodeParameter('limit', i) as number; + qs.q = getQuery(options, 'Account', returnAll, limit) as string; + responseData = await salesforceApiRequestAllItems.call(this, 'records', 'GET', '/query', {}, qs); + } + } catch (error) { + throw new NodeApiError(this.getNode(), error); + } + } + //https://developer.salesforce.com/docs/api-explorer/sobject/Account/delete-account-id + if (operation === 'delete') { + const accountId = this.getNodeParameter('accountId', i) as string; + try { + responseData = await salesforceApiRequest.call(this, 'DELETE', `/sobjects/account/${accountId}`); + } catch (error) { + throw new NodeApiError(this.getNode(), error); + } + } + //https://developer.salesforce.com/docs/api-explorer/sobject/Account/get-account + if (operation === 'getSummary') { + responseData = await salesforceApiRequest.call(this, 'GET', '/sobjects/account'); + } + //https://developer.salesforce.com/docs/api-explorer/sobject/Note/post-note + if (operation === 'addNote') { + const accountId = this.getNodeParameter('accountId', i) as string; + const title = this.getNodeParameter('title', i) as string; + const options = this.getNodeParameter('options', i) as IDataObject; + const body: INote = { + Title: title, + ParentId: accountId, + }; + if (options.body !== undefined) { + body.Body = options.body as string; + } + if (options.owner !== undefined) { + body.OwnerId = options.owner as string; + } + if (options.isPrivate !== undefined) { + body.IsPrivate = options.isPrivate as boolean; + } + responseData = await salesforceApiRequest.call(this, 'POST', '/sobjects/note', body); } - responseData = await salesforceApiRequest.call(this, 'POST', '/sobjects/task', body); } - //https://developer.salesforce.com/docs/api-explorer/sobject/Task/patch-task-id - if (operation === 'update') { - const taskId = this.getNodeParameter('taskId', i) as string; - const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; - const body: ITask = {}; - if (updateFields.whoId !== undefined) { - body.WhoId = updateFields.whoId as string; - } - if (updateFields.status !== undefined) { - body.Status = updateFields.status as string; - } - if (updateFields.whatId !== undefined) { - body.WhatId = updateFields.whatId as string; - } - if (updateFields.owner !== undefined) { - body.OwnerId = updateFields.owner as string; - } - if (updateFields.subject !== undefined) { - body.Subject = updateFields.subject as string; - } - if (updateFields.callType !== undefined) { - body.CallType = updateFields.callType as string; - } - if (updateFields.priority !== undefined) { - body.Priority = updateFields.priority as string; - } - if (updateFields.callObject !== undefined) { - body.CallObject = updateFields.callObject as string; - } - if (updateFields.description !== undefined) { - body.Description = updateFields.description as string; - } - if (updateFields.activityDate !== undefined) { - body.ActivityDate = updateFields.activityDate as string; - } - if (updateFields.isReminderSet !== undefined) { - body.IsReminderSet = updateFields.isReminderSet as boolean; - } - if (updateFields.recurrenceType !== undefined) { - body.RecurrenceType = updateFields.recurrenceType as string; - } - if (updateFields.callDisposition !== undefined) { - body.CallDisposition = updateFields.callDisposition as string; - } - if (updateFields.reminderDateTime !== undefined) { - body.ReminderDateTime = updateFields.reminderDateTime as string; - } - if (updateFields.recurrenceInstance !== undefined) { - body.RecurrenceInstance = updateFields.recurrenceInstance as string; - } - if (updateFields.recurrenceInterval !== undefined) { - body.RecurrenceInterval = updateFields.recurrenceInterval as number; - } - if (updateFields.recurrenceDayOfMonth !== undefined) { - body.RecurrenceDayOfMonth = updateFields.recurrenceDayOfMonth as number; - } - if (updateFields.callDurationInSeconds !== undefined) { - body.CallDurationInSeconds = updateFields.callDurationInSeconds as number; - } - if (updateFields.recurrenceEndDateOnly !== undefined) { - body.RecurrenceEndDateOnly = updateFields.recurrenceEndDateOnly as string; - } - if (updateFields.recurrenceMonthOfYear !== undefined) { - body.RecurrenceMonthOfYear = updateFields.recurrenceMonthOfYear as string; - } - if (updateFields.recurrenceDayOfWeekMask !== undefined) { - body.RecurrenceDayOfWeekMask = updateFields.recurrenceDayOfWeekMask as string; - } - if (updateFields.recurrenceStartDateOnly !== undefined) { - body.RecurrenceStartDateOnly = updateFields.recurrenceStartDateOnly as string; - } - if (updateFields.recurrenceTimeZoneSidKey !== undefined) { - body.RecurrenceTimeZoneSidKey = updateFields.recurrenceTimeZoneSidKey as string; - } - 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; + if (resource === 'case') { + //https://developer.salesforce.com/docs/api-explorer/sobject/Case/post-case + if (operation === 'create') { + const type = this.getNodeParameter('type', i) as string; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const body: ICase = { + Type: type, + }; + if (additionalFields.origin !== undefined) { + body.Origin = additionalFields.origin as string; + } + if (additionalFields.reason !== undefined) { + body.Reason = additionalFields.reason as string; + } + if (additionalFields.owner !== undefined) { + body.OwnerId = additionalFields.owner as string; + } + if (additionalFields.subject !== undefined) { + body.Subject = additionalFields.subject as string; + } + if (additionalFields.parentId !== undefined) { + body.ParentId = additionalFields.parentId as string; + } + if (additionalFields.priority !== undefined) { + body.Priority = additionalFields.priority as string; + } + if (additionalFields.accountId !== undefined) { + body.AccountId = additionalFields.accountId as string; + } + if (additionalFields.contactId !== undefined) { + body.ContactId = additionalFields.contactId as string; + } + if (additionalFields.description !== undefined) { + body.Description = additionalFields.description as string; + } + if (additionalFields.isEscalated !== undefined) { + body.IsEscalated = additionalFields.isEscalated as boolean; + } + if (additionalFields.suppliedName !== undefined) { + body.SuppliedName = additionalFields.suppliedName as string; + } + if (additionalFields.suppliedEmail !== undefined) { + body.SuppliedEmail = additionalFields.suppliedEmail as string; + } + if (additionalFields.suppliedPhone !== undefined) { + body.SuppliedPhone = additionalFields.suppliedPhone as string; + } + if (additionalFields.suppliedCompany !== undefined) { + body.SuppliedCompany = additionalFields.suppliedCompany 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/case', body); } - responseData = await salesforceApiRequest.call(this, 'PATCH', `/sobjects/task/${taskId}`, body); - } - //https://developer.salesforce.com/docs/api-explorer/sobject/Task/get-task-id - if (operation === 'get') { - const taskId = this.getNodeParameter('taskId', i) as string; - responseData = await salesforceApiRequest.call(this, 'GET', `/sobjects/task/${taskId}`); - } - //https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/resources_query.htm - if (operation === 'getAll') { - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - const options = this.getNodeParameter('options', i) as IDataObject; - try { - if (returnAll) { - qs.q = getQuery(options, 'Task', returnAll) as string; - responseData = await salesforceApiRequestAllItems.call(this, 'records', 'GET', '/query', {}, qs); - } else { - const limit = this.getNodeParameter('limit', i) as number; - qs.q = getQuery(options, 'Task', returnAll, limit) as string; - responseData = await salesforceApiRequestAllItems.call(this, 'records', 'GET', '/query', {}, qs); + //https://developer.salesforce.com/docs/api-explorer/sobject/Case/patch-case-id + if (operation === 'update') { + const caseId = this.getNodeParameter('caseId', i) as string; + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + const body: ICase = {}; + if (updateFields.type !== undefined) { + body.Type = updateFields.type as string; } - } catch (error) { - throw new NodeApiError(this.getNode(), error); + if (updateFields.origin !== undefined) { + body.Origin = updateFields.origin as string; + } + if (updateFields.reason !== undefined) { + body.Reason = updateFields.reason as string; + } + if (updateFields.owner !== undefined) { + body.OwnerId = updateFields.owner as string; + } + if (updateFields.subject !== undefined) { + body.Subject = updateFields.subject as string; + } + if (updateFields.parentId !== undefined) { + body.ParentId = updateFields.parentId as string; + } + if (updateFields.priority !== undefined) { + body.Priority = updateFields.priority as string; + } + if (updateFields.accountId !== undefined) { + body.AccountId = updateFields.accountId as string; + } + if (updateFields.contactId !== undefined) { + body.ContactId = updateFields.contactId as string; + } + if (updateFields.description !== undefined) { + body.Description = updateFields.description as string; + } + if (updateFields.isEscalated !== undefined) { + body.IsEscalated = updateFields.isEscalated as boolean; + } + if (updateFields.suppliedName !== undefined) { + body.SuppliedName = updateFields.suppliedName as string; + } + if (updateFields.suppliedEmail !== undefined) { + body.SuppliedEmail = updateFields.suppliedEmail as string; + } + if (updateFields.suppliedPhone !== undefined) { + body.SuppliedPhone = updateFields.suppliedPhone as string; + } + if (updateFields.suppliedCompany !== undefined) { + body.SuppliedCompany = updateFields.suppliedCompany 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/case/${caseId}`, body); + } + //https://developer.salesforce.com/docs/api-explorer/sobject/Case/get-case-id + if (operation === 'get') { + const caseId = this.getNodeParameter('caseId', i) as string; + responseData = await salesforceApiRequest.call(this, 'GET', `/sobjects/case/${caseId}`); + } + //https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/resources_query.htm + if (operation === 'getAll') { + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + const options = this.getNodeParameter('options', i) as IDataObject; + try { + if (returnAll) { + qs.q = getQuery(options, 'Case', returnAll) as string; + responseData = await salesforceApiRequestAllItems.call(this, 'records', 'GET', '/query', {}, qs); + } else { + const limit = this.getNodeParameter('limit', i) as number; + qs.q = getQuery(options, 'Case', returnAll, limit) as string; + responseData = await salesforceApiRequestAllItems.call(this, 'records', 'GET', '/query', {}, qs); + } + } catch (error) { + throw new NodeApiError(this.getNode(), error); + } + } + //https://developer.salesforce.com/docs/api-explorer/sobject/Case/delete-case-id + if (operation === 'delete') { + const caseId = this.getNodeParameter('caseId', i) as string; + try { + responseData = await salesforceApiRequest.call(this, 'DELETE', `/sobjects/case/${caseId}`); + } catch (error) { + throw new NodeApiError(this.getNode(), error); + } + } + //https://developer.salesforce.com/docs/api-explorer/sobject/Case/get-case + if (operation === 'getSummary') { + responseData = await salesforceApiRequest.call(this, 'GET', '/sobjects/case'); + } + //https://developer.salesforce.com/docs/api-explorer/sobject/CaseComment/post-casecomment + if (operation === 'addComment') { + const caseId = this.getNodeParameter('caseId', i) as string; + const options = this.getNodeParameter('options', i) as IDataObject; + const body: ICaseComment = { + ParentId: caseId, + }; + if (options.commentBody !== undefined) { + body.CommentBody = options.commentBody as string; + } + if (options.isPublished !== undefined) { + body.IsPublished = options.isPublished as boolean; + } + responseData = await salesforceApiRequest.call(this, 'POST', '/sobjects/casecomment', body); } } - //https://developer.salesforce.com/docs/api-explorer/sobject/Task/delete-task-id - if (operation === 'delete') { - const taskId = this.getNodeParameter('taskId', i) as string; - try { - responseData = await salesforceApiRequest.call(this, 'DELETE', `/sobjects/task/${taskId}`); - } catch (error) { - throw new NodeApiError(this.getNode(), error); + if (resource === 'task') { + //https://developer.salesforce.com/docs/api-explorer/sobject/Task/post-task + if (operation === 'create') { + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const status = this.getNodeParameter('status', i) as string; + const body: ITask = { + Status: status, + }; + if (additionalFields.whoId !== undefined) { + body.WhoId = additionalFields.whoId as string; + } + if (additionalFields.whatId !== undefined) { + body.WhatId = additionalFields.whatId as string; + } + if (additionalFields.owner !== undefined) { + body.OwnerId = additionalFields.owner as string; + } + if (additionalFields.subject !== undefined) { + body.Subject = additionalFields.subject as string; + } + if (additionalFields.callType !== undefined) { + body.CallType = additionalFields.callType as string; + } + if (additionalFields.priority !== undefined) { + body.Priority = additionalFields.priority as string; + } + if (additionalFields.callObject !== undefined) { + body.CallObject = additionalFields.callObject as string; + } + if (additionalFields.description !== undefined) { + body.Description = additionalFields.description as string; + } + if (additionalFields.activityDate !== undefined) { + body.ActivityDate = additionalFields.activityDate as string; + } + if (additionalFields.isReminderSet !== undefined) { + body.IsReminderSet = additionalFields.isReminderSet as boolean; + } + if (additionalFields.recurrenceType !== undefined) { + body.RecurrenceType = additionalFields.recurrenceType as string; + } + if (additionalFields.callDisposition !== undefined) { + body.CallDisposition = additionalFields.callDisposition as string; + } + if (additionalFields.reminderDateTime !== undefined) { + body.ReminderDateTime = additionalFields.reminderDateTime as string; + } + if (additionalFields.recurrenceInstance !== undefined) { + body.RecurrenceInstance = additionalFields.recurrenceInstance as string; + } + if (additionalFields.recurrenceInterval !== undefined) { + body.RecurrenceInterval = additionalFields.recurrenceInterval as number; + } + if (additionalFields.recurrenceDayOfMonth !== undefined) { + body.RecurrenceDayOfMonth = additionalFields.recurrenceDayOfMonth as number; + } + if (additionalFields.callDurationInSeconds !== undefined) { + body.CallDurationInSeconds = additionalFields.callDurationInSeconds as number; + } + if (additionalFields.recurrenceEndDateOnly !== undefined) { + body.RecurrenceEndDateOnly = additionalFields.recurrenceEndDateOnly as string; + } + if (additionalFields.recurrenceMonthOfYear !== undefined) { + body.RecurrenceMonthOfYear = additionalFields.recurrenceMonthOfYear as string; + } + if (additionalFields.recurrenceDayOfWeekMask !== undefined) { + body.RecurrenceDayOfWeekMask = additionalFields.recurrenceDayOfWeekMask as string; + } + if (additionalFields.recurrenceStartDateOnly !== undefined) { + body.RecurrenceStartDateOnly = additionalFields.recurrenceStartDateOnly as string; + } + if (additionalFields.recurrenceTimeZoneSidKey !== undefined) { + body.RecurrenceTimeZoneSidKey = additionalFields.recurrenceTimeZoneSidKey as string; + } + 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 + if (operation === 'update') { + const taskId = this.getNodeParameter('taskId', i) as string; + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + const body: ITask = {}; + if (updateFields.whoId !== undefined) { + body.WhoId = updateFields.whoId as string; + } + if (updateFields.status !== undefined) { + body.Status = updateFields.status as string; + } + if (updateFields.whatId !== undefined) { + body.WhatId = updateFields.whatId as string; + } + if (updateFields.owner !== undefined) { + body.OwnerId = updateFields.owner as string; + } + if (updateFields.subject !== undefined) { + body.Subject = updateFields.subject as string; + } + if (updateFields.callType !== undefined) { + body.CallType = updateFields.callType as string; + } + if (updateFields.priority !== undefined) { + body.Priority = updateFields.priority as string; + } + if (updateFields.callObject !== undefined) { + body.CallObject = updateFields.callObject as string; + } + if (updateFields.description !== undefined) { + body.Description = updateFields.description as string; + } + if (updateFields.activityDate !== undefined) { + body.ActivityDate = updateFields.activityDate as string; + } + if (updateFields.isReminderSet !== undefined) { + body.IsReminderSet = updateFields.isReminderSet as boolean; + } + if (updateFields.recurrenceType !== undefined) { + body.RecurrenceType = updateFields.recurrenceType as string; + } + if (updateFields.callDisposition !== undefined) { + body.CallDisposition = updateFields.callDisposition as string; + } + if (updateFields.reminderDateTime !== undefined) { + body.ReminderDateTime = updateFields.reminderDateTime as string; + } + if (updateFields.recurrenceInstance !== undefined) { + body.RecurrenceInstance = updateFields.recurrenceInstance as string; + } + if (updateFields.recurrenceInterval !== undefined) { + body.RecurrenceInterval = updateFields.recurrenceInterval as number; + } + if (updateFields.recurrenceDayOfMonth !== undefined) { + body.RecurrenceDayOfMonth = updateFields.recurrenceDayOfMonth as number; + } + if (updateFields.callDurationInSeconds !== undefined) { + body.CallDurationInSeconds = updateFields.callDurationInSeconds as number; + } + if (updateFields.recurrenceEndDateOnly !== undefined) { + body.RecurrenceEndDateOnly = updateFields.recurrenceEndDateOnly as string; + } + if (updateFields.recurrenceMonthOfYear !== undefined) { + body.RecurrenceMonthOfYear = updateFields.recurrenceMonthOfYear as string; + } + if (updateFields.recurrenceDayOfWeekMask !== undefined) { + body.RecurrenceDayOfWeekMask = updateFields.recurrenceDayOfWeekMask as string; + } + if (updateFields.recurrenceStartDateOnly !== undefined) { + body.RecurrenceStartDateOnly = updateFields.recurrenceStartDateOnly as string; + } + if (updateFields.recurrenceTimeZoneSidKey !== undefined) { + body.RecurrenceTimeZoneSidKey = updateFields.recurrenceTimeZoneSidKey as string; + } + 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 + if (operation === 'get') { + const taskId = this.getNodeParameter('taskId', i) as string; + responseData = await salesforceApiRequest.call(this, 'GET', `/sobjects/task/${taskId}`); + } + //https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/resources_query.htm + if (operation === 'getAll') { + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + const options = this.getNodeParameter('options', i) as IDataObject; + try { + if (returnAll) { + qs.q = getQuery(options, 'Task', returnAll) as string; + responseData = await salesforceApiRequestAllItems.call(this, 'records', 'GET', '/query', {}, qs); + } else { + const limit = this.getNodeParameter('limit', i) as number; + qs.q = getQuery(options, 'Task', returnAll, limit) as string; + responseData = await salesforceApiRequestAllItems.call(this, 'records', 'GET', '/query', {}, qs); + } + } catch (error) { + throw new NodeApiError(this.getNode(), error); + } + } + //https://developer.salesforce.com/docs/api-explorer/sobject/Task/delete-task-id + if (operation === 'delete') { + const taskId = this.getNodeParameter('taskId', i) as string; + try { + responseData = await salesforceApiRequest.call(this, 'DELETE', `/sobjects/task/${taskId}`); + } catch (error) { + throw new NodeApiError(this.getNode(), error); + } + } + //https://developer.salesforce.com/docs/api-explorer/sobject/Task/get-task + if (operation === 'getSummary') { + responseData = await salesforceApiRequest.call(this, 'GET', '/sobjects/task'); } } - //https://developer.salesforce.com/docs/api-explorer/sobject/Task/get-task - if (operation === 'getSummary') { - responseData = await salesforceApiRequest.call(this, 'GET', '/sobjects/task'); - } - } - if (resource === 'attachment') { - //https://developer.salesforce.com/docs/api-explorer/sobject/Attachment/post-attachment - if (operation === 'create') { - const name = this.getNodeParameter('name', i) as string; - const parentId = this.getNodeParameter('parentId', i) as string; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const binaryPropertyName = this.getNodeParameter('binaryPropertyName', i) as string; - const body: IAttachment = { - Name: name, - ParentId: parentId, - }; - if (items[i].binary && items[i].binary![binaryPropertyName]) { - body.Body = items[i].binary![binaryPropertyName].data; - body.ContentType = items[i].binary![binaryPropertyName].mimeType; - } else { - throw new NodeOperationError(this.getNode(), `The property ${binaryPropertyName} does not exist`); - } - if (additionalFields.description !== undefined) { - body.Description = additionalFields.description as string; - } - if (additionalFields.owner !== undefined) { - body.OwnerId = additionalFields.owner as string; - } - if (additionalFields.isPrivate !== undefined) { - body.IsPrivate = additionalFields.isPrivate as boolean; - } - responseData = await salesforceApiRequest.call(this, 'POST', '/sobjects/attachment', body); - } - //https://developer.salesforce.com/docs/api-explorer/sobject/Attachment/patch-attachment-id - if (operation === 'update') { - const attachmentId = this.getNodeParameter('attachmentId', i) as string; - const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; - const body: IAttachment = {}; - if (updateFields.binaryPropertyName !== undefined) { - const binaryPropertyName = updateFields.binaryPropertyName as string; + if (resource === 'attachment') { + //https://developer.salesforce.com/docs/api-explorer/sobject/Attachment/post-attachment + if (operation === 'create') { + const name = this.getNodeParameter('name', i) as string; + const parentId = this.getNodeParameter('parentId', i) as string; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const binaryPropertyName = this.getNodeParameter('binaryPropertyName', i) as string; + const body: IAttachment = { + Name: name, + ParentId: parentId, + }; if (items[i].binary && items[i].binary![binaryPropertyName]) { body.Body = items[i].binary![binaryPropertyName].data; body.ContentType = items[i].binary![binaryPropertyName].mimeType; } else { throw new NodeOperationError(this.getNode(), `The property ${binaryPropertyName} does not exist`); } - } - if (updateFields.name !== undefined) { - body.Name = updateFields.name as string; - } - if (updateFields.description !== undefined) { - body.Description = updateFields.description as string; - } - if (updateFields.owner !== undefined) { - body.OwnerId = updateFields.owner as string; - } - if (updateFields.isPrivate !== undefined) { - body.IsPrivate = updateFields.isPrivate as boolean; - } - responseData = await salesforceApiRequest.call(this, 'PATCH', `/sobjects/attachment/${attachmentId}`, body); - } - //https://developer.salesforce.com/docs/api-explorer/sobject/Attachment/get-attachment-id - if (operation === 'get') { - const attachmentId = this.getNodeParameter('attachmentId', i) as string; - responseData = await salesforceApiRequest.call(this, 'GET', `/sobjects/attachment/${attachmentId}`); - } - //https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/resources_query.htm - if (operation === 'getAll') { - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - const options = this.getNodeParameter('options', i) as IDataObject; - try { - if (returnAll) { - qs.q = getQuery(options, 'Attachment', returnAll) as string; - responseData = await salesforceApiRequestAllItems.call(this, 'records', 'GET', '/query', {}, qs); - } else { - const limit = this.getNodeParameter('limit', i) as number; - qs.q = getQuery(options, 'Attachment', returnAll, limit) as string; - responseData = await salesforceApiRequestAllItems.call(this, 'records', 'GET', '/query', {}, qs); + if (additionalFields.description !== undefined) { + body.Description = additionalFields.description as string; } - } catch (error) { - throw new NodeApiError(this.getNode(), error); - } - } - //https://developer.salesforce.com/docs/api-explorer/sobject/Attachment/delete-attachment-id - if (operation === 'delete') { - const attachmentId = this.getNodeParameter('attachmentId', i) as string; - try { - responseData = await salesforceApiRequest.call(this, 'DELETE', `/sobjects/attachment/${attachmentId}`); - } catch (error) { - throw new NodeApiError(this.getNode(), error); - } - } - //https://developer.salesforce.com/docs/api-explorer/sobject/Attachment/get-attachment-id - if (operation === 'getSummary') { - responseData = await salesforceApiRequest.call(this, 'GET', '/sobjects/attachment'); - } - } - if (resource === 'user') { - //https://developer.salesforce.com/docs/api-explorer/sobject/User/get-user-id - if (operation === 'get') { - const userId = this.getNodeParameter('userId', i) as string; - responseData = await salesforceApiRequest.call(this, 'GET', `/sobjects/user/${userId}`); - } - //https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/resources_query.htm - if (operation === 'getAll') { - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - const options = this.getNodeParameter('options', i) as IDataObject; - try { - if (returnAll) { - qs.q = getQuery(options, 'User', returnAll) as string; - responseData = await salesforceApiRequestAllItems.call(this, 'records', 'GET', '/query', {}, qs); - } else { - const limit = this.getNodeParameter('limit', i) as number; - qs.q = getQuery(options, 'User', returnAll, limit) as string; - responseData = await salesforceApiRequestAllItems.call(this, 'records', 'GET', '/query', {}, qs); + if (additionalFields.owner !== undefined) { + body.OwnerId = additionalFields.owner as string; } - } catch (error) { - throw new NodeApiError(this.getNode(), error); + if (additionalFields.isPrivate !== undefined) { + body.IsPrivate = additionalFields.isPrivate as boolean; + } + responseData = await salesforceApiRequest.call(this, 'POST', '/sobjects/attachment', body); } - } - } - 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) as object; - } 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; + //https://developer.salesforce.com/docs/api-explorer/sobject/Attachment/patch-attachment-id + if (operation === 'update') { + const attachmentId = this.getNodeParameter('attachmentId', i) as string; + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + const body: IAttachment = {}; + if (updateFields.binaryPropertyName !== undefined) { + const binaryPropertyName = updateFields.binaryPropertyName as string; + if (items[i].binary && items[i].binary![binaryPropertyName]) { + body.Body = items[i].binary![binaryPropertyName].data; + body.ContentType = items[i].binary![binaryPropertyName].mimeType; + } else { + throw new NodeOperationError(this.getNode(), `The property ${binaryPropertyName} does not exist`); } } + if (updateFields.name !== undefined) { + body.Name = updateFields.name as string; + } + if (updateFields.description !== undefined) { + body.Description = updateFields.description as string; + } + if (updateFields.owner !== undefined) { + body.OwnerId = updateFields.owner as string; + } + if (updateFields.isPrivate !== undefined) { + body.IsPrivate = updateFields.isPrivate as boolean; + } + responseData = await salesforceApiRequest.call(this, 'PATCH', `/sobjects/attachment/${attachmentId}`, body); } - 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); + //https://developer.salesforce.com/docs/api-explorer/sobject/Attachment/get-attachment-id + if (operation === 'get') { + const attachmentId = this.getNodeParameter('attachmentId', i) as string; + responseData = await salesforceApiRequest.call(this, 'GET', `/sobjects/attachment/${attachmentId}`); + } + //https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/resources_query.htm + if (operation === 'getAll') { + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + const options = this.getNodeParameter('options', i) as IDataObject; + try { + if (returnAll) { + qs.q = getQuery(options, 'Attachment', returnAll) as string; + responseData = await salesforceApiRequestAllItems.call(this, 'records', 'GET', '/query', {}, qs); + } else { + const limit = this.getNodeParameter('limit', i) as number; + qs.q = getQuery(options, 'Attachment', returnAll, limit) as string; + responseData = await salesforceApiRequestAllItems.call(this, 'records', 'GET', '/query', {}, qs); + } + } catch (error) { + throw new NodeApiError(this.getNode(), error); + } + } + //https://developer.salesforce.com/docs/api-explorer/sobject/Attachment/delete-attachment-id + if (operation === 'delete') { + const attachmentId = this.getNodeParameter('attachmentId', i) as string; + try { + responseData = await salesforceApiRequest.call(this, 'DELETE', `/sobjects/attachment/${attachmentId}`); + } catch (error) { + throw new NodeApiError(this.getNode(), error); + } + } + //https://developer.salesforce.com/docs/api-explorer/sobject/Attachment/get-attachment-id + if (operation === 'getSummary') { + responseData = await salesforceApiRequest.call(this, 'GET', '/sobjects/attachment'); } } - } - if (resource === 'search') { - //https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/resources_query.htm - if (operation === 'query') { - qs.q = this.getNodeParameter('query', i) as string; - responseData = await salesforceApiRequestAllItems.call(this, 'records', 'GET', '/query', {}, qs); + if (resource === 'user') { + //https://developer.salesforce.com/docs/api-explorer/sobject/User/get-user-id + if (operation === 'get') { + const userId = this.getNodeParameter('userId', i) as string; + responseData = await salesforceApiRequest.call(this, 'GET', `/sobjects/user/${userId}`); + } + //https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/resources_query.htm + if (operation === 'getAll') { + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + const options = this.getNodeParameter('options', i) as IDataObject; + try { + if (returnAll) { + qs.q = getQuery(options, 'User', returnAll) as string; + responseData = await salesforceApiRequestAllItems.call(this, 'records', 'GET', '/query', {}, qs); + } else { + const limit = this.getNodeParameter('limit', i) as number; + qs.q = getQuery(options, 'User', returnAll, limit) as string; + responseData = await salesforceApiRequestAllItems.call(this, 'records', 'GET', '/query', {}, qs); + } + } catch (error) { + throw new NodeApiError(this.getNode(), error); + } + } } - } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else { - if (responseData === undefined) { - // Make sure that always valid JSON gets returned which also matches the - // Salesforce default response - responseData = { - errors: [], - success: true, - }; + 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) as object; + } 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); + } + } } - returnData.push(responseData as IDataObject); + if (resource === 'search') { + //https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/resources_query.htm + if (operation === 'query') { + qs.q = this.getNodeParameter('query', i) as string; + responseData = await salesforceApiRequestAllItems.call(this, 'records', 'GET', '/query', {}, qs); + } + } + if (Array.isArray(responseData)) { + returnData.push.apply(returnData, responseData as IDataObject[]); + } else { + if (responseData === undefined) { + // Make sure that always valid JSON gets returned which also matches the + // Salesforce default response + responseData = { + errors: [], + success: true, + }; + } + returnData.push(responseData as IDataObject); + } + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } } return [this.helpers.returnJsonArray(returnData)]; } } + + + diff --git a/packages/nodes-base/nodes/Segment/Segment.node.ts b/packages/nodes-base/nodes/Segment/Segment.node.ts index eea1ef5481..4e60de84f9 100644 --- a/packages/nodes-base/nodes/Segment/Segment.node.ts +++ b/packages/nodes-base/nodes/Segment/Segment.node.ts @@ -104,526 +104,534 @@ export class Segment implements INodeType { const operation = this.getNodeParameter('operation', 0) as string; for (let i = 0; i < length; i++) { - if (resource === 'group') { - //https://segment.com/docs/connections/sources/catalog/libraries/server/http-api/#group - if (operation === 'add') { - const userId = this.getNodeParameter('userId', i) as string; - const groupId = this.getNodeParameter('groupId', i) as string; - const traits = (this.getNodeParameter('traits', i) as IDataObject).traitsUi as IDataObject[]; - const context = (this.getNodeParameter('context', i) as IDataObject).contextUi as IDataObject; - const integrations = (this.getNodeParameter('integrations', i) as IDataObject).integrationsUi as IDataObject; - const body: IGroup = { - groupId, - traits: { - company: {}, - address: {}, - }, - context: { - app: {}, - campaign: {}, - device: {}, - }, - integrations: {}, - }; - if (userId) { - body.userId = userId as string; - } else { - body.anonymousId = uuid(); - } - if (traits) { - if (traits && traits.length !== 0) { - for (const trait of traits) { - body.traits![trait.key as string] = trait.value; - } + try { + if (resource === 'group') { + //https://segment.com/docs/connections/sources/catalog/libraries/server/http-api/#group + if (operation === 'add') { + const userId = this.getNodeParameter('userId', i) as string; + const groupId = this.getNodeParameter('groupId', i) as string; + const traits = (this.getNodeParameter('traits', i) as IDataObject).traitsUi as IDataObject[]; + const context = (this.getNodeParameter('context', i) as IDataObject).contextUi as IDataObject; + const integrations = (this.getNodeParameter('integrations', i) as IDataObject).integrationsUi as IDataObject; + const body: IGroup = { + groupId, + traits: { + company: {}, + address: {}, + }, + context: { + app: {}, + campaign: {}, + device: {}, + }, + integrations: {}, + }; + if (userId) { + body.userId = userId as string; + } else { + body.anonymousId = uuid(); } - } - if (context) { - if (context.active) { - body.context!.active = context.active as boolean; - } - if (context.ip) { - body.context!.ip = context.ip as string; - } - if (context.locate) { - body.context!.locate = context.locate as string; - } - if (context.page) { - body.context!.page = context.page as string; - } - if (context.timezone) { - body.context!.timezone = context.timezone as string; - } - if (context.timezone) { - body.context!.timezone = context.timezone as string; - } - if (context.app) { - const app = (context.app as IDataObject).appUi as IDataObject; - if (app) { - if (app.name) { - //@ts-ignore - body.context.app.name = app.name as string; - } - if (app.version) { - //@ts-ignore - body.context.app.version = app.version as string; - } - if (app.build) { - //@ts-ignore - body.context.app.build = app.build as string; + if (traits) { + if (traits && traits.length !== 0) { + for (const trait of traits) { + body.traits![trait.key as string] = trait.value; } } } - if (context.campaign) { - const campaign = (context.campaign as IDataObject).campaignUi as IDataObject; - if (campaign) { - if (campaign.name) { - //@ts-ignore - body.context.campaign.name = campaign.name as string; - } - if (campaign.source) { - //@ts-ignore - body.context.campaign.source = campaign.source as string; - } - if (campaign.medium) { - //@ts-ignore - body.context.campaign.medium = campaign.medium as string; - } - if (campaign.term) { - //@ts-ignore - body.context.campaign.term = campaign.term as string; - } - if (campaign.content) { - //@ts-ignore - body.context.campaign.content = campaign.content as string; + if (context) { + if (context.active) { + body.context!.active = context.active as boolean; + } + if (context.ip) { + body.context!.ip = context.ip as string; + } + if (context.locate) { + body.context!.locate = context.locate as string; + } + if (context.page) { + body.context!.page = context.page as string; + } + if (context.timezone) { + body.context!.timezone = context.timezone as string; + } + if (context.timezone) { + body.context!.timezone = context.timezone as string; + } + if (context.app) { + const app = (context.app as IDataObject).appUi as IDataObject; + if (app) { + if (app.name) { + //@ts-ignore + body.context.app.name = app.name as string; + } + if (app.version) { + //@ts-ignore + body.context.app.version = app.version as string; + } + if (app.build) { + //@ts-ignore + body.context.app.build = app.build as string; + } + } + } + if (context.campaign) { + const campaign = (context.campaign as IDataObject).campaignUi as IDataObject; + if (campaign) { + if (campaign.name) { + //@ts-ignore + body.context.campaign.name = campaign.name as string; + } + if (campaign.source) { + //@ts-ignore + body.context.campaign.source = campaign.source as string; + } + if (campaign.medium) { + //@ts-ignore + body.context.campaign.medium = campaign.medium as string; + } + if (campaign.term) { + //@ts-ignore + body.context.campaign.term = campaign.term as string; + } + if (campaign.content) { + //@ts-ignore + body.context.campaign.content = campaign.content as string; + } } } - } - if (context.device) { - const device = (context.device as IDataObject).deviceUi as IDataObject; - if (device) { - if (device.id) { - //@ts-ignore - body.context.device.id = device.id as string; - } - if (device.manufacturer) { - //@ts-ignore - body.context.device.manufacturer = device.manufacturer as string; - } - if (device.model) { - //@ts-ignore - body.context.device.model = device.model as string; - } - if (device.type) { - //@ts-ignore - body.context.device.type = device.type as string; - } - if (device.version) { - //@ts-ignore - body.context.device.version = device.version as string; + if (context.device) { + const device = (context.device as IDataObject).deviceUi as IDataObject; + if (device) { + if (device.id) { + //@ts-ignore + body.context.device.id = device.id as string; + } + if (device.manufacturer) { + //@ts-ignore + body.context.device.manufacturer = device.manufacturer as string; + } + if (device.model) { + //@ts-ignore + body.context.device.model = device.model as string; + } + if (device.type) { + //@ts-ignore + body.context.device.type = device.type as string; + } + if (device.version) { + //@ts-ignore + body.context.device.version = device.version as string; + } } } } - } - if (integrations) { - if (integrations.all) { - body.integrations!.all = integrations.all as boolean; - } - if (integrations.salesforce) { - body.integrations!.salesforce = integrations.salesforce as boolean; + if (integrations) { + if (integrations.all) { + body.integrations!.all = integrations.all as boolean; + } + if (integrations.salesforce) { + body.integrations!.salesforce = integrations.salesforce as boolean; + } } + responseData = await segmentApiRequest.call(this, 'POST', '/group', body); } - responseData = await segmentApiRequest.call(this, 'POST', '/group', body); } - } - if (resource === 'identify') { - //https://segment.com/docs/connections/sources/catalog/libraries/server/http-api/#identify - if (operation === 'create') { - const userId = this.getNodeParameter('userId', i) as string; - const context = (this.getNodeParameter('context', i) as IDataObject).contextUi as IDataObject; - const traits = (this.getNodeParameter('traits', i) as IDataObject).traitsUi as IDataObject[]; - const integrations = (this.getNodeParameter('integrations', i) as IDataObject).integrationsUi as IDataObject; - const body: IIdentify = { - context: { - app: {}, - campaign: {}, - device: {}, - }, - traits: {}, - integrations: {}, - }; - if (userId) { - body.userId = userId as string; - } else { - body.anonymousId = uuid(); - } - if (context) { - if (context.active) { - body.context!.active = context.active as boolean; + if (resource === 'identify') { + //https://segment.com/docs/connections/sources/catalog/libraries/server/http-api/#identify + if (operation === 'create') { + const userId = this.getNodeParameter('userId', i) as string; + const context = (this.getNodeParameter('context', i) as IDataObject).contextUi as IDataObject; + const traits = (this.getNodeParameter('traits', i) as IDataObject).traitsUi as IDataObject[]; + const integrations = (this.getNodeParameter('integrations', i) as IDataObject).integrationsUi as IDataObject; + const body: IIdentify = { + context: { + app: {}, + campaign: {}, + device: {}, + }, + traits: {}, + integrations: {}, + }; + if (userId) { + body.userId = userId as string; + } else { + body.anonymousId = uuid(); } - if (context.ip) { - body.context!.ip = context.ip as string; - } - if (context.locate) { - body.context!.locate = context.locate as string; - } - if (context.page) { - body.context!.page = context.page as string; - } - if (context.timezone) { - body.context!.timezone = context.timezone as string; - } - if (context.timezone) { - body.context!.timezone = context.timezone as string; - } - if (context.app) { - const app = (context.app as IDataObject).appUi as IDataObject; - if (app) { - if (app.name) { - //@ts-ignore - body.context.app.name = app.name as string; + if (context) { + if (context.active) { + body.context!.active = context.active as boolean; + } + if (context.ip) { + body.context!.ip = context.ip as string; + } + if (context.locate) { + body.context!.locate = context.locate as string; + } + if (context.page) { + body.context!.page = context.page as string; + } + if (context.timezone) { + body.context!.timezone = context.timezone as string; + } + if (context.timezone) { + body.context!.timezone = context.timezone as string; + } + if (context.app) { + const app = (context.app as IDataObject).appUi as IDataObject; + if (app) { + if (app.name) { + //@ts-ignore + body.context.app.name = app.name as string; + } + if (app.version) { + //@ts-ignore + body.context.app.version = app.version as string; + } + if (app.build) { + //@ts-ignore + body.context.app.build = app.build as string; + } } - if (app.version) { - //@ts-ignore - body.context.app.version = app.version as string; + } + if (context.campaign) { + const campaign = (context.campaign as IDataObject).campaignUi as IDataObject; + if (campaign) { + if (campaign.name) { + //@ts-ignore + body.context.campaign.name = campaign.name as string; + } + if (campaign.source) { + //@ts-ignore + body.context.campaign.source = campaign.source as string; + } + if (campaign.medium) { + //@ts-ignore + body.context.campaign.medium = campaign.medium as string; + } + if (campaign.term) { + //@ts-ignore + body.context.campaign.term = campaign.term as string; + } + if (campaign.content) { + //@ts-ignore + body.context.campaign.content = campaign.content as string; + } } - if (app.build) { - //@ts-ignore - body.context.app.build = app.build as string; + } + + if (context.device) { + const device = (context.device as IDataObject).deviceUi as IDataObject; + if (device) { + if (device.id) { + //@ts-ignore + body.context.device.id = device.id as string; + } + if (device.manufacturer) { + //@ts-ignore + body.context.device.manufacturer = device.manufacturer as string; + } + if (device.model) { + //@ts-ignore + body.context.device.model = device.model as string; + } + if (device.type) { + //@ts-ignore + body.context.device.type = device.type as string; + } + if (device.version) { + //@ts-ignore + body.context.device.version = device.version as string; + } } } } - if (context.campaign) { - const campaign = (context.campaign as IDataObject).campaignUi as IDataObject; - if (campaign) { - if (campaign.name) { - //@ts-ignore - body.context.campaign.name = campaign.name as string; - } - if (campaign.source) { - //@ts-ignore - body.context.campaign.source = campaign.source as string; - } - if (campaign.medium) { - //@ts-ignore - body.context.campaign.medium = campaign.medium as string; - } - if (campaign.term) { - //@ts-ignore - body.context.campaign.term = campaign.term as string; - } - if (campaign.content) { - //@ts-ignore - body.context.campaign.content = campaign.content as string; + if (integrations) { + if (integrations.all) { + body.integrations!.all = integrations.all as boolean; + } + if (integrations.salesforce) { + body.integrations!.salesforce = integrations.salesforce as boolean; + } + } + + if (traits) { + if (traits && traits.length !== 0) { + for (const trait of traits) { + body.traits![trait.key as string] = trait.value; } } } - if (context.device) { - const device = (context.device as IDataObject).deviceUi as IDataObject; - if (device) { - if (device.id) { - //@ts-ignore - body.context.device.id = device.id as string; - } - if (device.manufacturer) { - //@ts-ignore - body.context.device.manufacturer = device.manufacturer as string; - } - if (device.model) { - //@ts-ignore - body.context.device.model = device.model as string; - } - if (device.type) { - //@ts-ignore - body.context.device.type = device.type as string; - } - if (device.version) { - //@ts-ignore - body.context.device.version = device.version as string; - } - } - } + responseData = await segmentApiRequest.call(this, 'POST', '/identify', body); } - if (integrations) { - if (integrations.all) { - body.integrations!.all = integrations.all as boolean; - } - if (integrations.salesforce) { - body.integrations!.salesforce = integrations.salesforce as boolean; - } - } - - if (traits) { - if (traits && traits.length !== 0) { - for (const trait of traits) { - body.traits![trait.key as string] = trait.value; - } - } - } - - responseData = await segmentApiRequest.call(this, 'POST', '/identify', body); } - } - if (resource === 'track') { - //https://segment.com/docs/connections/sources/catalog/libraries/server/http-api/#track - if (operation === 'event') { - const userId = this.getNodeParameter('userId', i) as string; - const event = this.getNodeParameter('event', i) as string; - const context = (this.getNodeParameter('context', i) as IDataObject).contextUi as IDataObject; - const integrations = (this.getNodeParameter('integrations', i) as IDataObject).integrationsUi as IDataObject; - const properties = (this.getNodeParameter('properties', i) as IDataObject).propertiesUi as IDataObject[]; - const body: ITrack = { - event, - traits: { - }, - context: { - app: {}, - campaign: {}, - device: {}, - }, - integrations: {}, - properties: {}, - }; - if (userId) { - body.userId = userId as string; - } else { - body.anonymousId = uuid(); - } - if (context) { - if (context.active) { - body.context!.active = context.active as boolean; + if (resource === 'track') { + //https://segment.com/docs/connections/sources/catalog/libraries/server/http-api/#track + if (operation === 'event') { + const userId = this.getNodeParameter('userId', i) as string; + const event = this.getNodeParameter('event', i) as string; + const context = (this.getNodeParameter('context', i) as IDataObject).contextUi as IDataObject; + const integrations = (this.getNodeParameter('integrations', i) as IDataObject).integrationsUi as IDataObject; + const properties = (this.getNodeParameter('properties', i) as IDataObject).propertiesUi as IDataObject[]; + const body: ITrack = { + event, + traits: { + }, + context: { + app: {}, + campaign: {}, + device: {}, + }, + integrations: {}, + properties: {}, + }; + if (userId) { + body.userId = userId as string; + } else { + body.anonymousId = uuid(); } - if (context.ip) { - body.context!.ip = context.ip as string; - } - if (context.locate) { - body.context!.locate = context.locate as string; - } - if (context.page) { - body.context!.page = context.page as string; - } - if (context.timezone) { - body.context!.timezone = context.timezone as string; - } - if (context.timezone) { - body.context!.timezone = context.timezone as string; - } - if (context.app) { - const app = (context.app as IDataObject).appUi as IDataObject; - if (app) { - if (app.name) { - //@ts-ignore - body.context.app.name = app.name as string; + if (context) { + if (context.active) { + body.context!.active = context.active as boolean; + } + if (context.ip) { + body.context!.ip = context.ip as string; + } + if (context.locate) { + body.context!.locate = context.locate as string; + } + if (context.page) { + body.context!.page = context.page as string; + } + if (context.timezone) { + body.context!.timezone = context.timezone as string; + } + if (context.timezone) { + body.context!.timezone = context.timezone as string; + } + if (context.app) { + const app = (context.app as IDataObject).appUi as IDataObject; + if (app) { + if (app.name) { + //@ts-ignore + body.context.app.name = app.name as string; + } + if (app.version) { + //@ts-ignore + body.context.app.version = app.version as string; + } + if (app.build) { + //@ts-ignore + body.context.app.build = app.build as string; + } } - if (app.version) { - //@ts-ignore - body.context.app.version = app.version as string; + } + if (context.campaign) { + const campaign = (context.campaign as IDataObject).campaignUi as IDataObject; + if (campaign) { + if (campaign.name) { + //@ts-ignore + body.context.campaign.name = campaign.name as string; + } + if (campaign.source) { + //@ts-ignore + body.context.campaign.source = campaign.source as string; + } + if (campaign.medium) { + //@ts-ignore + body.context.campaign.medium = campaign.medium as string; + } + if (campaign.term) { + //@ts-ignore + body.context.campaign.term = campaign.term as string; + } + if (campaign.content) { + //@ts-ignore + body.context.campaign.content = campaign.content as string; + } } - if (app.build) { - //@ts-ignore - body.context.app.build = app.build as string; + } + + if (context.device) { + const device = (context.device as IDataObject).deviceUi as IDataObject; + if (device) { + if (device.id) { + //@ts-ignore + body.context.device.id = device.id as string; + } + if (device.manufacturer) { + //@ts-ignore + body.context.device.manufacturer = device.manufacturer as string; + } + if (device.model) { + //@ts-ignore + body.context.device.model = device.model as string; + } + if (device.type) { + //@ts-ignore + body.context.device.type = device.type as string; + } + if (device.version) { + //@ts-ignore + body.context.device.version = device.version as string; + } } } } - if (context.campaign) { - const campaign = (context.campaign as IDataObject).campaignUi as IDataObject; - if (campaign) { - if (campaign.name) { - //@ts-ignore - body.context.campaign.name = campaign.name as string; - } - if (campaign.source) { - //@ts-ignore - body.context.campaign.source = campaign.source as string; - } - if (campaign.medium) { - //@ts-ignore - body.context.campaign.medium = campaign.medium as string; - } - if (campaign.term) { - //@ts-ignore - body.context.campaign.term = campaign.term as string; - } - if (campaign.content) { - //@ts-ignore - body.context.campaign.content = campaign.content as string; + if (integrations) { + if (integrations.all) { + body.integrations!.all = integrations.all as boolean; + } + if (integrations.salesforce) { + body.integrations!.salesforce = integrations.salesforce as boolean; + } + } + if (properties) { + if (properties && properties.length !== 0) { + for (const property of properties) { + body.properties![property.key as string] = property.value; } } } - if (context.device) { - const device = (context.device as IDataObject).deviceUi as IDataObject; - if (device) { - if (device.id) { - //@ts-ignore - body.context.device.id = device.id as string; - } - if (device.manufacturer) { - //@ts-ignore - body.context.device.manufacturer = device.manufacturer as string; - } - if (device.model) { - //@ts-ignore - body.context.device.model = device.model as string; - } - if (device.type) { - //@ts-ignore - body.context.device.type = device.type as string; - } - if (device.version) { - //@ts-ignore - body.context.device.version = device.version as string; + responseData = await segmentApiRequest.call(this, 'POST', '/track', body); + } + //https://segment.com/docs/connections/sources/catalog/libraries/server/http-api/#page + if (operation === 'page') { + const userId = this.getNodeParameter('userId', i) as string; + const name = this.getNodeParameter('name', i) as string; + const context = (this.getNodeParameter('context', i) as IDataObject).contextUi as IDataObject; + const integrations = (this.getNodeParameter('integrations', i) as IDataObject).integrationsUi as IDataObject; + const properties = (this.getNodeParameter('properties', i) as IDataObject).propertiesUi as IDataObject[]; + const body: ITrack = { + name, + traits: {}, + context: { + app: {}, + campaign: {}, + device: {}, + }, + integrations: {}, + properties: {}, + }; + if (userId) { + body.userId = userId as string; + } else { + body.anonymousId = uuid(); + } + if (context) { + if (context.active) { + body.context!.active = context.active as boolean; + } + if (context.ip) { + body.context!.ip = context.ip as string; + } + if (context.locate) { + body.context!.locate = context.locate as string; + } + if (context.page) { + body.context!.page = context.page as string; + } + if (context.timezone) { + body.context!.timezone = context.timezone as string; + } + if (context.timezone) { + body.context!.timezone = context.timezone as string; + } + if (context.app) { + const app = (context.app as IDataObject).appUi as IDataObject; + if (app) { + if (app.name) { + //@ts-ignore + body.context.app.name = app.name as string; + } + if (app.version) { + //@ts-ignore + body.context.app.version = app.version as string; + } + if (app.build) { + //@ts-ignore + body.context.app.build = app.build as string; + } } } - } - } - if (integrations) { - if (integrations.all) { - body.integrations!.all = integrations.all as boolean; - } - if (integrations.salesforce) { - body.integrations!.salesforce = integrations.salesforce as boolean; - } - } - if (properties) { - if (properties && properties.length !== 0) { - for (const property of properties) { - body.properties![property.key as string] = property.value; + if (context.campaign) { + const campaign = (context.campaign as IDataObject).campaignUi as IDataObject; + if (campaign) { + if (campaign.name) { + //@ts-ignore + body.context.campaign.name = campaign.name as string; + } + if (campaign.source) { + //@ts-ignore + body.context.campaign.source = campaign.source as string; + } + if (campaign.medium) { + //@ts-ignore + body.context.campaign.medium = campaign.medium as string; + } + if (campaign.term) { + //@ts-ignore + body.context.campaign.term = campaign.term as string; + } + if (campaign.content) { + //@ts-ignore + body.context.campaign.content = campaign.content as string; + } + } } - } - } - responseData = await segmentApiRequest.call(this, 'POST', '/track', body); + if (context.device) { + const device = (context.device as IDataObject).deviceUi as IDataObject; + if (device) { + if (device.id) { + //@ts-ignore + body.context.device.id = device.id as string; + } + if (device.manufacturer) { + //@ts-ignore + body.context.device.manufacturer = device.manufacturer as string; + } + if (device.model) { + //@ts-ignore + body.context.device.model = device.model as string; + } + if (device.type) { + //@ts-ignore + body.context.device.type = device.type as string; + } + if (device.version) { + //@ts-ignore + body.context.device.version = device.version as string; + } + } + } + } + if (integrations) { + if (integrations.all) { + body.integrations!.all = integrations.all as boolean; + } + if (integrations.salesforce) { + body.integrations!.salesforce = integrations.salesforce as boolean; + } + } + if (properties) { + if (properties && properties.length !== 0) { + for (const property of properties) { + body.properties![property.key as string] = property.value; + } + } + } + responseData = await segmentApiRequest.call(this, 'POST', '/page', body); + } } - //https://segment.com/docs/connections/sources/catalog/libraries/server/http-api/#page - if (operation === 'page') { - const userId = this.getNodeParameter('userId', i) as string; - const name = this.getNodeParameter('name', i) as string; - const context = (this.getNodeParameter('context', i) as IDataObject).contextUi as IDataObject; - const integrations = (this.getNodeParameter('integrations', i) as IDataObject).integrationsUi as IDataObject; - const properties = (this.getNodeParameter('properties', i) as IDataObject).propertiesUi as IDataObject[]; - const body: ITrack = { - name, - traits: {}, - context: { - app: {}, - campaign: {}, - device: {}, - }, - integrations: {}, - properties: {}, - }; - if (userId) { - body.userId = userId as string; - } else { - body.anonymousId = uuid(); - } - if (context) { - if (context.active) { - body.context!.active = context.active as boolean; - } - if (context.ip) { - body.context!.ip = context.ip as string; - } - if (context.locate) { - body.context!.locate = context.locate as string; - } - if (context.page) { - body.context!.page = context.page as string; - } - if (context.timezone) { - body.context!.timezone = context.timezone as string; - } - if (context.timezone) { - body.context!.timezone = context.timezone as string; - } - if (context.app) { - const app = (context.app as IDataObject).appUi as IDataObject; - if (app) { - if (app.name) { - //@ts-ignore - body.context.app.name = app.name as string; - } - if (app.version) { - //@ts-ignore - body.context.app.version = app.version as string; - } - if (app.build) { - //@ts-ignore - body.context.app.build = app.build as string; - } - } - } - if (context.campaign) { - const campaign = (context.campaign as IDataObject).campaignUi as IDataObject; - if (campaign) { - if (campaign.name) { - //@ts-ignore - body.context.campaign.name = campaign.name as string; - } - if (campaign.source) { - //@ts-ignore - body.context.campaign.source = campaign.source as string; - } - if (campaign.medium) { - //@ts-ignore - body.context.campaign.medium = campaign.medium as string; - } - if (campaign.term) { - //@ts-ignore - body.context.campaign.term = campaign.term as string; - } - if (campaign.content) { - //@ts-ignore - body.context.campaign.content = campaign.content as string; - } - } - } - - if (context.device) { - const device = (context.device as IDataObject).deviceUi as IDataObject; - if (device) { - if (device.id) { - //@ts-ignore - body.context.device.id = device.id as string; - } - if (device.manufacturer) { - //@ts-ignore - body.context.device.manufacturer = device.manufacturer as string; - } - if (device.model) { - //@ts-ignore - body.context.device.model = device.model as string; - } - if (device.type) { - //@ts-ignore - body.context.device.type = device.type as string; - } - if (device.version) { - //@ts-ignore - body.context.device.version = device.version as string; - } - } - } - } - if (integrations) { - if (integrations.all) { - body.integrations!.all = integrations.all as boolean; - } - if (integrations.salesforce) { - body.integrations!.salesforce = integrations.salesforce as boolean; - } - } - if (properties) { - if (properties && properties.length !== 0) { - for (const property of properties) { - body.properties![property.key as string] = property.value; - } - } - } - responseData = await segmentApiRequest.call(this, 'POST', '/page', body); + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; } + throw error; } if (Array.isArray(responseData)) { returnData.push.apply(returnData, responseData as IDataObject[]); diff --git a/packages/nodes-base/nodes/SendGrid/SendGrid.node.ts b/packages/nodes-base/nodes/SendGrid/SendGrid.node.ts index ba9a6c3608..0b447b482b 100644 --- a/packages/nodes-base/nodes/SendGrid/SendGrid.node.ts +++ b/packages/nodes-base/nodes/SendGrid/SendGrid.node.ts @@ -139,22 +139,30 @@ export class SendGrid implements INodeType { if (resource === 'contact') { if (operation === 'getAll') { for (let i = 0; i < length; i++) { - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - const filters = this.getNodeParameter('filters', i) as IDataObject; - let endpoint = '/marketing/contacts'; - let method = 'GET'; - const body: IDataObject = {}; - if (filters.query && filters.query !== '') { - endpoint = '/marketing/contacts/search'; - method = 'POST'; - Object.assign(body, { query: filters.query }); + try { + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + const filters = this.getNodeParameter('filters', i) as IDataObject; + let endpoint = '/marketing/contacts'; + let method = 'GET'; + const body: IDataObject = {}; + if (filters.query && filters.query !== '') { + endpoint = '/marketing/contacts/search'; + method = 'POST'; + Object.assign(body, { query: filters.query }); + } + responseData = await sendGridApiRequestAllItems.call(this, endpoint, method, 'result', body, qs); + if (returnAll === false) { + const limit = this.getNodeParameter('limit', i) as number; + responseData = responseData.splice(0, limit); + } + returnData.push.apply(returnData, responseData); + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } - responseData = await sendGridApiRequestAllItems.call(this, endpoint, method, 'result', body, qs); - if (returnAll === false) { - const limit = this.getNodeParameter('limit', i) as number; - responseData = responseData.splice(0, limit); - } - returnData.push.apply(returnData, responseData); } } if (operation === 'get') { @@ -163,272 +171,343 @@ export class SendGrid implements INodeType { let method; const body: IDataObject = {}; for (let i = 0; i < length; i++) { - if (by === 'id') { - method = 'GET'; - const contactId = this.getNodeParameter('contactId', i) as string; - endpoint = `/marketing/contacts/${contactId}`; - } else { - const email = this.getNodeParameter('email', i) as string; - endpoint = '/marketing/contacts/search'; - method = 'POST'; - Object.assign(body, { query: `email LIKE '${email}' ` }); + try { + if (by === 'id') { + method = 'GET'; + const contactId = this.getNodeParameter('contactId', i) as string; + endpoint = `/marketing/contacts/${contactId}`; + } else { + const email = this.getNodeParameter('email', i) as string; + endpoint = '/marketing/contacts/search'; + method = 'POST'; + Object.assign(body, { query: `email LIKE '${email}' ` }); + } + responseData = await sendGridApiRequest.call(this, endpoint, method, body, qs); + responseData = responseData.result || responseData; + if (Array.isArray(responseData)) { + responseData = responseData[0]; + } + returnData.push(responseData); + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } - responseData = await sendGridApiRequest.call(this, endpoint, method, body, qs); - responseData = responseData.result || responseData; - if (Array.isArray(responseData)) { - responseData = responseData[0]; - } - returnData.push(responseData); } } if (operation === 'upsert') { - const contacts = []; - for (let i = 0; i < length; i++) { - const email = this.getNodeParameter('email', i) as string; - const additionalFields = this.getNodeParameter( - 'additionalFields', - i, - ) as IDataObject; - const contact: IDataObject = { - email, - }; - if (additionalFields.addressUi) { - const addressValues = (additionalFields.addressUi as IDataObject).addressValues as IDataObject; - const addressLine1 = addressValues.address1 as string; - const addressLine2 = addressValues.address2 as string; - if (addressLine2) { - Object.assign(contact, { address_line_2: addressLine2 }); + try { + const contacts = []; + for (let i = 0; i < length; i++) { + const email = this.getNodeParameter('email', i) as string; + const additionalFields = this.getNodeParameter( + 'additionalFields', + i, + ) as IDataObject; + const contact: IDataObject = { + email, + }; + if (additionalFields.addressUi) { + const addressValues = (additionalFields.addressUi as IDataObject).addressValues as IDataObject; + const addressLine1 = addressValues.address1 as string; + const addressLine2 = addressValues.address2 as string; + if (addressLine2) { + Object.assign(contact, { address_line_2: addressLine2 }); + } + Object.assign(contact, { address_line_1: addressLine1 }); } - Object.assign(contact, { address_line_1: addressLine1 }); - } - if (additionalFields.city) { - const city = additionalFields.city as string; - Object.assign(contact, { city }); - } - if (additionalFields.country) { - const country = additionalFields.country as string; - Object.assign(contact, { country }); - } - if (additionalFields.firstName) { - const firstName = additionalFields.firstName as string; - Object.assign(contact, { first_name: firstName }); - } - if (additionalFields.lastName) { - const lastName = additionalFields.lastName as string; - Object.assign(contact, { last_name: lastName }); - } - if (additionalFields.postalCode) { - const postalCode = additionalFields.postalCode as string; - Object.assign(contact, { postal_code: postalCode }); - } - if (additionalFields.stateProvinceRegion) { - const stateProvinceRegion = additionalFields.stateProvinceRegion as string; - Object.assign(contact, { state_province_region: stateProvinceRegion }); - } - if (additionalFields.alternateEmails) { - const alternateEmails = ((additionalFields.alternateEmails as string).split(',') as string[]).filter(email => !!email); - if (alternateEmails.length !== 0) { - Object.assign(contact, { alternate_emails: alternateEmails }); + if (additionalFields.city) { + const city = additionalFields.city as string; + Object.assign(contact, { city }); } - } - if (additionalFields.listIdsUi) { - const listIdValues = (additionalFields.listIdsUi as IDataObject).listIdValues as IDataObject; - const listIds = listIdValues.listIds as IDataObject[]; - Object.assign(contact, { list_ids: listIds }); - } - if (additionalFields.customFieldsUi) { - const customFields = (additionalFields.customFieldsUi as IDataObject).customFieldValues as IDataObject[]; - if (customFields) { - const data = customFields.reduce((obj, value) => Object.assign(obj, { [`${value.fieldId}`]: value.fieldValue }), {}); - Object.assign(contact, { custom_fields: data }); + if (additionalFields.country) { + const country = additionalFields.country as string; + Object.assign(contact, { country }); } + if (additionalFields.firstName) { + const firstName = additionalFields.firstName as string; + Object.assign(contact, { first_name: firstName }); + } + if (additionalFields.lastName) { + const lastName = additionalFields.lastName as string; + Object.assign(contact, { last_name: lastName }); + } + if (additionalFields.postalCode) { + const postalCode = additionalFields.postalCode as string; + Object.assign(contact, { postal_code: postalCode }); + } + if (additionalFields.stateProvinceRegion) { + const stateProvinceRegion = additionalFields.stateProvinceRegion as string; + Object.assign(contact, { state_province_region: stateProvinceRegion }); + } + if (additionalFields.alternateEmails) { + const alternateEmails = ((additionalFields.alternateEmails as string).split(',') as string[]).filter(email => !!email); + if (alternateEmails.length !== 0) { + Object.assign(contact, { alternate_emails: alternateEmails }); + } + } + if (additionalFields.listIdsUi) { + const listIdValues = (additionalFields.listIdsUi as IDataObject).listIdValues as IDataObject; + const listIds = listIdValues.listIds as IDataObject[]; + Object.assign(contact, { list_ids: listIds }); + } + if (additionalFields.customFieldsUi) { + const customFields = (additionalFields.customFieldsUi as IDataObject).customFieldValues as IDataObject[]; + if (customFields) { + const data = customFields.reduce((obj, value) => Object.assign(obj, { [`${value.fieldId}`]: value.fieldValue }), {}); + Object.assign(contact, { custom_fields: data }); + } + } + contacts.push(contact); } - contacts.push(contact); - } - responseData = await sendGridApiRequest.call(this, '/marketing/contacts', 'PUT', { contacts }, qs); + responseData = await sendGridApiRequest.call(this, '/marketing/contacts', 'PUT', { contacts }, qs); - returnData.push(responseData); + returnData.push(responseData); + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + } else { + throw error; + } + } } if (operation === 'delete') { for (let i = 0; i < length; i++) { - const deleteAll = this.getNodeParameter('deleteAll', i) as boolean; - if (deleteAll === true) { - qs.delete_all_contacts = 'true'; + try { + const deleteAll = this.getNodeParameter('deleteAll', i) as boolean; + if (deleteAll === true) { + qs.delete_all_contacts = 'true'; + } + qs.ids = (this.getNodeParameter('ids', i) as string).replace(/\s/g, ''); + responseData = await sendGridApiRequest.call(this, `/marketing/contacts`, 'DELETE', {}, qs); + returnData.push(responseData); + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } - qs.ids = (this.getNodeParameter('ids', i) as string).replace(/\s/g, ''); - responseData = await sendGridApiRequest.call(this, `/marketing/contacts`, 'DELETE', {}, qs); - returnData.push(responseData); } } } if (resource === 'list') { if (operation === 'getAll') { for (let i = 0; i < length; i++) { - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - responseData = await sendGridApiRequestAllItems.call(this, `/marketing/lists`, 'GET', 'result', {}, qs); - if (returnAll === false) { - const limit = this.getNodeParameter('limit', i) as number; - responseData = responseData.splice(0, limit); + try { + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + responseData = await sendGridApiRequestAllItems.call(this, `/marketing/lists`, 'GET', 'result', {}, qs); + if (returnAll === false) { + const limit = this.getNodeParameter('limit', i) as number; + responseData = responseData.splice(0, limit); + } + returnData.push.apply(returnData, responseData); + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } - returnData.push.apply(returnData, responseData); } } if (operation === 'get') { for (let i = 0; i < length; i++) { - const listId = this.getNodeParameter('listId', i) as string; - qs.contact_sample = this.getNodeParameter('contactSample', i) as boolean; - responseData = await sendGridApiRequest.call(this, `/marketing/lists/${listId}`, 'GET', {}, qs); - returnData.push(responseData); + try { + const listId = this.getNodeParameter('listId', i) as string; + qs.contact_sample = this.getNodeParameter('contactSample', i) as boolean; + responseData = await sendGridApiRequest.call(this, `/marketing/lists/${listId}`, 'GET', {}, qs); + returnData.push(responseData); + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; + } } } if (operation === 'create') { for (let i = 0; i < length; i++) { - const name = this.getNodeParameter('name', i) as string; - responseData = await sendGridApiRequest.call(this, '/marketing/lists', 'POST', { name }, qs); - returnData.push(responseData); + try { + const name = this.getNodeParameter('name', i) as string; + responseData = await sendGridApiRequest.call(this, '/marketing/lists', 'POST', { name }, qs); + returnData.push(responseData); + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; + } } } if (operation === 'delete') { for (let i = 0; i < length; i++) { - const listId = this.getNodeParameter('listId', i) as string; - qs.delete_contacts = this.getNodeParameter('deleteContacts', i) as boolean; - responseData = await sendGridApiRequest.call(this, `/marketing/lists/${listId}`, 'DELETE', {}, qs); - responseData = { success: true }; - returnData.push(responseData); + try { + const listId = this.getNodeParameter('listId', i) as string; + qs.delete_contacts = this.getNodeParameter('deleteContacts', i) as boolean; + responseData = await sendGridApiRequest.call(this, `/marketing/lists/${listId}`, 'DELETE', {}, qs); + responseData = { success: true }; + returnData.push(responseData); + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; + } } } if (operation === 'update') { for (let i = 0; i < length; i++) { - const name = this.getNodeParameter('name', i) as string; - const listId = this.getNodeParameter('listId', i) as string; - responseData = await sendGridApiRequest.call(this, `/marketing/lists/${listId}`, 'PATCH', { name }, qs); - returnData.push(responseData); + try { + const name = this.getNodeParameter('name', i) as string; + const listId = this.getNodeParameter('listId', i) as string; + responseData = await sendGridApiRequest.call(this, `/marketing/lists/${listId}`, 'PATCH', { name }, qs); + returnData.push(responseData); + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; + } } } } if (resource === 'mail') { if (operation === 'send') { for (let i = 0; i < length; i++) { + try { + const toEmail = this.getNodeParameter('toEmail', i) as string; - const toEmail = this.getNodeParameter('toEmail', i) as string; + const parsedToEmail = toEmail.includes(',') + ? toEmail.split(',').map((i) => ({ email: i.trim() })) + : [{ email: toEmail.trim() }]; - const parsedToEmail = toEmail.includes(',') - ? toEmail.split(',').map((i) => ({ email: i.trim() })) - : [{ email: toEmail.trim() }]; - - const { - bccEmail, - ccEmail, - enableSandbox, - sendAt, - headers, - attachments, - categories, - ipPoolName, - } = this.getNodeParameter('additionalFields', i) as { - bccEmail: string; - ccEmail: string; - enableSandbox: boolean, - sendAt: string; - headers: { details: Array<{ key: string; value: string }> }; - attachments: string; - categories: string; - ipPoolName: string; - }; - - const body: SendMailBody = { - personalizations: [{ - to: parsedToEmail, - }], - from: { - email: (this.getNodeParameter('fromEmail', i) as string).trim(), - name: this.getNodeParameter('fromName', i) as string, - }, - mail_settings: { - sandbox_mode: { - enable: enableSandbox || false, - }, - }, - }; - - const dynamicTemplateEnabled = this.getNodeParameter('dynamicTemplate', i); - - // dynamic template - if (dynamicTemplateEnabled) { - body.template_id = this.getNodeParameter('templateId', i) as string; - - const { fields } = this.getNodeParameter('dynamicTemplateFields', i) as { - fields: Array<{ [key: string]: string }> + const { + bccEmail, + ccEmail, + enableSandbox, + sendAt, + headers, + attachments, + categories, + ipPoolName, + } = this.getNodeParameter('additionalFields', i) as { + bccEmail: string; + ccEmail: string; + enableSandbox: boolean, + sendAt: string; + headers: { details: Array<{ key: string; value: string }> }; + attachments: string; + categories: string; + ipPoolName: string; }; - if (fields) { - body.personalizations[0].dynamic_template_data = {}; - fields.forEach(field => { - body.personalizations[0].dynamic_template_data![field.key] = field.value; - }); - } + const body: SendMailBody = { + personalizations: [{ + to: parsedToEmail, + }], + from: { + email: (this.getNodeParameter('fromEmail', i) as string).trim(), + name: this.getNodeParameter('fromName', i) as string, + }, + mail_settings: { + sandbox_mode: { + enable: enableSandbox || false, + }, + }, + }; - // message body - } else { - body.personalizations[0].subject = this.getNodeParameter('subject', i) as string; - body.content = [{ - type: this.getNodeParameter('contentType', i) as string, - value: this.getNodeParameter('contentValue', i) as string, - }]; - } + const dynamicTemplateEnabled = this.getNodeParameter('dynamicTemplate', i); - if (attachments) { - const attachmentsToSend = []; - const binaryProperties = attachments.split(',').map((p) => p.trim()); + // dynamic template + if (dynamicTemplateEnabled) { + body.template_id = this.getNodeParameter('templateId', i) as string; - for (const property of binaryProperties) { - if (!items[i].binary?.hasOwnProperty(property)) { - throw new NodeOperationError(this.getNode(), `The binary property ${property} does not exist`); + const { fields } = this.getNodeParameter('dynamicTemplateFields', i) as { + fields: Array<{ [key: string]: string }> + }; + + if (fields) { + body.personalizations[0].dynamic_template_data = {}; + fields.forEach(field => { + body.personalizations[0].dynamic_template_data![field.key] = field.value; + }); } - const binaryProperty = items[i].binary![property]; - - attachmentsToSend.push({ - content: binaryProperty.data, - filename: binaryProperty.fileName || 'unknown', - type: binaryProperty.mimeType, - }); + // message body + } else { + body.personalizations[0].subject = this.getNodeParameter('subject', i) as string; + body.content = [{ + type: this.getNodeParameter('contentType', i) as string, + value: this.getNodeParameter('contentValue', i) as string, + }]; } - if (attachmentsToSend.length) { - body.attachments = attachmentsToSend; + if (attachments) { + const attachmentsToSend = []; + const binaryProperties = attachments.split(',').map((p) => p.trim()); + + for (const property of binaryProperties) { + if (!items[i].binary?.hasOwnProperty(property)) { + throw new NodeOperationError(this.getNode(), `The binary property ${property} does not exist`); + } + + const binaryProperty = items[i].binary![property]; + + attachmentsToSend.push({ + content: binaryProperty.data, + filename: binaryProperty.fileName || 'unknown', + type: binaryProperty.mimeType, + }); + } + + if (attachmentsToSend.length) { + body.attachments = attachmentsToSend; + } } + + if (bccEmail) { + body.personalizations[0].bcc = bccEmail.split(',').map(i => ({ email: i.trim() })); + } + + if (ccEmail) { + body.personalizations[0].cc = ccEmail.split(',').map(i => ({ email: i.trim() })); + } + + if (headers?.details.length) { + const parsedHeaders: { [key: string]: string } = {}; + headers.details.forEach(obj => parsedHeaders[obj['key']] = obj['value']); + body.headers = parsedHeaders; + } + + if (categories) { + body.categories = categories.split(',') as string[]; + } + + if (ipPoolName) { + body.ip_pool_name = ipPoolName as string; + } + + if (sendAt) { + body.personalizations[0].send_at = moment.tz(sendAt, timezone).unix(); + } + + const data = await sendGridApiRequest.call(this, '/mail/send', 'POST', body, qs, { resolveWithFullResponse: true }); + + returnData.push({ messageId: data!.headers['x-message-id'] }); + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } - - if (bccEmail) { - body.personalizations[0].bcc = bccEmail.split(',').map(i => ({ email: i.trim() })); - } - - if (ccEmail) { - body.personalizations[0].cc = ccEmail.split(',').map(i => ({ email: i.trim() })); - } - - if (headers?.details.length) { - const parsedHeaders: { [key: string]: string } = {}; - headers.details.forEach(obj => parsedHeaders[obj['key']] = obj['value']); - body.headers = parsedHeaders; - } - - if (categories) { - body.categories = categories.split(',') as string[]; - } - - if (ipPoolName) { - body.ip_pool_name = ipPoolName as string; - } - - if (sendAt) { - body.personalizations[0].send_at = moment.tz(sendAt, timezone).unix(); - } - - const data = await sendGridApiRequest.call(this, '/mail/send', 'POST', body, qs, { resolveWithFullResponse: true }); - - returnData.push({ messageId: data!.headers['x-message-id'] }); } } } diff --git a/packages/nodes-base/nodes/SentryIo/SentryIo.node.ts b/packages/nodes-base/nodes/SentryIo/SentryIo.node.ts index fa8aeab7c8..294f86580c 100644 --- a/packages/nodes-base/nodes/SentryIo/SentryIo.node.ts +++ b/packages/nodes-base/nodes/SentryIo/SentryIo.node.ts @@ -317,445 +317,453 @@ export class SentryIo implements INodeType { const operation = this.getNodeParameter('operation', 0) as string; for (let i = 0; i < length; i++) { - if (resource === 'event') { - if (operation === 'getAll') { - const organizationSlug = this.getNodeParameter('organizationSlug', i) as string; - const projectSlug = this.getNodeParameter('projectSlug', i) as string; - const full = this.getNodeParameter('full', i) as boolean; - const returnAll = this.getNodeParameter('returnAll', i) as boolean; + try { + if (resource === 'event') { + if (operation === 'getAll') { + const organizationSlug = this.getNodeParameter('organizationSlug', i) as string; + const projectSlug = this.getNodeParameter('projectSlug', i) as string; + const full = this.getNodeParameter('full', i) as boolean; + const returnAll = this.getNodeParameter('returnAll', i) as boolean; - const endpoint = `/api/0/projects/${organizationSlug}/${projectSlug}/events/`; + const endpoint = `/api/0/projects/${organizationSlug}/${projectSlug}/events/`; - if (returnAll === false) { - const limit = this.getNodeParameter('limit', i) as number; - qs.limit = limit; + if (returnAll === false) { + const limit = this.getNodeParameter('limit', i) as number; + qs.limit = limit; + } + + qs.full = full; + + responseData = await sentryApiRequestAllItems.call(this, 'GET', endpoint, {}, qs); + + if (returnAll === false) { + const limit = this.getNodeParameter('limit', i) as number; + responseData = responseData.splice(0, limit); + } } + if (operation === 'get') { + const organizationSlug = this.getNodeParameter('organizationSlug', i) as string; + const projectSlug = this.getNodeParameter('projectSlug', i) as string; + const eventId = this.getNodeParameter('eventId', i) as string; - qs.full = full; + const endpoint = `/api/0/projects/${organizationSlug}/${projectSlug}/events/${eventId}/`; - responseData = await sentryApiRequestAllItems.call(this, 'GET', endpoint, {}, qs); - - if (returnAll === false) { - const limit = this.getNodeParameter('limit', i) as number; - responseData = responseData.splice(0, limit); + responseData = await sentryIoApiRequest.call(this, 'GET', endpoint, qs); } } - if (operation === 'get') { - const organizationSlug = this.getNodeParameter('organizationSlug', i) as string; - const projectSlug = this.getNodeParameter('projectSlug', i) as string; - const eventId = this.getNodeParameter('eventId', i) as string; + if (resource === 'issue') { + if (operation === 'getAll') { + const organizationSlug = this.getNodeParameter('organizationSlug', i) as string; + const projectSlug = this.getNodeParameter('projectSlug', i) as string; + const returnAll = this.getNodeParameter('returnAll', i) as boolean; - const endpoint = `/api/0/projects/${organizationSlug}/${projectSlug}/events/${eventId}/`; + const endpoint = `/api/0/projects/${organizationSlug}/${projectSlug}/issues/`; - responseData = await sentryIoApiRequest.call(this, 'GET', endpoint, qs); - } - } - if (resource === 'issue') { - if (operation === 'getAll') { - const organizationSlug = this.getNodeParameter('organizationSlug', i) as string; - const projectSlug = this.getNodeParameter('projectSlug', i) as string; - const returnAll = this.getNodeParameter('returnAll', i) as boolean; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const endpoint = `/api/0/projects/${organizationSlug}/${projectSlug}/issues/`; + if (additionalFields.statsPeriod) { + qs.statsPeriod = additionalFields.statsPeriod as string; + } + if (additionalFields.shortIdLookup) { + qs.shortIdLookup = additionalFields.shortIdLookup as boolean; + } + if (additionalFields.query) { + qs.query = additionalFields.query as string; + } - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + if (returnAll === false) { + const limit = this.getNodeParameter('limit', i) as number; + qs.limit = limit; + } + + responseData = await sentryApiRequestAllItems.call(this, 'GET', endpoint, {}, qs); + + if (returnAll === false) { + const limit = this.getNodeParameter('limit', i) as number; + responseData = responseData.splice(0, limit); + } - if (additionalFields.statsPeriod) { - qs.statsPeriod = additionalFields.statsPeriod as string; } - if (additionalFields.shortIdLookup) { - qs.shortIdLookup = additionalFields.shortIdLookup as boolean; + if (operation === 'get') { + const issueId = this.getNodeParameter('issueId', i) as string; + const endpoint = `/api/0/issues/${issueId}/`; + + responseData = await sentryIoApiRequest.call(this, 'GET', endpoint, qs); } - if (additionalFields.query) { - qs.query = additionalFields.query as string; + if (operation === 'delete') { + const issueId = this.getNodeParameter('issueId', i) as string; + const endpoint = `/api/0/issues/${issueId}/`; + + responseData = await sentryIoApiRequest.call(this, 'DELETE', endpoint, qs); + + responseData = { success: true }; } + if (operation === 'update') { + const issueId = this.getNodeParameter('issueId', i) as string; + const endpoint = `/api/0/issues/${issueId}/`; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - if (returnAll === false) { - const limit = this.getNodeParameter('limit', i) as number; - qs.limit = limit; - } + if (additionalFields.status) { + qs.status = additionalFields.status as string; + } + if (additionalFields.assignedTo) { + qs.assignedTo = additionalFields.assignedTo as string; + } + if (additionalFields.hasSeen) { + qs.hasSeen = additionalFields.hasSeen as boolean; + } + if (additionalFields.isBookmarked) { + qs.isBookmarked = additionalFields.isBookmarked as boolean; + } + if (additionalFields.isSubscribed) { + qs.isSubscribed = additionalFields.isSubscribed as boolean; + } + if (additionalFields.isPublic) { + qs.isPublic = additionalFields.isPublic as boolean; + } - responseData = await sentryApiRequestAllItems.call(this, 'GET', endpoint, {}, qs); - - if (returnAll === false) { - const limit = this.getNodeParameter('limit', i) as number; - responseData = responseData.splice(0, limit); - } - - } - if (operation === 'get') { - const issueId = this.getNodeParameter('issueId', i) as string; - const endpoint = `/api/0/issues/${issueId}/`; - - responseData = await sentryIoApiRequest.call(this, 'GET', endpoint, qs); - } - if (operation === 'delete') { - const issueId = this.getNodeParameter('issueId', i) as string; - const endpoint = `/api/0/issues/${issueId}/`; - - responseData = await sentryIoApiRequest.call(this, 'DELETE', endpoint, qs); - - responseData = { success: true }; - } - if (operation === 'update') { - const issueId = this.getNodeParameter('issueId', i) as string; - const endpoint = `/api/0/issues/${issueId}/`; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - - if (additionalFields.status) { - qs.status = additionalFields.status as string; - } - if (additionalFields.assignedTo) { - qs.assignedTo = additionalFields.assignedTo as string; - } - if (additionalFields.hasSeen) { - qs.hasSeen = additionalFields.hasSeen as boolean; - } - if (additionalFields.isBookmarked) { - qs.isBookmarked = additionalFields.isBookmarked as boolean; - } - if (additionalFields.isSubscribed) { - qs.isSubscribed = additionalFields.isSubscribed as boolean; - } - if (additionalFields.isPublic) { - qs.isPublic = additionalFields.isPublic as boolean; - } - - responseData = await sentryIoApiRequest.call(this, 'PUT', endpoint, qs); - } - } - if (resource === 'organization') { - if (operation === 'get') { - const organizationSlug = this.getNodeParameter('organizationSlug', i) as string; - const endpoint = `/api/0/organizations/${organizationSlug}/`; - - responseData = await sentryIoApiRequest.call(this, 'GET', endpoint, qs); - } - if (operation === 'getAll') { - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const endpoint = `/api/0/organizations/`; - - if (additionalFields.member) { - qs.member = additionalFields.member as boolean; - } - if (additionalFields.owner) { - qs.owner = additionalFields.owner as boolean; - } - - if (returnAll === false) { - const limit = this.getNodeParameter('limit', i) as number; - qs.limit = limit; - } - - responseData = await sentryApiRequestAllItems.call(this, 'GET', endpoint, {}, qs); - - if (responseData === undefined) { - responseData = []; - } - - if (returnAll === false) { - const limit = this.getNodeParameter('limit', i) as number; - responseData = responseData.splice(0, limit); + responseData = await sentryIoApiRequest.call(this, 'PUT', endpoint, qs); } } - if (operation === 'create') { - const name = this.getNodeParameter('name', i) as string; - const agreeTerms = this.getNodeParameter('agreeTerms', i) as boolean; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const endpoint = `/api/0/organizations/`; + if (resource === 'organization') { + if (operation === 'get') { + const organizationSlug = this.getNodeParameter('organizationSlug', i) as string; + const endpoint = `/api/0/organizations/${organizationSlug}/`; - qs.name = name; - qs.agreeTerms = agreeTerms; - - if (additionalFields.slug) { - qs.slug = additionalFields.slug as string; + responseData = await sentryIoApiRequest.call(this, 'GET', endpoint, qs); } + if (operation === 'getAll') { + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const endpoint = `/api/0/organizations/`; - responseData = await sentryIoApiRequest.call(this, 'POST', endpoint, qs); - } - if (operation === 'update') { - const organizationSlug = this.getNodeParameter('organization_slug', i) as string; - const endpoint = `/api/0/organizations/${organizationSlug}/`; + if (additionalFields.member) { + qs.member = additionalFields.member as boolean; + } + if (additionalFields.owner) { + qs.owner = additionalFields.owner as boolean; + } - const body = this.getNodeParameter('updateFields', i) as IDataObject; + if (returnAll === false) { + const limit = this.getNodeParameter('limit', i) as number; + qs.limit = limit; + } - responseData = await sentryIoApiRequest.call(this, 'PUT', endpoint, body, qs); - } - } - if (resource === 'project') { - if (operation === 'create') { - const organizationSlug = this.getNodeParameter('organizationSlug', i) as string; - const teamSlug = this.getNodeParameter('teamSlug', i) as string; - const name = this.getNodeParameter('name', i) as string; + responseData = await sentryApiRequestAllItems.call(this, 'GET', endpoint, {}, qs); - const endpoint = `/api/0/teams/${organizationSlug}/${teamSlug}/projects/`; + if (responseData === undefined) { + responseData = []; + } - const body = { - name, - ...this.getNodeParameter('additionalFields', i) as IDataObject, - }; - - responseData = await sentryIoApiRequest.call(this, 'POST', endpoint, body, qs); - } - if (operation === 'get') { - const organizationSlug = this.getNodeParameter('organizationSlug', i) as string; - const projectSlug = this.getNodeParameter('projectSlug', i) as string; - const endpoint = `/api/0/projects/${organizationSlug}/${projectSlug}/`; - - responseData = await sentryIoApiRequest.call(this, 'GET', endpoint, qs); - } - if (operation === 'getAll') { - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - const endpoint = `/api/0/projects/`; - - if (returnAll === false) { - const limit = this.getNodeParameter('limit', i) as number; - qs.limit = limit; + if (returnAll === false) { + const limit = this.getNodeParameter('limit', i) as number; + responseData = responseData.splice(0, limit); + } } + if (operation === 'create') { + const name = this.getNodeParameter('name', i) as string; + const agreeTerms = this.getNodeParameter('agreeTerms', i) as boolean; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const endpoint = `/api/0/organizations/`; - responseData = await sentryApiRequestAllItems.call(this, 'GET', endpoint, {}, qs); + qs.name = name; + qs.agreeTerms = agreeTerms; - if (returnAll === false) { - const limit = this.getNodeParameter('limit', i) as number; - responseData = responseData.splice(0, limit); + if (additionalFields.slug) { + qs.slug = additionalFields.slug as string; + } + + responseData = await sentryIoApiRequest.call(this, 'POST', endpoint, qs); + } + if (operation === 'update') { + const organizationSlug = this.getNodeParameter('organization_slug', i) as string; + const endpoint = `/api/0/organizations/${organizationSlug}/`; + + const body = this.getNodeParameter('updateFields', i) as IDataObject; + + responseData = await sentryIoApiRequest.call(this, 'PUT', endpoint, body, qs); } } - if (operation === 'update') { - const organizationSlug = this.getNodeParameter('organizationSlug', i) as string; - const projectSlug = this.getNodeParameter('projectSlug', i) as string; - const endpoint = `/api/0/projects/${organizationSlug}/${projectSlug}/`; - const body = this.getNodeParameter('updateFields', i) as IDataObject; + if (resource === 'project') { + if (operation === 'create') { + const organizationSlug = this.getNodeParameter('organizationSlug', i) as string; + const teamSlug = this.getNodeParameter('teamSlug', i) as string; + const name = this.getNodeParameter('name', i) as string; - responseData = await sentryIoApiRequest.call(this, 'PUT', endpoint, body, qs); - } - if (operation === 'delete') { - const organizationSlug = this.getNodeParameter('organizationSlug', i) as string; - const projectSlug = this.getNodeParameter('projectSlug', i) as string; - const endpoint = `/api/0/projects/${organizationSlug}/${projectSlug}/`; + const endpoint = `/api/0/teams/${organizationSlug}/${teamSlug}/projects/`; - responseData = await sentryIoApiRequest.call(this, 'DELETE', endpoint, qs); - responseData = { success: true }; - } - } - if (resource === 'release') { - if (operation === 'get') { - const organizationSlug = this.getNodeParameter('organizationSlug', i) as string; - const version = this.getNodeParameter('version', i) as string; - const endpoint = `/api/0/organizations/${organizationSlug}/releases/${version}/`; + const body = { + name, + ...this.getNodeParameter('additionalFields', i) as IDataObject, + }; - responseData = await sentryIoApiRequest.call(this, 'GET', endpoint, qs); - } - if (operation === 'getAll') { - const organizationSlug = this.getNodeParameter('organizationSlug', i) as string; - const endpoint = `/api/0/organizations/${organizationSlug}/releases/`; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - - if (additionalFields.query) { - qs.query = additionalFields.query as string; + responseData = await sentryIoApiRequest.call(this, 'POST', endpoint, body, qs); } + if (operation === 'get') { + const organizationSlug = this.getNodeParameter('organizationSlug', i) as string; + const projectSlug = this.getNodeParameter('projectSlug', i) as string; + const endpoint = `/api/0/projects/${organizationSlug}/${projectSlug}/`; - if (returnAll === false) { - const limit = this.getNodeParameter('limit', i) as number; - qs.limit = limit; + responseData = await sentryIoApiRequest.call(this, 'GET', endpoint, qs); } + if (operation === 'getAll') { + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + const endpoint = `/api/0/projects/`; - responseData = await sentryApiRequestAllItems.call(this, 'GET', endpoint, {}, qs); + if (returnAll === false) { + const limit = this.getNodeParameter('limit', i) as number; + qs.limit = limit; + } - if (returnAll === false) { - const limit = this.getNodeParameter('limit', i) as number; - responseData = responseData.splice(0, limit); + responseData = await sentryApiRequestAllItems.call(this, 'GET', endpoint, {}, qs); + + if (returnAll === false) { + const limit = this.getNodeParameter('limit', i) as number; + responseData = responseData.splice(0, limit); + } + } + if (operation === 'update') { + const organizationSlug = this.getNodeParameter('organizationSlug', i) as string; + const projectSlug = this.getNodeParameter('projectSlug', i) as string; + const endpoint = `/api/0/projects/${organizationSlug}/${projectSlug}/`; + const body = this.getNodeParameter('updateFields', i) as IDataObject; + + responseData = await sentryIoApiRequest.call(this, 'PUT', endpoint, body, qs); + } + if (operation === 'delete') { + const organizationSlug = this.getNodeParameter('organizationSlug', i) as string; + const projectSlug = this.getNodeParameter('projectSlug', i) as string; + const endpoint = `/api/0/projects/${organizationSlug}/${projectSlug}/`; + + responseData = await sentryIoApiRequest.call(this, 'DELETE', endpoint, qs); + responseData = { success: true }; } } - if (operation === 'delete') { - const organizationSlug = this.getNodeParameter('organizationSlug', i) as string; - const version = this.getNodeParameter('version', i) as string; - const endpoint = `/api/0/organizations/${organizationSlug}/releases/${version}/`; - responseData = await sentryIoApiRequest.call(this, 'DELETE', endpoint, qs); - responseData = { success: true }; + if (resource === 'release') { + if (operation === 'get') { + const organizationSlug = this.getNodeParameter('organizationSlug', i) as string; + const version = this.getNodeParameter('version', i) as string; + const endpoint = `/api/0/organizations/${organizationSlug}/releases/${version}/`; + + responseData = await sentryIoApiRequest.call(this, 'GET', endpoint, qs); + } + if (operation === 'getAll') { + const organizationSlug = this.getNodeParameter('organizationSlug', i) as string; + const endpoint = `/api/0/organizations/${organizationSlug}/releases/`; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + + if (additionalFields.query) { + qs.query = additionalFields.query as string; + } + + if (returnAll === false) { + const limit = this.getNodeParameter('limit', i) as number; + qs.limit = limit; + } + + responseData = await sentryApiRequestAllItems.call(this, 'GET', endpoint, {}, qs); + + if (returnAll === false) { + const limit = this.getNodeParameter('limit', i) as number; + responseData = responseData.splice(0, limit); + } + } + if (operation === 'delete') { + const organizationSlug = this.getNodeParameter('organizationSlug', i) as string; + const version = this.getNodeParameter('version', i) as string; + const endpoint = `/api/0/organizations/${organizationSlug}/releases/${version}/`; + responseData = await sentryIoApiRequest.call(this, 'DELETE', endpoint, qs); + responseData = { success: true }; + } + if (operation === 'create') { + const organizationSlug = this.getNodeParameter('organizationSlug', i) as string; + const endpoint = `/api/0/organizations/${organizationSlug}/releases/`; + const version = this.getNodeParameter('version', i) as string; + const url = this.getNodeParameter('url', i) as string; + const projects = this.getNodeParameter('projects', i) as string[]; + + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + + if (additionalFields.dateReleased) { + qs.dateReleased = additionalFields.dateReleased as string; + } + + qs.version = version; + qs.url = url; + qs.projects = projects; + + if (additionalFields.commits) { + const commits: ICommit[] = []; + //@ts-ignore + // tslint:disable-next-line: no-any + additionalFields.commits.commitProperties.map((commit: any) => { + const commitObject: ICommit = { id: commit.id }; + + if (commit.repository) { + commitObject.repository = commit.repository; + } + if (commit.message) { + commitObject.message = commit.message; + } + if (commit.patchSet && Array.isArray(commit.patchSet)) { + commit.patchSet.patchSetProperties.map((patchSet: IPatchSet) => { + commitObject.patch_set?.push(patchSet); + }); + } + if (commit.authorName) { + commitObject.author_name = commit.authorName; + } + if (commit.authorEmail) { + commitObject.author_email = commit.authorEmail; + } + if (commit.timestamp) { + commitObject.timestamp = commit.timestamp; + } + + commits.push(commitObject); + }); + + qs.commits = commits; + } + if (additionalFields.refs) { + const refs: IRef[] = []; + //@ts-ignore + additionalFields.refs.refProperties.map((ref: IRef) => { + refs.push(ref); + }); + + qs.refs = refs; + } + + responseData = await sentryIoApiRequest.call(this, 'POST', endpoint, qs); + } + if (operation === 'update') { + const organizationSlug = this.getNodeParameter('organizationSlug', i) as string; + const version = this.getNodeParameter('version', i) as string; + const endpoint = `/api/0/organizations/${organizationSlug}/releases/${version}/`; + + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + + const body = { ...updateFields }; + + if (updateFields.commits) { + const commits: ICommit[] = []; + //@ts-ignore + // tslint:disable-next-line: no-any + updateFields.commits.commitProperties.map((commit: any) => { + const commitObject: ICommit = { id: commit.id }; + + if (commit.repository) { + commitObject.repository = commit.repository; + } + if (commit.message) { + commitObject.message = commit.message; + } + if (commit.patchSet && Array.isArray(commit.patchSet)) { + commit.patchSet.patchSetProperties.map((patchSet: IPatchSet) => { + commitObject.patch_set?.push(patchSet); + }); + } + if (commit.authorName) { + commitObject.author_name = commit.authorName; + } + if (commit.authorEmail) { + commitObject.author_email = commit.authorEmail; + } + if (commit.timestamp) { + commitObject.timestamp = commit.timestamp; + } + + commits.push(commitObject); + }); + + body.commits = commits; + } + if (updateFields.refs) { + const refs: IRef[] = []; + //@ts-ignore + updateFields.refs.refProperties.map((ref: IRef) => { + refs.push(ref); + }); + + body.refs = refs; + } + + responseData = await sentryIoApiRequest.call(this, 'PUT', endpoint, body, qs); + } } - if (operation === 'create') { - const organizationSlug = this.getNodeParameter('organizationSlug', i) as string; - const endpoint = `/api/0/organizations/${organizationSlug}/releases/`; - const version = this.getNodeParameter('version', i) as string; - const url = this.getNodeParameter('url', i) as string; - const projects = this.getNodeParameter('projects', i) as string[]; + if (resource === 'team') { + if (operation === 'get') { + const organizationSlug = this.getNodeParameter('organizationSlug', i) as string; + const teamSlug = this.getNodeParameter('teamSlug', i) as string; + const endpoint = `/api/0/teams/${organizationSlug}/${teamSlug}/`; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + responseData = await sentryIoApiRequest.call(this, 'GET', endpoint, qs); + } + if (operation === 'getAll') { + const organizationSlug = this.getNodeParameter('organizationSlug', i) as string; + const endpoint = `/api/0/organizations/${organizationSlug}/teams/`; + const returnAll = this.getNodeParameter('returnAll', i) as boolean; - if (additionalFields.dateReleased) { - qs.dateReleased = additionalFields.dateReleased as string; + if (returnAll === false) { + const limit = this.getNodeParameter('limit', i) as number; + qs.limit = limit; + } + + responseData = await sentryApiRequestAllItems.call(this, 'GET', endpoint, {}, qs); + + if (returnAll === false) { + const limit = this.getNodeParameter('limit', i) as number; + responseData = responseData.splice(0, limit); + } } - qs.version = version; - qs.url = url; - qs.projects = projects; + if (operation === 'create') { + const organizationSlug = this.getNodeParameter('organizationSlug', i) as string; + const name = this.getNodeParameter('name', i) as string; + const endpoint = `/api/0/organizations/${organizationSlug}/teams/`; - if (additionalFields.commits) { - const commits: ICommit[] = []; - //@ts-ignore - // tslint:disable-next-line: no-any - additionalFields.commits.commitProperties.map((commit: any) => { - const commitObject: ICommit = { id: commit.id }; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - if (commit.repository) { - commitObject.repository = commit.repository; - } - if (commit.message) { - commitObject.message = commit.message; - } - if (commit.patchSet && Array.isArray(commit.patchSet)) { - commit.patchSet.patchSetProperties.map((patchSet: IPatchSet) => { - commitObject.patch_set?.push(patchSet); - }); - } - if (commit.authorName) { - commitObject.author_name = commit.authorName; - } - if (commit.authorEmail) { - commitObject.author_email = commit.authorEmail; - } - if (commit.timestamp) { - commitObject.timestamp = commit.timestamp; - } + qs.name = name; - commits.push(commitObject); - }); + if (additionalFields.slug) { + qs.slug = additionalFields.slug; + } - qs.commits = commits; + responseData = await sentryIoApiRequest.call(this, 'POST', endpoint, qs); } - if (additionalFields.refs) { - const refs: IRef[] = []; - //@ts-ignore - additionalFields.refs.refProperties.map((ref: IRef) => { - refs.push(ref); - }); + if (operation === 'update') { + const organizationSlug = this.getNodeParameter('organizationSlug', i) as string; + const teamSlug = this.getNodeParameter('teamSlug', i) as string; + const endpoint = `/api/0/teams/${organizationSlug}/${teamSlug}/`; - qs.refs = refs; + const body = this.getNodeParameter('updateFields', i) as IDataObject; + + responseData = await sentryIoApiRequest.call(this, 'PUT', endpoint, body, qs); } + if (operation === 'delete') { + const organizationSlug = this.getNodeParameter('organizationSlug', i) as string; + const teamSlug = this.getNodeParameter('teamSlug', i) as string; + const endpoint = `/api/0/teams/${organizationSlug}/${teamSlug}/`; - responseData = await sentryIoApiRequest.call(this, 'POST', endpoint, qs); - } - if (operation === 'update') { - const organizationSlug = this.getNodeParameter('organizationSlug', i) as string; - const version = this.getNodeParameter('version', i) as string; - const endpoint = `/api/0/organizations/${organizationSlug}/releases/${version}/`; - - const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; - - const body = { ...updateFields }; - - if (updateFields.commits) { - const commits: ICommit[] = []; - //@ts-ignore - // tslint:disable-next-line: no-any - updateFields.commits.commitProperties.map((commit: any) => { - const commitObject: ICommit = { id: commit.id }; - - if (commit.repository) { - commitObject.repository = commit.repository; - } - if (commit.message) { - commitObject.message = commit.message; - } - if (commit.patchSet && Array.isArray(commit.patchSet)) { - commit.patchSet.patchSetProperties.map((patchSet: IPatchSet) => { - commitObject.patch_set?.push(patchSet); - }); - } - if (commit.authorName) { - commitObject.author_name = commit.authorName; - } - if (commit.authorEmail) { - commitObject.author_email = commit.authorEmail; - } - if (commit.timestamp) { - commitObject.timestamp = commit.timestamp; - } - - commits.push(commitObject); - }); - - body.commits = commits; - } - if (updateFields.refs) { - const refs: IRef[] = []; - //@ts-ignore - updateFields.refs.refProperties.map((ref: IRef) => { - refs.push(ref); - }); - - body.refs = refs; - } - - responseData = await sentryIoApiRequest.call(this, 'PUT', endpoint, body, qs); - } - } - if (resource === 'team') { - if (operation === 'get') { - const organizationSlug = this.getNodeParameter('organizationSlug', i) as string; - const teamSlug = this.getNodeParameter('teamSlug', i) as string; - const endpoint = `/api/0/teams/${organizationSlug}/${teamSlug}/`; - - responseData = await sentryIoApiRequest.call(this, 'GET', endpoint, qs); - } - if (operation === 'getAll') { - const organizationSlug = this.getNodeParameter('organizationSlug', i) as string; - const endpoint = `/api/0/organizations/${organizationSlug}/teams/`; - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - - if (returnAll === false) { - const limit = this.getNodeParameter('limit', i) as number; - qs.limit = limit; - } - - responseData = await sentryApiRequestAllItems.call(this, 'GET', endpoint, {}, qs); - - if (returnAll === false) { - const limit = this.getNodeParameter('limit', i) as number; - responseData = responseData.splice(0, limit); + responseData = await sentryIoApiRequest.call(this, 'DELETE', endpoint, qs); + responseData = { success: true }; } } - if (operation === 'create') { - const organizationSlug = this.getNodeParameter('organizationSlug', i) as string; - const name = this.getNodeParameter('name', i) as string; - const endpoint = `/api/0/organizations/${organizationSlug}/teams/`; - - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - - qs.name = name; - - if (additionalFields.slug) { - qs.slug = additionalFields.slug; - } - - responseData = await sentryIoApiRequest.call(this, 'POST', endpoint, qs); + if (Array.isArray(responseData)) { + returnData.push.apply(returnData, responseData as IDataObject[]); + } else { + returnData.push(responseData as IDataObject); } - if (operation === 'update') { - const organizationSlug = this.getNodeParameter('organizationSlug', i) as string; - const teamSlug = this.getNodeParameter('teamSlug', i) as string; - const endpoint = `/api/0/teams/${organizationSlug}/${teamSlug}/`; - - const body = this.getNodeParameter('updateFields', i) as IDataObject; - - responseData = await sentryIoApiRequest.call(this, 'PUT', endpoint, body, qs); + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; } - if (operation === 'delete') { - const organizationSlug = this.getNodeParameter('organizationSlug', i) as string; - const teamSlug = this.getNodeParameter('teamSlug', i) as string; - const endpoint = `/api/0/teams/${organizationSlug}/${teamSlug}/`; - - responseData = await sentryIoApiRequest.call(this, 'DELETE', endpoint, qs); - responseData = { success: true }; - } - } - - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else { - returnData.push(responseData as IDataObject); + throw error; } } return [this.helpers.returnJsonArray(returnData)]; diff --git a/packages/nodes-base/nodes/Shopify/Shopify.node.ts b/packages/nodes-base/nodes/Shopify/Shopify.node.ts index a97fffb48e..80f65bb137 100644 --- a/packages/nodes-base/nodes/Shopify/Shopify.node.ts +++ b/packages/nodes-base/nodes/Shopify/Shopify.node.ts @@ -131,240 +131,248 @@ export class Shopify implements INodeType { 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 === 'order') { - //https://shopify.dev/docs/admin-api/rest/reference/orders/order#create-2020-04 - if (operation === 'create') { - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const discount = additionalFields.discountCodesUi as IDataObject; - const billing = additionalFields.billingAddressUi as IDataObject; - const shipping = additionalFields.shippingAddressUi as IDataObject; - const lineItem = (this.getNodeParameter('limeItemsUi', i) as IDataObject).lineItemValues as IDataObject[]; - if (lineItem === undefined) { - throw new NodeOperationError(this.getNode(), 'At least one line item has to be added'); - } - const body: IOrder = { - test: true, - line_items: keysToSnakeCase(lineItem) as ILineItem[], - }; - if (additionalFields.fulfillmentStatus) { - body.fulfillment_status = additionalFields.fulfillmentStatus as string; - } - if (additionalFields.inventoryBehaviour) { - body.inventory_behaviour = additionalFields.inventoryBehaviour as string; - } - if (additionalFields.locationId) { - body.location_id = additionalFields.locationId as number; - } - if (additionalFields.note) { - body.note = additionalFields.note as string; - } - if (additionalFields.sendFulfillmentReceipt) { - body.send_fulfillment_receipt = additionalFields.sendFulfillmentReceipt as boolean; - } - if (additionalFields.sendReceipt) { - body.send_receipt = additionalFields.sendReceipt as boolean; - } - if (additionalFields.sendReceipt) { - body.send_receipt = additionalFields.sendReceipt as boolean; - } - if (additionalFields.sourceName) { - body.source_name = additionalFields.sourceName as string; - } - if (additionalFields.tags) { - body.tags = additionalFields.tags as string; - } - if (additionalFields.test) { - body.test = additionalFields.test as boolean; - } - if (additionalFields.email) { - body.email = additionalFields.email as string; - } - if (discount) { - body.discount_codes = discount.discountCodesValues as IDiscountCode[]; - } - if (billing) { - body.billing_address = keysToSnakeCase(billing.billingAddressValues as IDataObject)[0] as IAddress; - } - if (shipping) { - body.shipping_address = keysToSnakeCase(shipping.shippingAddressValues as IDataObject)[0] as IAddress; - } - responseData = await shopifyApiRequest.call(this, 'POST', '/orders.json', { order: body }); - responseData = responseData.order; - } - //https://shopify.dev/docs/admin-api/rest/reference/orders/order#destroy-2020-04 - if (operation === 'delete') { - const orderId = this.getNodeParameter('orderId', i) as string; - responseData = await shopifyApiRequest.call(this, 'DELETE', `/orders/${orderId}.json`); - responseData = { success: true }; - } - //https://shopify.dev/docs/admin-api/rest/reference/orders/order#show-2020-04 - if (operation === 'get') { - const orderId = this.getNodeParameter('orderId', i) as string; - const options = this.getNodeParameter('options', i) as IDataObject; - if (options.fields) { - qs.fields = options.fields as string; - } - responseData = await shopifyApiRequest.call(this, 'GET', `/orders/${orderId}.json`, {}, qs); - responseData = responseData.order; - } - //https://shopify.dev/docs/admin-api/rest/reference/orders/order#index-2020-04 - 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; - } - if (options.attributionAppId) { - qs.attribution_app_id = options.attributionAppId as string; - } - if (options.createdAtMin) { - qs.created_at_min = options.createdAtMin as string; - } - if (options.createdAtMax) { - qs.created_at_max = options.createdAtMax as string; - } - if (options.updatedAtMax) { - qs.updated_at_max = options.updatedAtMax as string; - } - if (options.updatedAtMin) { - qs.updated_at_min = options.updatedAtMin as string; - } - if (options.processedAtMin) { - qs.processed_at_min = options.processedAtMin as string; - } - if (options.processedAtMax) { - qs.processed_at_max = options.processedAtMax as string; - } - if (options.sinceId) { - qs.since_id = options.sinceId as string; - } - if (options.ids) { - qs.ids = options.ids as string; - } - if (options.status) { - qs.status = options.status as string; - } - if (options.financialStatus) { - qs.financial_status = options.financialStatus as string; - } - if (options.fulfillmentStatus) { - qs.fulfillment_status = options.fulfillmentStatus as string; - } - - if (returnAll === true) { - responseData = await shopifyApiRequestAllItems.call(this, 'orders', 'GET', '/orders.json', {}, qs); - } else { - qs.limit = this.getNodeParameter('limit', i) as number; - responseData = await shopifyApiRequest.call(this, 'GET', '/orders.json', {}, qs); - responseData = responseData.orders; - } - } - //https://shopify.dev/docs/admin-api/rest/reference/orders/order#update-2019-10 - if (operation === 'update') { - const orderId = this.getNodeParameter('orderId', i) as string; - const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; - const shipping = updateFields.shippingAddressUi as IDataObject; - const body: IOrder = {}; - if (updateFields.locationId) { - body.location_id = updateFields.locationId as number; - } - if (updateFields.note) { - body.note = updateFields.note as string; - } - if (updateFields.sourceName) { - body.source_name = updateFields.sourceName as string; - } - if (updateFields.tags) { - body.tags = updateFields.tags as string; - } - if (updateFields.email) { - body.email = updateFields.email as string; - } - if (shipping) { - body.shipping_address = keysToSnakeCase(shipping.shippingAddressValues as IDataObject)[0] as IAddress; - } - responseData = await shopifyApiRequest.call(this, 'PUT', `/orders/${orderId}.json`, { order: body }); - responseData = responseData.order; - } - } else if (resource === 'product') { - const productId = this.getNodeParameter('productId', i, '') as string; - let body: IProduct = {}; - //https://shopify.dev/docs/admin-api/rest/reference/products/product#create-2020-04 - if (operation === 'create') { - const title = this.getNodeParameter('title', i) as string; - - const additionalFields = this.getNodeParameter('additionalFields', i, {}) as IDataObject; - - if (additionalFields.productOptions) { - const metadata = (additionalFields.productOptions as IDataObject).option as IDataObject[]; - additionalFields.options = {}; - for (const data of metadata) { - //@ts-ignore - additionalFields.options[data.name as string] = data.value; + try { + if (resource === 'order') { + //https://shopify.dev/docs/admin-api/rest/reference/orders/order#create-2020-04 + if (operation === 'create') { + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const discount = additionalFields.discountCodesUi as IDataObject; + const billing = additionalFields.billingAddressUi as IDataObject; + const shipping = additionalFields.shippingAddressUi as IDataObject; + const lineItem = (this.getNodeParameter('limeItemsUi', i) as IDataObject).lineItemValues as IDataObject[]; + if (lineItem === undefined) { + throw new NodeOperationError(this.getNode(), 'At least one line item has to be added'); } - delete additionalFields.productOptions; - } - - body = additionalFields; - - body.title = title; - - responseData = await shopifyApiRequest.call(this, 'POST', '/products.json', { product: body }); - responseData = responseData.product; - } - if (operation === 'delete') { - //https://shopify.dev/docs/admin-api/rest/reference/products/product#destroy-2020-04 - responseData = await shopifyApiRequest.call(this, 'DELETE', `/products/${productId}.json`); - responseData = { success: true }; - } - if (operation === 'get') { - //https://shopify.dev/docs/admin-api/rest/reference/products/product#show-2020-04 - const additionalFields = this.getNodeParameter('additionalFields', i, {}) as IDataObject; - Object.assign(qs, additionalFields); - responseData = await shopifyApiRequest.call(this, 'GET', `/products/${productId}.json`, {}, qs); - responseData = responseData.product; - } - if (operation === 'getAll') { - //https://shopify.dev/docs/admin-api/rest/reference/products/product#index-2020-04 - const additionalFields = this.getNodeParameter('additionalFields', i, {}) as IDataObject; - - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - - Object.assign(qs, additionalFields); - - if (returnAll === true) { - responseData = await shopifyApiRequestAllItems.call(this, 'products', 'GET', '/products.json', {}, qs); - } else { - qs.limit = this.getNodeParameter('limit', i) as number; - responseData = await shopifyApiRequest.call(this, 'GET', '/products.json', {}, qs); - responseData = responseData.products; - } - } - if (operation === 'update') { - //https://shopify.dev/docs/admin-api/rest/reference/products/product?api[version]=2020-07#update-2020-07 - const updateFields = this.getNodeParameter('updateFields', i, {}) as IDataObject; - - if (updateFields.productOptions) { - const metadata = (updateFields.productOptions as IDataObject).option as IDataObject[]; - updateFields.options = {}; - for (const data of metadata) { - //@ts-ignore - updateFields.options[data.name as string] = data.value; + const body: IOrder = { + test: true, + line_items: keysToSnakeCase(lineItem) as ILineItem[], + }; + if (additionalFields.fulfillmentStatus) { + body.fulfillment_status = additionalFields.fulfillmentStatus as string; } - delete updateFields.productOptions; + if (additionalFields.inventoryBehaviour) { + body.inventory_behaviour = additionalFields.inventoryBehaviour as string; + } + if (additionalFields.locationId) { + body.location_id = additionalFields.locationId as number; + } + if (additionalFields.note) { + body.note = additionalFields.note as string; + } + if (additionalFields.sendFulfillmentReceipt) { + body.send_fulfillment_receipt = additionalFields.sendFulfillmentReceipt as boolean; + } + if (additionalFields.sendReceipt) { + body.send_receipt = additionalFields.sendReceipt as boolean; + } + if (additionalFields.sendReceipt) { + body.send_receipt = additionalFields.sendReceipt as boolean; + } + if (additionalFields.sourceName) { + body.source_name = additionalFields.sourceName as string; + } + if (additionalFields.tags) { + body.tags = additionalFields.tags as string; + } + if (additionalFields.test) { + body.test = additionalFields.test as boolean; + } + if (additionalFields.email) { + body.email = additionalFields.email as string; + } + if (discount) { + body.discount_codes = discount.discountCodesValues as IDiscountCode[]; + } + if (billing) { + body.billing_address = keysToSnakeCase(billing.billingAddressValues as IDataObject)[0] as IAddress; + } + if (shipping) { + body.shipping_address = keysToSnakeCase(shipping.shippingAddressValues as IDataObject)[0] as IAddress; + } + responseData = await shopifyApiRequest.call(this, 'POST', '/orders.json', { order: body }); + responseData = responseData.order; } + //https://shopify.dev/docs/admin-api/rest/reference/orders/order#destroy-2020-04 + if (operation === 'delete') { + const orderId = this.getNodeParameter('orderId', i) as string; + responseData = await shopifyApiRequest.call(this, 'DELETE', `/orders/${orderId}.json`); + responseData = { success: true }; + } + //https://shopify.dev/docs/admin-api/rest/reference/orders/order#show-2020-04 + if (operation === 'get') { + const orderId = this.getNodeParameter('orderId', i) as string; + const options = this.getNodeParameter('options', i) as IDataObject; + if (options.fields) { + qs.fields = options.fields as string; + } + responseData = await shopifyApiRequest.call(this, 'GET', `/orders/${orderId}.json`, {}, qs); + responseData = responseData.order; + } + //https://shopify.dev/docs/admin-api/rest/reference/orders/order#index-2020-04 + 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; + } + if (options.attributionAppId) { + qs.attribution_app_id = options.attributionAppId as string; + } + if (options.createdAtMin) { + qs.created_at_min = options.createdAtMin as string; + } + if (options.createdAtMax) { + qs.created_at_max = options.createdAtMax as string; + } + if (options.updatedAtMax) { + qs.updated_at_max = options.updatedAtMax as string; + } + if (options.updatedAtMin) { + qs.updated_at_min = options.updatedAtMin as string; + } + if (options.processedAtMin) { + qs.processed_at_min = options.processedAtMin as string; + } + if (options.processedAtMax) { + qs.processed_at_max = options.processedAtMax as string; + } + if (options.sinceId) { + qs.since_id = options.sinceId as string; + } + if (options.ids) { + qs.ids = options.ids as string; + } + if (options.status) { + qs.status = options.status as string; + } + if (options.financialStatus) { + qs.financial_status = options.financialStatus as string; + } + if (options.fulfillmentStatus) { + qs.fulfillment_status = options.fulfillmentStatus as string; + } - body = updateFields; + if (returnAll === true) { + responseData = await shopifyApiRequestAllItems.call(this, 'orders', 'GET', '/orders.json', {}, qs); + } else { + qs.limit = this.getNodeParameter('limit', i) as number; + responseData = await shopifyApiRequest.call(this, 'GET', '/orders.json', {}, qs); + responseData = responseData.orders; + } + } + //https://shopify.dev/docs/admin-api/rest/reference/orders/order#update-2019-10 + if (operation === 'update') { + const orderId = this.getNodeParameter('orderId', i) as string; + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + const shipping = updateFields.shippingAddressUi as IDataObject; + const body: IOrder = {}; + if (updateFields.locationId) { + body.location_id = updateFields.locationId as number; + } + if (updateFields.note) { + body.note = updateFields.note as string; + } + if (updateFields.sourceName) { + body.source_name = updateFields.sourceName as string; + } + if (updateFields.tags) { + body.tags = updateFields.tags as string; + } + if (updateFields.email) { + body.email = updateFields.email as string; + } + if (shipping) { + body.shipping_address = keysToSnakeCase(shipping.shippingAddressValues as IDataObject)[0] as IAddress; + } + responseData = await shopifyApiRequest.call(this, 'PUT', `/orders/${orderId}.json`, { order: body }); + responseData = responseData.order; + } + } else if (resource === 'product') { + const productId = this.getNodeParameter('productId', i, '') as string; + let body: IProduct = {}; + //https://shopify.dev/docs/admin-api/rest/reference/products/product#create-2020-04 + if (operation === 'create') { + const title = this.getNodeParameter('title', i) as string; - responseData = await shopifyApiRequest.call(this, 'PUT', `/products/${productId}.json`, { product: body }); + const additionalFields = this.getNodeParameter('additionalFields', i, {}) as IDataObject; - responseData = responseData.product; + if (additionalFields.productOptions) { + const metadata = (additionalFields.productOptions as IDataObject).option as IDataObject[]; + additionalFields.options = {}; + for (const data of metadata) { + //@ts-ignore + additionalFields.options[data.name as string] = data.value; + } + delete additionalFields.productOptions; + } + + body = additionalFields; + + body.title = title; + + responseData = await shopifyApiRequest.call(this, 'POST', '/products.json', { product: body }); + responseData = responseData.product; + } + if (operation === 'delete') { + //https://shopify.dev/docs/admin-api/rest/reference/products/product#destroy-2020-04 + responseData = await shopifyApiRequest.call(this, 'DELETE', `/products/${productId}.json`); + responseData = { success: true }; + } + if (operation === 'get') { + //https://shopify.dev/docs/admin-api/rest/reference/products/product#show-2020-04 + const additionalFields = this.getNodeParameter('additionalFields', i, {}) as IDataObject; + Object.assign(qs, additionalFields); + responseData = await shopifyApiRequest.call(this, 'GET', `/products/${productId}.json`, {}, qs); + responseData = responseData.product; + } + if (operation === 'getAll') { + //https://shopify.dev/docs/admin-api/rest/reference/products/product#index-2020-04 + const additionalFields = this.getNodeParameter('additionalFields', i, {}) as IDataObject; + + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + + Object.assign(qs, additionalFields); + + if (returnAll === true) { + responseData = await shopifyApiRequestAllItems.call(this, 'products', 'GET', '/products.json', {}, qs); + } else { + qs.limit = this.getNodeParameter('limit', i) as number; + responseData = await shopifyApiRequest.call(this, 'GET', '/products.json', {}, qs); + responseData = responseData.products; + } + } + if (operation === 'update') { + //https://shopify.dev/docs/admin-api/rest/reference/products/product?api[version]=2020-07#update-2020-07 + const updateFields = this.getNodeParameter('updateFields', i, {}) as IDataObject; + + if (updateFields.productOptions) { + const metadata = (updateFields.productOptions as IDataObject).option as IDataObject[]; + updateFields.options = {}; + for (const data of metadata) { + //@ts-ignore + updateFields.options[data.name as string] = data.value; + } + delete updateFields.productOptions; + } + + body = updateFields; + + responseData = await shopifyApiRequest.call(this, 'PUT', `/products/${productId}.json`, { product: body }); + + responseData = responseData.product; + } } - } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else { - returnData.push(responseData); + if (Array.isArray(responseData)) { + returnData.push.apply(returnData, responseData as IDataObject[]); + } else { + returnData.push(responseData); + } + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } } return [this.helpers.returnJsonArray(returnData)]; diff --git a/packages/nodes-base/nodes/Signl4/Signl4.node.ts b/packages/nodes-base/nodes/Signl4/Signl4.node.ts index 390d1fd1c2..34fa8497f3 100644 --- a/packages/nodes-base/nodes/Signl4/Signl4.node.ts +++ b/packages/nodes-base/nodes/Signl4/Signl4.node.ts @@ -260,115 +260,123 @@ export class Signl4 implements INodeType { 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 === 'alert') { - //https://connect.signl4.com/webhook/docs/index.html - // Send alert - if (operation === 'send') { - const message = this.getNodeParameter('message', i) as string; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + try { + if (resource === 'alert') { + //https://connect.signl4.com/webhook/docs/index.html + // Send alert + if (operation === 'send') { + const message = this.getNodeParameter('message', i) as string; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const data: IDataObject = { - message, - }; + const data: IDataObject = { + message, + }; - if (additionalFields.title) { - data.title = additionalFields.title as string; - } - - if (additionalFields.service) { - data.service = additionalFields.service as string; - } - if (additionalFields.locationFieldsUi) { - const locationUi = (additionalFields.locationFieldsUi as IDataObject).locationFieldsValues as IDataObject; - if (locationUi) { - data['X-S4-Location'] = `${locationUi.latitude},${locationUi.longitude}`; + if (additionalFields.title) { + data.title = additionalFields.title as string; } - } - if (additionalFields.alertingScenario) { - data['X-S4-AlertingScenario'] = additionalFields.alertingScenario as string; - } - - if (additionalFields.filtering) { - data['X-S4-Filtering'] = (additionalFields.filtering as boolean).toString(); - } - - if (additionalFields.externalId) { - data['X-S4-ExternalID'] = additionalFields.externalId as string; - } - - data['X-S4-Status'] = 'new'; - - data['X-S4-SourceSystem'] = 'n8n'; - - // Attachments - const attachments = additionalFields.attachmentsUi as IDataObject; - if (attachments) { - if (attachments.attachmentsBinary && items[i].binary) { - - const propertyName = (attachments.attachmentsBinary as IDataObject).property as string; - - const binaryProperty = (items[i].binary as IBinaryKeyData)[propertyName]; - - if (binaryProperty) { - - const supportedFileExtension = ['png', 'jpg', 'jpeg', 'bmp', 'gif', 'mp3', 'wav']; - - if (!supportedFileExtension.includes(binaryProperty.fileExtension as string)) { - - throw new NodeOperationError(this.getNode(), `Invalid extension, just ${supportedFileExtension.join(',')} are supported}`); - } - - data.attachment = { - value: Buffer.from(binaryProperty.data, BINARY_ENCODING), - options: { - filename: binaryProperty.fileName, - contentType: binaryProperty.mimeType, - }, - }; - - } else { - throw new NodeOperationError(this.getNode(), `Binary property ${propertyName} does not exist on input`); + if (additionalFields.service) { + data.service = additionalFields.service as string; + } + if (additionalFields.locationFieldsUi) { + const locationUi = (additionalFields.locationFieldsUi as IDataObject).locationFieldsValues as IDataObject; + if (locationUi) { + data['X-S4-Location'] = `${locationUi.latitude},${locationUi.longitude}`; } } + + if (additionalFields.alertingScenario) { + data['X-S4-AlertingScenario'] = additionalFields.alertingScenario as string; + } + + if (additionalFields.filtering) { + data['X-S4-Filtering'] = (additionalFields.filtering as boolean).toString(); + } + + if (additionalFields.externalId) { + data['X-S4-ExternalID'] = additionalFields.externalId as string; + } + + data['X-S4-Status'] = 'new'; + + data['X-S4-SourceSystem'] = 'n8n'; + + // Attachments + const attachments = additionalFields.attachmentsUi as IDataObject; + if (attachments) { + if (attachments.attachmentsBinary && items[i].binary) { + + const propertyName = (attachments.attachmentsBinary as IDataObject).property as string; + + const binaryProperty = (items[i].binary as IBinaryKeyData)[propertyName]; + + if (binaryProperty) { + + const supportedFileExtension = ['png', 'jpg', 'jpeg', 'bmp', 'gif', 'mp3', 'wav']; + + if (!supportedFileExtension.includes(binaryProperty.fileExtension as string)) { + + throw new NodeOperationError(this.getNode(), `Invalid extension, just ${supportedFileExtension.join(',')} are supported}`); + } + + data.attachment = { + value: Buffer.from(binaryProperty.data, BINARY_ENCODING), + options: { + filename: binaryProperty.fileName, + contentType: binaryProperty.mimeType, + }, + }; + + } else { + throw new NodeOperationError(this.getNode(), `Binary property ${propertyName} does not exist on input`); + } + } + } + + responseData = await SIGNL4ApiRequest.call( + this, + 'POST', + '', + {}, + { + formData: data, + }, + ); } + // Resolve alert + if (operation === 'resolve') { - responseData = await SIGNL4ApiRequest.call( - this, - 'POST', - '', - {}, - { - formData: data, - }, - ); + const data: IDataObject = {}; + + data['X-S4-ExternalID'] = this.getNodeParameter('externalId', i) as string; + + data['X-S4-Status'] = 'resolved'; + + data['X-S4-SourceSystem'] = 'n8n'; + + responseData = await SIGNL4ApiRequest.call( + this, + 'POST', + '', + {}, + { + formData: data, + }, + ); + } } - // Resolve alert - if (operation === 'resolve') { - - const data: IDataObject = {}; - - data['X-S4-ExternalID'] = this.getNodeParameter('externalId', i) as string; - - data['X-S4-Status'] = 'resolved'; - - data['X-S4-SourceSystem'] = 'n8n'; - - responseData = await SIGNL4ApiRequest.call( - this, - 'POST', - '', - {}, - { - formData: data, - }, - ); + if (Array.isArray(responseData)) { + returnData.push.apply(returnData, responseData as IDataObject[]); + } else if (responseData !== undefined) { + returnData.push(responseData as IDataObject); } - } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else if (responseData !== undefined) { - returnData.push(responseData as IDataObject); + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } } return [this.helpers.returnJsonArray(returnData)]; diff --git a/packages/nodes-base/nodes/Slack/Slack.node.ts b/packages/nodes-base/nodes/Slack/Slack.node.ts index 42c3864e17..ef0c282011 100644 --- a/packages/nodes-base/nodes/Slack/Slack.node.ts +++ b/packages/nodes-base/nodes/Slack/Slack.node.ts @@ -289,257 +289,492 @@ export class Slack implements INodeType { const operation = this.getNodeParameter('operation', 0) as string; for (let i = 0; i < length; i++) { - responseData = { error: 'Resource ' + resource + ' / operation ' + operation + ' not found!' }; - qs = {}; - if (resource === 'channel') { - //https://api.slack.com/methods/conversations.archive - if (operation === 'archive') { - const channel = this.getNodeParameter('channelId', i) as string; - const body: IDataObject = { - channel, - }; - responseData = await slackApiRequest.call(this, 'POST', '/conversations.archive', body, qs); - } - //https://api.slack.com/methods/conversations.close - if (operation === 'close') { - const channel = this.getNodeParameter('channelId', i) as string; - const body: IDataObject = { - channel, - }; - responseData = await slackApiRequest.call(this, 'POST', '/conversations.close', body, qs); - } - //https://api.slack.com/methods/conversations.create - if (operation === 'create') { - const channel = this.getNodeParameter('channelId', i) as string; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const body: IDataObject = { - name: channel, - }; - if (additionalFields.isPrivate) { - body.is_private = additionalFields.isPrivate as boolean; + try { + responseData = { error: 'Resource ' + resource + ' / operation ' + operation + ' not found!' }; + qs = {}; + if (resource === 'channel') { + //https://api.slack.com/methods/conversations.archive + if (operation === 'archive') { + const channel = this.getNodeParameter('channelId', i) as string; + const body: IDataObject = { + channel, + }; + responseData = await slackApiRequest.call(this, 'POST', '/conversations.archive', body, qs); } - responseData = await slackApiRequest.call(this, 'POST', '/conversations.create', body, qs); - responseData = responseData.channel; - } - //https://api.slack.com/methods/conversations.kick - if (operation === 'kick') { - const channel = this.getNodeParameter('channelId', i) as string; - const userId = this.getNodeParameter('userId', i) as string; - const body: IDataObject = { - name: channel, - user: userId, - }; - responseData = await slackApiRequest.call(this, 'POST', '/conversations.kick', body, qs); - } - //https://api.slack.com/methods/conversations.join - if (operation === 'join') { - const channel = this.getNodeParameter('channelId', i) as string; - const body: IDataObject = { - channel, - }; - responseData = await slackApiRequest.call(this, 'POST', '/conversations.join', body, qs); - responseData = responseData.channel; - } - //https://api.slack.com/methods/conversations.info - if (operation === 'get') { - const channel = this.getNodeParameter('channelId', i) as string; - qs.channel = channel; - responseData = await slackApiRequest.call(this, 'POST', '/conversations.info', {}, qs); - responseData = responseData.channel; - } - //https://api.slack.com/methods/conversations.list - if (operation === 'getAll') { - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - const filters = this.getNodeParameter('filters', i) as IDataObject; - if (filters.types) { - qs.types = (filters.types as string[]).join(','); + //https://api.slack.com/methods/conversations.close + if (operation === 'close') { + const channel = this.getNodeParameter('channelId', i) as string; + const body: IDataObject = { + channel, + }; + responseData = await slackApiRequest.call(this, 'POST', '/conversations.close', body, qs); } - if (filters.excludeArchived) { - qs.exclude_archived = filters.excludeArchived as boolean; - } - if (returnAll === true) { - responseData = await slackApiRequestAllItems.call(this, 'channels', 'GET', '/conversations.list', {}, qs); - } else { - qs.limit = this.getNodeParameter('limit', i) as number; - responseData = await slackApiRequest.call(this, 'GET', '/conversations.list', {}, qs); - responseData = responseData.channels; - } - } - //https://api.slack.com/methods/conversations.history - if (operation === 'history') { - const channel = this.getNodeParameter('channelId', i) as string; - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - const filters = this.getNodeParameter('filters', i) as IDataObject; - qs.channel = channel; - if (filters.inclusive) { - qs.inclusive = filters.inclusive as boolean; - } - if (filters.latest) { - qs.latest = filters.latest as string; - } - if (filters.oldest) { - qs.oldest = filters.oldest as string; - } - if (returnAll === true) { - responseData = await slackApiRequestAllItems.call(this, 'messages', 'GET', '/conversations.history', {}, qs); - } else { - qs.limit = this.getNodeParameter('limit', i) as number; - responseData = await slackApiRequest.call(this, 'GET', '/conversations.history', {}, qs); - responseData = responseData.messages; - } - } - //https://api.slack.com/methods/conversations.invite - if (operation === 'invite') { - const channel = this.getNodeParameter('channelId', i) as string; - const userIds = (this.getNodeParameter('userIds', i) as string[]).join(','); - const body: IDataObject = { - channel, - users: userIds, - }; - responseData = await slackApiRequest.call(this, 'POST', '/conversations.invite', body, qs); - responseData = responseData.channel; - } - //https://api.slack.com/methods/conversations.leave - if (operation === 'leave') { - const channel = this.getNodeParameter('channelId', i) as string; - const body: IDataObject = { - channel, - }; - responseData = await slackApiRequest.call(this, 'POST', '/conversations.leave', body, qs); - } - //https://api.slack.com/methods/conversations.members - if (operation === 'member') { - const returnAll = this.getNodeParameter('returnAll', 0) as boolean; - const resolveData = this.getNodeParameter('resolveData', 0) as boolean; - qs.channel = this.getNodeParameter('channelId', i) as string; - if (returnAll) { - responseData = await slackApiRequestAllItems.call(this, 'members', 'GET', '/conversations.members', {}, qs); - responseData = responseData.map((member: string) => ({ member })); - } else { - qs.limit = this.getNodeParameter('limit', i) as number; - responseData = await slackApiRequest.call(this, 'GET', '/conversations.members', {}, qs); - responseData = responseData.members.map((member: string) => ({ member })); - } - - if (resolveData) { - const data: IDataObject[] = []; - for (const { member } of responseData) { - const { user } = await slackApiRequest.call(this, 'GET', '/users.info', {}, { user: member }); - data.push(user); + //https://api.slack.com/methods/conversations.create + if (operation === 'create') { + const channel = this.getNodeParameter('channelId', i) as string; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const body: IDataObject = { + name: channel, + }; + if (additionalFields.isPrivate) { + body.is_private = additionalFields.isPrivate as boolean; } - responseData = data; + responseData = await slackApiRequest.call(this, 'POST', '/conversations.create', body, qs); + responseData = responseData.channel; } - } - //https://api.slack.com/methods/conversations.open - if (operation === 'open') { - const options = this.getNodeParameter('options', i) as IDataObject; - const body: IDataObject = {}; - if (options.channelId) { - body.channel = options.channelId as string; + //https://api.slack.com/methods/conversations.kick + if (operation === 'kick') { + const channel = this.getNodeParameter('channelId', i) as string; + const userId = this.getNodeParameter('userId', i) as string; + const body: IDataObject = { + name: channel, + user: userId, + }; + responseData = await slackApiRequest.call(this, 'POST', '/conversations.kick', body, qs); } - if (options.returnIm) { - body.return_im = options.returnIm as boolean; + //https://api.slack.com/methods/conversations.join + if (operation === 'join') { + const channel = this.getNodeParameter('channelId', i) as string; + const body: IDataObject = { + channel, + }; + responseData = await slackApiRequest.call(this, 'POST', '/conversations.join', body, qs); + responseData = responseData.channel; } - if (options.users) { - body.users = (options.users as string[]).join(','); + //https://api.slack.com/methods/conversations.info + if (operation === 'get') { + const channel = this.getNodeParameter('channelId', i) as string; + qs.channel = channel; + responseData = await slackApiRequest.call(this, 'POST', '/conversations.info', {}, qs); + responseData = responseData.channel; } - responseData = await slackApiRequest.call(this, 'POST', '/conversations.open', body, qs); - responseData = responseData.channel; - } - //https://api.slack.com/methods/conversations.rename - if (operation === 'rename') { - const channel = this.getNodeParameter('channelId', i) as IDataObject; - const name = this.getNodeParameter('name', i) as IDataObject; - const body: IDataObject = { - channel, - name, - }; - responseData = await slackApiRequest.call(this, 'POST', '/conversations.rename', body, qs); - responseData = responseData.channel; - } - //https://api.slack.com/methods/conversations.replies - if (operation === 'replies') { - const channel = this.getNodeParameter('channelId', i) as string; - const ts = this.getNodeParameter('ts', i) as string; - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - const filters = this.getNodeParameter('filters', i) as IDataObject; - qs.channel = channel; - qs.ts = ts; - if (filters.inclusive) { - qs.inclusive = filters.inclusive as boolean; + //https://api.slack.com/methods/conversations.list + if (operation === 'getAll') { + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + const filters = this.getNodeParameter('filters', i) as IDataObject; + if (filters.types) { + qs.types = (filters.types as string[]).join(','); + } + if (filters.excludeArchived) { + qs.exclude_archived = filters.excludeArchived as boolean; + } + if (returnAll === true) { + responseData = await slackApiRequestAllItems.call(this, 'channels', 'GET', '/conversations.list', {}, qs); + } else { + qs.limit = this.getNodeParameter('limit', i) as number; + responseData = await slackApiRequest.call(this, 'GET', '/conversations.list', {}, qs); + responseData = responseData.channels; + } } - if (filters.latest) { - qs.latest = filters.latest as string; + //https://api.slack.com/methods/conversations.history + if (operation === 'history') { + const channel = this.getNodeParameter('channelId', i) as string; + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + const filters = this.getNodeParameter('filters', i) as IDataObject; + qs.channel = channel; + if (filters.inclusive) { + qs.inclusive = filters.inclusive as boolean; + } + if (filters.latest) { + qs.latest = filters.latest as string; + } + if (filters.oldest) { + qs.oldest = filters.oldest as string; + } + if (returnAll === true) { + responseData = await slackApiRequestAllItems.call(this, 'messages', 'GET', '/conversations.history', {}, qs); + } else { + qs.limit = this.getNodeParameter('limit', i) as number; + responseData = await slackApiRequest.call(this, 'GET', '/conversations.history', {}, qs); + responseData = responseData.messages; + } } - if (filters.oldest) { - qs.oldest = filters.oldest as string; + //https://api.slack.com/methods/conversations.invite + if (operation === 'invite') { + const channel = this.getNodeParameter('channelId', i) as string; + const userIds = (this.getNodeParameter('userIds', i) as string[]).join(','); + const body: IDataObject = { + channel, + users: userIds, + }; + responseData = await slackApiRequest.call(this, 'POST', '/conversations.invite', body, qs); + responseData = responseData.channel; } - if (returnAll === true) { - responseData = await slackApiRequestAllItems.call(this, 'messages', 'GET', '/conversations.replies', {}, qs); - } else { - qs.limit = this.getNodeParameter('limit', i) as number; - responseData = await slackApiRequest.call(this, 'GET', '/conversations.replies', {}, qs); - responseData = responseData.messages; + //https://api.slack.com/methods/conversations.leave + if (operation === 'leave') { + const channel = this.getNodeParameter('channelId', i) as string; + const body: IDataObject = { + channel, + }; + responseData = await slackApiRequest.call(this, 'POST', '/conversations.leave', body, qs); } - } - //https://api.slack.com/methods/conversations.setPurpose - if (operation === 'setPurpose') { - const channel = this.getNodeParameter('channelId', i) as IDataObject; - const purpose = this.getNodeParameter('purpose', i) as IDataObject; - const body: IDataObject = { - channel, - purpose, - }; - responseData = await slackApiRequest.call(this, 'POST', '/conversations.setPurpose', body, qs); - responseData = responseData.channel; - } - //https://api.slack.com/methods/conversations.setTopic - if (operation === 'setTopic') { - const channel = this.getNodeParameter('channelId', i) as IDataObject; - const topic = this.getNodeParameter('topic', i) as IDataObject; - const body: IDataObject = { - channel, - topic, - }; - responseData = await slackApiRequest.call(this, 'POST', '/conversations.setTopic', body, qs); - responseData = responseData.channel; - } - //https://api.slack.com/methods/conversations.unarchive - if (operation === 'unarchive') { - const channel = this.getNodeParameter('channelId', i) as string; - const body: IDataObject = { - channel, - }; - responseData = await slackApiRequest.call(this, 'POST', '/conversations.unarchive', body, qs); - } - } - if (resource === 'message') { - //https://api.slack.com/methods/chat.postMessage - if (['post', 'postEphemeral'].includes(operation)) { - const channel = this.getNodeParameter('channel', i) as string; - const { sendAsUser } = this.getNodeParameter('otherOptions', i) as IDataObject; - const text = this.getNodeParameter('text', i) as string; - const body: IDataObject = { - channel, - text, - }; + //https://api.slack.com/methods/conversations.members + if (operation === 'member') { + const returnAll = this.getNodeParameter('returnAll', 0) as boolean; + const resolveData = this.getNodeParameter('resolveData', 0) as boolean; + qs.channel = this.getNodeParameter('channelId', i) as string; + if (returnAll) { + responseData = await slackApiRequestAllItems.call(this, 'members', 'GET', '/conversations.members', {}, qs); + responseData = responseData.map((member: string) => ({ member })); + } else { + qs.limit = this.getNodeParameter('limit', i) as number; + responseData = await slackApiRequest.call(this, 'GET', '/conversations.members', {}, qs); + responseData = responseData.members.map((member: string) => ({ member })); + } - let action = 'postMessage'; - - if (operation === 'postEphemeral') { - body.user = this.getNodeParameter('user', i) as string; - action = 'postEphemeral'; + if (resolveData) { + const data: IDataObject[] = []; + for (const { member } of responseData) { + const { user } = await slackApiRequest.call(this, 'GET', '/users.info', {}, { user: member }); + data.push(user); + } + responseData = data; + } } - - const jsonParameters = this.getNodeParameter('jsonParameters', i) as boolean; - - if (authentication === 'accessToken' && sendAsUser !== '') { - body.username = sendAsUser; + //https://api.slack.com/methods/conversations.open + if (operation === 'open') { + const options = this.getNodeParameter('options', i) as IDataObject; + const body: IDataObject = {}; + if (options.channelId) { + body.channel = options.channelId as string; + } + if (options.returnIm) { + body.return_im = options.returnIm as boolean; + } + if (options.users) { + body.users = (options.users as string[]).join(','); + } + responseData = await slackApiRequest.call(this, 'POST', '/conversations.open', body, qs); + responseData = responseData.channel; } + //https://api.slack.com/methods/conversations.rename + if (operation === 'rename') { + const channel = this.getNodeParameter('channelId', i) as IDataObject; + const name = this.getNodeParameter('name', i) as IDataObject; + const body: IDataObject = { + channel, + name, + }; + responseData = await slackApiRequest.call(this, 'POST', '/conversations.rename', body, qs); + responseData = responseData.channel; + } + //https://api.slack.com/methods/conversations.replies + if (operation === 'replies') { + const channel = this.getNodeParameter('channelId', i) as string; + const ts = this.getNodeParameter('ts', i) as string; + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + const filters = this.getNodeParameter('filters', i) as IDataObject; + qs.channel = channel; + qs.ts = ts; + if (filters.inclusive) { + qs.inclusive = filters.inclusive as boolean; + } + if (filters.latest) { + qs.latest = filters.latest as string; + } + if (filters.oldest) { + qs.oldest = filters.oldest as string; + } + if (returnAll === true) { + responseData = await slackApiRequestAllItems.call(this, 'messages', 'GET', '/conversations.replies', {}, qs); + } else { + qs.limit = this.getNodeParameter('limit', i) as number; + responseData = await slackApiRequest.call(this, 'GET', '/conversations.replies', {}, qs); + responseData = responseData.messages; + } + } + //https://api.slack.com/methods/conversations.setPurpose + if (operation === 'setPurpose') { + const channel = this.getNodeParameter('channelId', i) as IDataObject; + const purpose = this.getNodeParameter('purpose', i) as IDataObject; + const body: IDataObject = { + channel, + purpose, + }; + responseData = await slackApiRequest.call(this, 'POST', '/conversations.setPurpose', body, qs); + responseData = responseData.channel; + } + //https://api.slack.com/methods/conversations.setTopic + if (operation === 'setTopic') { + const channel = this.getNodeParameter('channelId', i) as IDataObject; + const topic = this.getNodeParameter('topic', i) as IDataObject; + const body: IDataObject = { + channel, + topic, + }; + responseData = await slackApiRequest.call(this, 'POST', '/conversations.setTopic', body, qs); + responseData = responseData.channel; + } + //https://api.slack.com/methods/conversations.unarchive + if (operation === 'unarchive') { + const channel = this.getNodeParameter('channelId', i) as string; + const body: IDataObject = { + channel, + }; + responseData = await slackApiRequest.call(this, 'POST', '/conversations.unarchive', body, qs); + } + } + if (resource === 'message') { + //https://api.slack.com/methods/chat.postMessage + if (['post', 'postEphemeral'].includes(operation)) { + const channel = this.getNodeParameter('channel', i) as string; + const { sendAsUser } = this.getNodeParameter('otherOptions', i) as IDataObject; + const text = this.getNodeParameter('text', i) as string; + const body: IDataObject = { + channel, + text, + }; - if (!jsonParameters) { - const attachments = this.getNodeParameter('attachments', i, []) as unknown as Attachment[]; - const blocksUi = (this.getNodeParameter('blocksUi', i, []) as IDataObject).blocksValues as IDataObject[]; + let action = 'postMessage'; + + if (operation === 'postEphemeral') { + body.user = this.getNodeParameter('user', i) as string; + action = 'postEphemeral'; + } + + const jsonParameters = this.getNodeParameter('jsonParameters', i) as boolean; + + if (authentication === 'accessToken' && sendAsUser !== '') { + body.username = sendAsUser; + } + + if (!jsonParameters) { + const attachments = this.getNodeParameter('attachments', i, []) as unknown as Attachment[]; + const blocksUi = (this.getNodeParameter('blocksUi', i, []) as IDataObject).blocksValues as IDataObject[]; + + // The node does save the fields data differently than the API + // expects so fix the data befre we send the request + for (const attachment of attachments) { + if (attachment.fields !== undefined) { + if (attachment.fields.item !== undefined) { + // Move the field-content up + // @ts-ignore + attachment.fields = attachment.fields.item; + } else { + // If it does not have any items set remove it + delete attachment.fields; + } + } + } + body['attachments'] = attachments; + + if (blocksUi) { + const blocks: Block[] = []; + for (const blockUi of blocksUi) { + const block: Block = {}; + const elements: Element[] = []; + block.block_id = blockUi.blockId as string; + block.type = blockUi.type as string; + if (block.type === 'actions') { + const elementsUi = (blockUi.elementsUi as IDataObject).elementsValues as IDataObject[]; + if (elementsUi) { + for (const elementUi of elementsUi) { + const element: Element = {}; + if (elementUi.actionId === '') { + throw new NodeOperationError(this.getNode(), 'Action ID must be set'); + } + if (elementUi.text === '') { + throw new NodeOperationError(this.getNode(), 'Text must be set'); + } + element.action_id = elementUi.actionId as string; + element.type = elementUi.type as string; + element.text = { + text: elementUi.text as string, + type: 'plain_text', + emoji: elementUi.emoji as boolean, + }; + if (elementUi.url) { + element.url = elementUi.url as string; + } + if (elementUi.value) { + element.value = elementUi.value as string; + } + if (elementUi.style !== 'default') { + element.style = elementUi.style as string; + } + const confirmUi = (elementUi.confirmUi as IDataObject).confirmValue as IDataObject; + if (confirmUi) { + const confirm: Confirm = {}; + const titleUi = (confirmUi.titleUi as IDataObject).titleValue as IDataObject; + const textUi = (confirmUi.textUi as IDataObject).textValue as IDataObject; + const confirmTextUi = (confirmUi.confirmTextUi as IDataObject).confirmValue as IDataObject; + const denyUi = (confirmUi.denyUi as IDataObject).denyValue as IDataObject; + const style = confirmUi.style as string; + if (titleUi) { + confirm.title = { + type: 'plain_text', + text: titleUi.text as string, + emoji: titleUi.emoji as boolean, + }; + } + if (textUi) { + confirm.text = { + type: 'plain_text', + text: textUi.text as string, + emoji: textUi.emoji as boolean, + }; + } + if (confirmTextUi) { + confirm.confirm = { + type: 'plain_text', + text: confirmTextUi.text as string, + emoji: confirmTextUi.emoji as boolean, + }; + } + if (denyUi) { + confirm.deny = { + type: 'plain_text', + text: denyUi.text as string, + emoji: denyUi.emoji as boolean, + }; + } + if (style !== 'default') { + confirm.style = style as string; + } + element.confirm = confirm; + } + elements.push(element); + } + block.elements = elements; + } + } else if (block.type === 'section') { + const textUi = (blockUi.textUi as IDataObject).textValue as IDataObject; + if (textUi) { + const text: Text = {}; + if (textUi.type === 'plainText') { + text.type = 'plain_text'; + text.emoji = textUi.emoji as boolean; + } else { + text.type = 'mrkdwn'; + text.verbatim = textUi.verbatim as boolean; + } + text.text = textUi.text as string; + block.text = text; + } else { + throw new NodeOperationError(this.getNode(), 'Property text must be defined'); + } + const fieldsUi = (blockUi.fieldsUi as IDataObject).fieldsValues as IDataObject[]; + if (fieldsUi) { + const fields: Text[] = []; + for (const fieldUi of fieldsUi) { + const field: Text = {}; + if (fieldUi.type === 'plainText') { + field.type = 'plain_text'; + field.emoji = fieldUi.emoji as boolean; + } else { + field.type = 'mrkdwn'; + field.verbatim = fieldUi.verbatim as boolean; + } + field.text = fieldUi.text as string; + fields.push(field); + } + // If not fields were added then it's not needed to send the property + if (fields.length > 0) { + block.fields = fields; + } + } + const accessoryUi = (blockUi.accessoryUi as IDataObject).accessoriesValues as IDataObject; + if (accessoryUi) { + const accessory: Element = {}; + if (accessoryUi.type === 'button') { + accessory.type = 'button'; + accessory.text = { + text: accessoryUi.text as string, + type: 'plain_text', + emoji: accessoryUi.emoji as boolean, + }; + if (accessoryUi.url) { + accessory.url = accessoryUi.url as string; + } + if (accessoryUi.value) { + accessory.value = accessoryUi.value as string; + } + if (accessoryUi.style !== 'default') { + accessory.style = accessoryUi.style as string; + } + const confirmUi = (accessoryUi.confirmUi as IDataObject).confirmValue as IDataObject; + if (confirmUi) { + const confirm: Confirm = {}; + const titleUi = (confirmUi.titleUi as IDataObject).titleValue as IDataObject; + const textUi = (confirmUi.textUi as IDataObject).textValue as IDataObject; + const confirmTextUi = (confirmUi.confirmTextUi as IDataObject).confirmValue as IDataObject; + const denyUi = (confirmUi.denyUi as IDataObject).denyValue as IDataObject; + const style = confirmUi.style as string; + if (titleUi) { + confirm.title = { + type: 'plain_text', + text: titleUi.text as string, + emoji: titleUi.emoji as boolean, + }; + } + if (textUi) { + confirm.text = { + type: 'plain_text', + text: textUi.text as string, + emoji: textUi.emoji as boolean, + }; + } + if (confirmTextUi) { + confirm.confirm = { + type: 'plain_text', + text: confirmTextUi.text as string, + emoji: confirmTextUi.emoji as boolean, + }; + } + if (denyUi) { + confirm.deny = { + type: 'plain_text', + text: denyUi.text as string, + emoji: denyUi.emoji as boolean, + }; + } + if (style !== 'default') { + confirm.style = style as string; + } + accessory.confirm = confirm; + } + } + block.accessory = accessory; + } + } + blocks.push(block); + } + body.blocks = blocks; + } + + } else { + const attachmentsJson = this.getNodeParameter('attachmentsJson', i, '') as string; + const blocksJson = this.getNodeParameter('blocksJson', i, []) as string; + if (attachmentsJson !== '' && validateJSON(attachmentsJson) === undefined) { + throw new NodeOperationError(this.getNode(), 'Attachments it is not a valid json'); + } + if (blocksJson !== '' && validateJSON(blocksJson) === undefined) { + throw new NodeOperationError(this.getNode(), 'Blocks it is not a valid json'); + } + if (attachmentsJson !== '') { + body.attachments = attachmentsJson; + } + if (blocksJson !== '') { + body.blocks = blocksJson; + } + } + + // Add all the other options to the request + const otherOptions = this.getNodeParameter('otherOptions', i) as IDataObject; + Object.assign(body, otherOptions); + responseData = await slackApiRequest.call(this, 'POST', `/chat.${action}`, body, qs); + } + //https://api.slack.com/methods/chat.update + if (operation === 'update') { + const channel = this.getNodeParameter('channelId', i) as string; + const text = this.getNodeParameter('text', i) as string; + const ts = this.getNodeParameter('ts', i) as string; + const attachments = this.getNodeParameter('attachments', i, []) as unknown as IAttachment[]; + const body: IDataObject = { + channel, + text, + ts, + }; // The node does save the fields data differently than the API // expects so fix the data befre we send the request @@ -557,497 +792,270 @@ export class Slack implements INodeType { } body['attachments'] = attachments; - if (blocksUi) { - const blocks: Block[] = []; - for (const blockUi of blocksUi) { - const block: Block = {}; - const elements: Element[] = []; - block.block_id = blockUi.blockId as string; - block.type = blockUi.type as string; - if (block.type === 'actions') { - const elementsUi = (blockUi.elementsUi as IDataObject).elementsValues as IDataObject[]; - if (elementsUi) { - for (const elementUi of elementsUi) { - const element: Element = {}; - if (elementUi.actionId === '') { - throw new NodeOperationError(this.getNode(), 'Action ID must be set'); - } - if (elementUi.text === '') { - throw new NodeOperationError(this.getNode(), 'Text must be set'); - } - element.action_id = elementUi.actionId as string; - element.type = elementUi.type as string; - element.text = { - text: elementUi.text as string, - type: 'plain_text', - emoji: elementUi.emoji as boolean, - }; - if (elementUi.url) { - element.url = elementUi.url as string; - } - if (elementUi.value) { - element.value = elementUi.value as string; - } - if (elementUi.style !== 'default') { - element.style = elementUi.style as string; - } - const confirmUi = (elementUi.confirmUi as IDataObject).confirmValue as IDataObject; - if (confirmUi) { - const confirm: Confirm = {}; - const titleUi = (confirmUi.titleUi as IDataObject).titleValue as IDataObject; - const textUi = (confirmUi.textUi as IDataObject).textValue as IDataObject; - const confirmTextUi = (confirmUi.confirmTextUi as IDataObject).confirmValue as IDataObject; - const denyUi = (confirmUi.denyUi as IDataObject).denyValue as IDataObject; - const style = confirmUi.style as string; - if (titleUi) { - confirm.title = { - type: 'plain_text', - text: titleUi.text as string, - emoji: titleUi.emoji as boolean, - }; - } - if (textUi) { - confirm.text = { - type: 'plain_text', - text: textUi.text as string, - emoji: textUi.emoji as boolean, - }; - } - if (confirmTextUi) { - confirm.confirm = { - type: 'plain_text', - text: confirmTextUi.text as string, - emoji: confirmTextUi.emoji as boolean, - }; - } - if (denyUi) { - confirm.deny = { - type: 'plain_text', - text: denyUi.text as string, - emoji: denyUi.emoji as boolean, - }; - } - if (style !== 'default') { - confirm.style = style as string; - } - element.confirm = confirm; - } - elements.push(element); - } - block.elements = elements; - } - } else if (block.type === 'section') { - const textUi = (blockUi.textUi as IDataObject).textValue as IDataObject; - if (textUi) { - const text: Text = {}; - if (textUi.type === 'plainText') { - text.type = 'plain_text'; - text.emoji = textUi.emoji as boolean; - } else { - text.type = 'mrkdwn'; - text.verbatim = textUi.verbatim as boolean; - } - text.text = textUi.text as string; - block.text = text; - } else { - throw new NodeOperationError(this.getNode(), 'Property text must be defined'); - } - const fieldsUi = (blockUi.fieldsUi as IDataObject).fieldsValues as IDataObject[]; - if (fieldsUi) { - const fields: Text[] = []; - for (const fieldUi of fieldsUi) { - const field: Text = {}; - if (fieldUi.type === 'plainText') { - field.type = 'plain_text'; - field.emoji = fieldUi.emoji as boolean; - } else { - field.type = 'mrkdwn'; - field.verbatim = fieldUi.verbatim as boolean; - } - field.text = fieldUi.text as string; - fields.push(field); - } - // If not fields were added then it's not needed to send the property - if (fields.length > 0) { - block.fields = fields; - } - } - const accessoryUi = (blockUi.accessoryUi as IDataObject).accessoriesValues as IDataObject; - if (accessoryUi) { - const accessory: Element = {}; - if (accessoryUi.type === 'button') { - accessory.type = 'button'; - accessory.text = { - text: accessoryUi.text as string, - type: 'plain_text', - emoji: accessoryUi.emoji as boolean, - }; - if (accessoryUi.url) { - accessory.url = accessoryUi.url as string; - } - if (accessoryUi.value) { - accessory.value = accessoryUi.value as string; - } - if (accessoryUi.style !== 'default') { - accessory.style = accessoryUi.style as string; - } - const confirmUi = (accessoryUi.confirmUi as IDataObject).confirmValue as IDataObject; - if (confirmUi) { - const confirm: Confirm = {}; - const titleUi = (confirmUi.titleUi as IDataObject).titleValue as IDataObject; - const textUi = (confirmUi.textUi as IDataObject).textValue as IDataObject; - const confirmTextUi = (confirmUi.confirmTextUi as IDataObject).confirmValue as IDataObject; - const denyUi = (confirmUi.denyUi as IDataObject).denyValue as IDataObject; - const style = confirmUi.style as string; - if (titleUi) { - confirm.title = { - type: 'plain_text', - text: titleUi.text as string, - emoji: titleUi.emoji as boolean, - }; - } - if (textUi) { - confirm.text = { - type: 'plain_text', - text: textUi.text as string, - emoji: textUi.emoji as boolean, - }; - } - if (confirmTextUi) { - confirm.confirm = { - type: 'plain_text', - text: confirmTextUi.text as string, - emoji: confirmTextUi.emoji as boolean, - }; - } - if (denyUi) { - confirm.deny = { - type: 'plain_text', - text: denyUi.text as string, - emoji: denyUi.emoji as boolean, - }; - } - if (style !== 'default') { - confirm.style = style as string; - } - accessory.confirm = confirm; - } - } - block.accessory = accessory; - } - } - blocks.push(block); - } - body.blocks = blocks; - } - - } else { - const attachmentsJson = this.getNodeParameter('attachmentsJson', i, '') as string; - const blocksJson = this.getNodeParameter('blocksJson', i, []) as string; - if (attachmentsJson !== '' && validateJSON(attachmentsJson) === undefined) { - throw new NodeOperationError(this.getNode(), 'Attachments it is not a valid json'); - } - if (blocksJson !== '' && validateJSON(blocksJson) === undefined) { - throw new NodeOperationError(this.getNode(), 'Blocks it is not a valid json'); - } - if (attachmentsJson !== '') { - body.attachments = attachmentsJson; - } - if (blocksJson !== '') { - body.blocks = blocksJson; - } + // Add all the other options to the request + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + Object.assign(body, updateFields); + responseData = await slackApiRequest.call(this, 'POST', '/chat.update', body, qs); } - - // Add all the other options to the request - const otherOptions = this.getNodeParameter('otherOptions', i) as IDataObject; - Object.assign(body, otherOptions); - responseData = await slackApiRequest.call(this, 'POST', `/chat.${action}`, body, qs); - } - //https://api.slack.com/methods/chat.update - if (operation === 'update') { - const channel = this.getNodeParameter('channelId', i) as string; - const text = this.getNodeParameter('text', i) as string; - const ts = this.getNodeParameter('ts', i) as string; - const attachments = this.getNodeParameter('attachments', i, []) as unknown as IAttachment[]; - const body: IDataObject = { - channel, - text, - ts, - }; - - // The node does save the fields data differently than the API - // expects so fix the data befre we send the request - for (const attachment of attachments) { - if (attachment.fields !== undefined) { - if (attachment.fields.item !== undefined) { - // Move the field-content up - // @ts-ignore - attachment.fields = attachment.fields.item; - } else { - // If it does not have any items set remove it - delete attachment.fields; - } - } - } - body['attachments'] = attachments; - - // Add all the other options to the request - const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; - Object.assign(body, updateFields); - responseData = await slackApiRequest.call(this, 'POST', '/chat.update', body, qs); - } - //https://api.slack.com/methods/chat.delete - if (operation === 'delete') { - const channel = this.getNodeParameter('channelId', i) as string; - const timestamp = this.getNodeParameter('timestamp', i) as string; - const body: IDataObject = { - channel, - ts: timestamp, - }; - // Add all the other options to the request - responseData = await slackApiRequest.call(this, 'POST', '/chat.delete', body, qs); - } - //https://api.slack.com/methods/chat.getPermalink - if (operation === 'getPermalink') { - const channel = this.getNodeParameter('channelId', i) as string; - const timestamp = this.getNodeParameter('timestamp', i) as string; - const qs = { - channel, - message_ts: timestamp, - }; - responseData = await slackApiRequest.call(this, 'GET', '/chat.getPermalink', {}, qs); - } - } - if (resource === 'reaction') { - const channel = this.getNodeParameter('channelId', i) as string; - const timestamp = this.getNodeParameter('timestamp', i) as string; - //https://api.slack.com/methods/reactions.add - if (operation === 'add') { - const name = this.getNodeParameter('name', i) as string; - const body: IDataObject = { - channel, - name, - timestamp, - }; - responseData = await slackApiRequest.call(this, 'POST', '/reactions.add', body, qs); - } - //https://api.slack.com/methods/reactions.remove - if (operation === 'remove') { - const name = this.getNodeParameter('name', i) as string; - const body: IDataObject = { - channel, - name, - timestamp, - }; - responseData = await slackApiRequest.call(this, 'POST', '/reactions.remove', body, qs); - } - //https://api.slack.com/methods/reactions.get - if (operation === 'get') { - qs.channel = channel; - qs.timestamp = timestamp; - responseData = await slackApiRequest.call(this, 'GET', '/reactions.get', {}, qs); - } - } - if (resource === 'star') { - //https://api.slack.com/methods/stars.add - if (operation === 'add') { - const options = this.getNodeParameter('options', i) as IDataObject; - const body: IDataObject = {}; - if (options.channelId) { - body.channel = options.channelId as string; - } - if (options.fileId) { - body.file = options.fileId as string; - } - if (options.fileComment) { - body.file_comment = options.fileComment as string; - } - if (options.timestamp) { - body.timestamp = options.timestamp as string; - } - responseData = await slackApiRequest.call(this, 'POST', '/stars.add', body, qs); - } - //https://api.slack.com/methods/stars.remove - if (operation === 'delete') { - const options = this.getNodeParameter('options', i) as IDataObject; - const body: IDataObject = {}; - if (options.channelId) { - body.channel = options.channelId as string; - } - if (options.fileId) { - body.file = options.fileId as string; - } - if (options.fileComment) { - body.file_comment = options.fileComment as string; - } - if (options.timestamp) { - body.timestamp = options.timestamp as string; - } - responseData = await slackApiRequest.call(this, 'POST', '/stars.remove', body, qs); - } - //https://api.slack.com/methods/stars.list - if (operation === 'getAll') { - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - if (returnAll === true) { - responseData = await slackApiRequestAllItems.call(this, 'items', 'GET', '/stars.list', {}, qs); - } else { - qs.limit = this.getNodeParameter('limit', i) as number; - responseData = await slackApiRequest.call(this, 'GET', '/stars.list', {}, qs); - responseData = responseData.items; - } - } - } - if (resource === 'file') { - //https://api.slack.com/methods/files.upload - if (operation === 'upload') { - const options = this.getNodeParameter('options', i) as IDataObject; - const binaryData = this.getNodeParameter('binaryData', i) as boolean; - const body: IDataObject = {}; - if (options.channelIds) { - body.channels = (options.channelIds as string[]).join(','); - } - if (options.fileName) { - body.filename = options.fileName as string; - } - if (options.initialComment) { - body.initial_comment = options.initialComment as string; - } - if (options.threadTs) { - body.thread_ts = options.threadTs as string; - } - if (options.title) { - body.title = options.title as string; - } - if (binaryData) { - const binaryPropertyName = this.getNodeParameter('binaryPropertyName', i) as string; - if (items[i].binary === undefined - //@ts-ignore - || items[i].binary[binaryPropertyName] === undefined) { - throw new NodeOperationError(this.getNode(), `No binary data property "${binaryPropertyName}" does not exists on item!`); - } - body.file = { - //@ts-ignore - value: Buffer.from(items[i].binary[binaryPropertyName].data, BINARY_ENCODING), - options: { - //@ts-ignore - filename: items[i].binary[binaryPropertyName].fileName, - //@ts-ignore - contentType: items[i].binary[binaryPropertyName].mimeType, - }, + //https://api.slack.com/methods/chat.delete + if (operation === 'delete') { + const channel = this.getNodeParameter('channelId', i) as string; + const timestamp = this.getNodeParameter('timestamp', i) as string; + const body: IDataObject = { + channel, + ts: timestamp, }; - responseData = await slackApiRequest.call(this, 'POST', '/files.upload', {}, qs, { 'Content-Type': 'multipart/form-data' }, { formData: body }); - responseData = responseData.file; - } else { - const fileContent = this.getNodeParameter('fileContent', i) as string; - body.content = fileContent; - responseData = await slackApiRequest.call(this, 'POST', '/files.upload', body, qs, { 'Content-Type': 'application/x-www-form-urlencoded' }, { form: body }); - responseData = responseData.file; + // Add all the other options to the request + responseData = await slackApiRequest.call(this, 'POST', '/chat.delete', body, qs); + } + //https://api.slack.com/methods/chat.getPermalink + if (operation === 'getPermalink') { + const channel = this.getNodeParameter('channelId', i) as string; + const timestamp = this.getNodeParameter('timestamp', i) as string; + const qs = { + channel, + message_ts: timestamp, + }; + responseData = await slackApiRequest.call(this, 'GET', '/chat.getPermalink', {}, qs); } } - //https://api.slack.com/methods/files.list - if (operation === 'getAll') { - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - const filters = this.getNodeParameter('filters', i) as IDataObject; - if (filters.channelId) { - qs.channel = filters.channelId as string; + if (resource === 'reaction') { + const channel = this.getNodeParameter('channelId', i) as string; + const timestamp = this.getNodeParameter('timestamp', i) as string; + //https://api.slack.com/methods/reactions.add + if (operation === 'add') { + const name = this.getNodeParameter('name', i) as string; + const body: IDataObject = { + channel, + name, + timestamp, + }; + responseData = await slackApiRequest.call(this, 'POST', '/reactions.add', body, qs); } - if (filters.showFilesHidden) { - qs.show_files_hidden_by_limit = filters.showFilesHidden as boolean; + //https://api.slack.com/methods/reactions.remove + if (operation === 'remove') { + const name = this.getNodeParameter('name', i) as string; + const body: IDataObject = { + channel, + name, + timestamp, + }; + responseData = await slackApiRequest.call(this, 'POST', '/reactions.remove', body, qs); } - if (filters.tsFrom) { - qs.ts_from = filters.tsFrom as string; - } - if (filters.tsTo) { - qs.ts_to = filters.tsTo as string; - } - if (filters.types) { - qs.types = (filters.types as string[]).join(',') as string; - } - if (filters.userId) { - qs.user = filters.userId as string; - } - if (returnAll === true) { - responseData = await slackApiRequestAllItems.call(this, 'files', 'GET', '/files.list', {}, qs); - } else { - qs.count = this.getNodeParameter('limit', i) as number; - responseData = await slackApiRequest.call(this, 'GET', '/files.list', {}, qs); - responseData = responseData.files; + //https://api.slack.com/methods/reactions.get + if (operation === 'get') { + qs.channel = channel; + qs.timestamp = timestamp; + responseData = await slackApiRequest.call(this, 'GET', '/reactions.get', {}, qs); } } - //https://api.slack.com/methods/files.info - if (operation === 'get') { - const fileId = this.getNodeParameter('fileId', i) as string; - qs.file = fileId; - responseData = await slackApiRequest.call(this, 'GET', '/files.info', {}, qs); - responseData = responseData.file; - } - } - if (resource === 'user') { - //https://api.slack.com/methods/users.info - if (operation === 'info') { - qs.user = this.getNodeParameter('user', i) as string; - responseData = await slackApiRequest.call(this, 'GET', '/users.info', {}, qs); - responseData = responseData.user; - } - //https://api.slack.com/methods/users.getPresence - if (operation === 'getPresence') { - qs.user = this.getNodeParameter('user', i) as string; - responseData = await slackApiRequest.call(this, 'GET', '/users.getPresence', {}, qs); - } - } - if (resource === 'userProfile') { - //https://api.slack.com/methods/users.profile.set - if (operation === 'update') { - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - - const timezone = this.getTimezone(); - - const body: IDataObject = {}; - - Object.assign(body, additionalFields); - - if (body.status_expiration === undefined) { - body.status_expiration = 0; - - } else { - body.status_expiration = moment.tz(body.status_expiration as string, timezone).unix(); + if (resource === 'star') { + //https://api.slack.com/methods/stars.add + if (operation === 'add') { + const options = this.getNodeParameter('options', i) as IDataObject; + const body: IDataObject = {}; + if (options.channelId) { + body.channel = options.channelId as string; + } + if (options.fileId) { + body.file = options.fileId as string; + } + if (options.fileComment) { + body.file_comment = options.fileComment as string; + } + if (options.timestamp) { + body.timestamp = options.timestamp as string; + } + responseData = await slackApiRequest.call(this, 'POST', '/stars.add', body, qs); } - - if (body.customFieldUi) { - const customFields = (body.customFieldUi as IDataObject).customFieldValues as IDataObject[]; - - body.fields = {}; - - for (const customField of customFields) { - //@ts-ignore - body.fields[customField.id] = { - value: customField.value, - alt: customField.alt, - }; + //https://api.slack.com/methods/stars.remove + if (operation === 'delete') { + const options = this.getNodeParameter('options', i) as IDataObject; + const body: IDataObject = {}; + if (options.channelId) { + body.channel = options.channelId as string; + } + if (options.fileId) { + body.file = options.fileId as string; + } + if (options.fileComment) { + body.file_comment = options.fileComment as string; + } + if (options.timestamp) { + body.timestamp = options.timestamp as string; + } + responseData = await slackApiRequest.call(this, 'POST', '/stars.remove', body, qs); + } + //https://api.slack.com/methods/stars.list + if (operation === 'getAll') { + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + if (returnAll === true) { + responseData = await slackApiRequestAllItems.call(this, 'items', 'GET', '/stars.list', {}, qs); + } else { + qs.limit = this.getNodeParameter('limit', i) as number; + responseData = await slackApiRequest.call(this, 'GET', '/stars.list', {}, qs); + responseData = responseData.items; } } - - responseData = await slackApiRequest.call(this, 'POST', '/users.profile.set', { profile: body }, qs); - - responseData = responseData.profile; } - //https://api.slack.com/methods/users.profile.get - if (operation === 'get') { - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - - const qs: IDataObject = {}; - - Object.assign(qs, additionalFields); - - responseData = await slackApiRequest.call(this, 'POST', '/users.profile.get', undefined, qs); - - responseData = responseData.profile; + if (resource === 'file') { + //https://api.slack.com/methods/files.upload + if (operation === 'upload') { + const options = this.getNodeParameter('options', i) as IDataObject; + const binaryData = this.getNodeParameter('binaryData', i) as boolean; + const body: IDataObject = {}; + if (options.channelIds) { + body.channels = (options.channelIds as string[]).join(','); + } + if (options.fileName) { + body.filename = options.fileName as string; + } + if (options.initialComment) { + body.initial_comment = options.initialComment as string; + } + if (options.threadTs) { + body.thread_ts = options.threadTs as string; + } + if (options.title) { + body.title = options.title as string; + } + if (binaryData) { + const binaryPropertyName = this.getNodeParameter('binaryPropertyName', i) as string; + if (items[i].binary === undefined + //@ts-ignore + || items[i].binary[binaryPropertyName] === undefined) { + throw new NodeOperationError(this.getNode(), `No binary data property "${binaryPropertyName}" does not exists on item!`); + } + body.file = { + //@ts-ignore + value: Buffer.from(items[i].binary[binaryPropertyName].data, BINARY_ENCODING), + options: { + //@ts-ignore + filename: items[i].binary[binaryPropertyName].fileName, + //@ts-ignore + contentType: items[i].binary[binaryPropertyName].mimeType, + }, + }; + responseData = await slackApiRequest.call(this, 'POST', '/files.upload', {}, qs, { 'Content-Type': 'multipart/form-data' }, { formData: body }); + responseData = responseData.file; + } else { + const fileContent = this.getNodeParameter('fileContent', i) as string; + body.content = fileContent; + responseData = await slackApiRequest.call(this, 'POST', '/files.upload', body, qs, { 'Content-Type': 'application/x-www-form-urlencoded' }, { form: body }); + responseData = responseData.file; + } + } + //https://api.slack.com/methods/files.list + if (operation === 'getAll') { + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + const filters = this.getNodeParameter('filters', i) as IDataObject; + if (filters.channelId) { + qs.channel = filters.channelId as string; + } + if (filters.showFilesHidden) { + qs.show_files_hidden_by_limit = filters.showFilesHidden as boolean; + } + if (filters.tsFrom) { + qs.ts_from = filters.tsFrom as string; + } + if (filters.tsTo) { + qs.ts_to = filters.tsTo as string; + } + if (filters.types) { + qs.types = (filters.types as string[]).join(',') as string; + } + if (filters.userId) { + qs.user = filters.userId as string; + } + if (returnAll === true) { + responseData = await slackApiRequestAllItems.call(this, 'files', 'GET', '/files.list', {}, qs); + } else { + qs.count = this.getNodeParameter('limit', i) as number; + responseData = await slackApiRequest.call(this, 'GET', '/files.list', {}, qs); + responseData = responseData.files; + } + } + //https://api.slack.com/methods/files.info + if (operation === 'get') { + const fileId = this.getNodeParameter('fileId', i) as string; + qs.file = fileId; + responseData = await slackApiRequest.call(this, 'GET', '/files.info', {}, qs); + responseData = responseData.file; + } } - } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else { - returnData.push(responseData as IDataObject); + if (resource === 'user') { + //https://api.slack.com/methods/users.info + if (operation === 'info') { + qs.user = this.getNodeParameter('user', i) as string; + responseData = await slackApiRequest.call(this, 'GET', '/users.info', {}, qs); + responseData = responseData.user; + } + //https://api.slack.com/methods/users.getPresence + if (operation === 'getPresence') { + qs.user = this.getNodeParameter('user', i) as string; + responseData = await slackApiRequest.call(this, 'GET', '/users.getPresence', {}, qs); + } + } + if (resource === 'userProfile') { + //https://api.slack.com/methods/users.profile.set + if (operation === 'update') { + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + + const timezone = this.getTimezone(); + + const body: IDataObject = {}; + + Object.assign(body, additionalFields); + + if (body.status_expiration === undefined) { + body.status_expiration = 0; + + } else { + body.status_expiration = moment.tz(body.status_expiration as string, timezone).unix(); + } + + if (body.customFieldUi) { + const customFields = (body.customFieldUi as IDataObject).customFieldValues as IDataObject[]; + + body.fields = {}; + + for (const customField of customFields) { + //@ts-ignore + body.fields[customField.id] = { + value: customField.value, + alt: customField.alt, + }; + } + } + + responseData = await slackApiRequest.call(this, 'POST', '/users.profile.set', { profile: body }, qs); + + responseData = responseData.profile; + } + //https://api.slack.com/methods/users.profile.get + if (operation === 'get') { + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + + const qs: IDataObject = {}; + + Object.assign(qs, additionalFields); + + responseData = await slackApiRequest.call(this, 'POST', '/users.profile.get', undefined, qs); + + responseData = responseData.profile; + } + } + if (Array.isArray(responseData)) { + returnData.push.apply(returnData, responseData as IDataObject[]); + } else { + returnData.push(responseData as IDataObject); + } + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } } return [this.helpers.returnJsonArray(returnData)]; diff --git a/packages/nodes-base/nodes/Spontit/Spontit.node.ts b/packages/nodes-base/nodes/Spontit/Spontit.node.ts index 0f8dd60794..1a85db0654 100644 --- a/packages/nodes-base/nodes/Spontit/Spontit.node.ts +++ b/packages/nodes-base/nodes/Spontit/Spontit.node.ts @@ -67,46 +67,54 @@ export class Spontit implements INodeType { const resource = this.getNodeParameter('resource', 0) as string; const operation = this.getNodeParameter('operation', 0) as string; for (let i = 0; i < items.length; i++) { - if (resource === 'push') { - if (operation === 'create') { - const content = this.getNodeParameter('content', i) as string; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + try { + if (resource === 'push') { + if (operation === 'create') { + const content = this.getNodeParameter('content', i) as string; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const body: IDataObject = { - content, - }; + const body: IDataObject = { + content, + }; - Object.assign(body, additionalFields); + Object.assign(body, additionalFields); - if (body.pushToFollowers) { - body.pushToFollowers = (body.pushToFollowers as string).split(','); + if (body.pushToFollowers) { + body.pushToFollowers = (body.pushToFollowers as string).split(','); + } + + if (body.pushToPhoneNumbers) { + body.pushToPhoneNumbers = (body.pushToPhoneNumbers as string).split(','); + } + + if (body.pushToEmails) { + body.pushToEmails = (body.pushToEmails as string).split(','); + } + + if (body.schedule) { + body.scheduled = moment.tz(body.schedule, timezone).unix(); + } + + if (body.expirationStamp) { + body.expirationStamp = moment.tz(body.expirationStamp, timezone).unix(); + } + + responseData = await spontitApiRequest.call(this, 'POST', '/push', body); + + responseData = responseData.data; } - - if (body.pushToPhoneNumbers) { - body.pushToPhoneNumbers = (body.pushToPhoneNumbers as string).split(','); - } - - if (body.pushToEmails) { - body.pushToEmails = (body.pushToEmails as string).split(','); - } - - if (body.schedule) { - body.scheduled = moment.tz(body.schedule, timezone).unix(); - } - - if (body.expirationStamp) { - body.expirationStamp = moment.tz(body.expirationStamp, timezone).unix(); - } - - responseData = await spontitApiRequest.call(this, 'POST', '/push', body); - - responseData = responseData.data; } - } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else if (responseData !== undefined) { - returnData.push(responseData as IDataObject); + if (Array.isArray(responseData)) { + returnData.push.apply(returnData, responseData as IDataObject[]); + } else if (responseData !== undefined) { + returnData.push(responseData as IDataObject); + } + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } } diff --git a/packages/nodes-base/nodes/Spotify/Spotify.node.ts b/packages/nodes-base/nodes/Spotify/Spotify.node.ts index 012867f395..e896ca83ea 100644 --- a/packages/nodes-base/nodes/Spotify/Spotify.node.ts +++ b/packages/nodes-base/nodes/Spotify/Spotify.node.ts @@ -896,321 +896,159 @@ export class Spotify implements INodeType { returnAll = false; for (let i = 0; i < items.length; i++) { - if (resource === 'player') { + try { + if (resource === 'player') { - // ----------------------------- - // Player Operations - // ----------------------------- + // ----------------------------- + // Player Operations + // ----------------------------- - if (operation === 'pause') { - requestMethod = 'PUT'; + if (operation === 'pause') { + requestMethod = 'PUT'; - endpoint = `/me/player/pause`; - - responseData = await spotifyApiRequest.call(this, requestMethod, endpoint, body, qs); - - responseData = { success: true }; - - } else if (operation === 'recentlyPlayed') { - requestMethod = 'GET'; - - endpoint = `/me/player/recently-played`; - - const limit = this.getNodeParameter('limit', i) as number; - - qs = { - limit, - }; - - responseData = await spotifyApiRequest.call(this, requestMethod, endpoint, body, qs); - - responseData = responseData.items; - - } else if (operation === 'currentlyPlaying') { - requestMethod = 'GET'; - - endpoint = `/me/player/currently-playing`; - - responseData = await spotifyApiRequest.call(this, requestMethod, endpoint, body, qs); - - } else if (operation === 'nextSong') { - requestMethod = 'POST'; - - endpoint = `/me/player/next`; - - responseData = await spotifyApiRequest.call(this, requestMethod, endpoint, body, qs); - - responseData = { success: true }; - - } else if (operation === 'previousSong') { - requestMethod = 'POST'; - - endpoint = `/me/player/previous`; - - responseData = await spotifyApiRequest.call(this, requestMethod, endpoint, body, qs); - - responseData = { success: true }; - - } else if (operation === 'startMusic') { - requestMethod = 'PUT'; - - endpoint = `/me/player/play`; - - const id = this.getNodeParameter('id', i) as string; - - body.context_uri = id; - - responseData = await spotifyApiRequest.call(this, requestMethod, endpoint, body, qs); - - responseData = { success: true }; - - } else if (operation === 'addSongToQueue') { - requestMethod = 'POST'; - - endpoint = `/me/player/queue`; - - const id = this.getNodeParameter('id', i) as string; - - qs = { - uri: id, - }; - - responseData = await spotifyApiRequest.call(this, requestMethod, endpoint, body, qs); - - responseData = { success: true }; - } else if (operation === 'resume') { - requestMethod = 'PUT'; - - endpoint = `/me/player/play`; - - responseData = await spotifyApiRequest.call(this, requestMethod, endpoint, body, qs); - - responseData = { success: true }; - } else if (operation === 'volume') { - requestMethod = 'PUT'; - - endpoint = `/me/player/volume`; - - const volumePercent = this.getNodeParameter('volumePercent', i) as number; - - qs = { - volume_percent: volumePercent, - }; - - responseData = await spotifyApiRequest.call(this, requestMethod, endpoint, body, qs); - - responseData = { success: true }; - } - - } else if (resource === 'album') { - - // ----------------------------- - // Album Operations - // ----------------------------- - - if (operation === 'get') { - const uri = this.getNodeParameter('id', i) as string; - - const id = uri.replace('spotify:album:', ''); - - requestMethod = 'GET'; - - endpoint = `/albums/${id}`; - - responseData = await spotifyApiRequest.call(this, requestMethod, endpoint, body, qs); - - } else if (operation === 'getNewReleases') { - - endpoint = '/browse/new-releases'; - requestMethod = 'GET'; - - const filters = this.getNodeParameter('filters', i) as IDataObject; - - if (Object.keys(filters).length) { - Object.assign(qs, filters); - } - - returnAll = this.getNodeParameter('returnAll', i) as boolean; - - if (!returnAll) { - qs.limit = this.getNodeParameter('limit', i); - responseData = await spotifyApiRequest.call(this, requestMethod, endpoint, body, qs); - responseData = responseData.albums.items; - } - - } else if (operation === 'getTracks') { - const uri = this.getNodeParameter('id', i) as string; - - const id = uri.replace('spotify:album:', ''); - - requestMethod = 'GET'; - - endpoint = `/albums/${id}/tracks`; - - propertyName = 'tracks'; - - returnAll = this.getNodeParameter('returnAll', i) as boolean; - - propertyName = 'items'; - - if (!returnAll) { - const limit = this.getNodeParameter('limit', i) as number; - - qs = { - limit, - }; - - responseData = await spotifyApiRequest.call(this, requestMethod, endpoint, body, qs); - - responseData = responseData.items; - } - } else if (operation === 'search') { - requestMethod = 'GET'; - - endpoint = '/search'; - - propertyName = 'albums.items'; - - returnAll = this.getNodeParameter('returnAll', i) as boolean; - const q = this.getNodeParameter('query', i) as string; - const filters = this.getNodeParameter('filters', i) as IDataObject; - - qs = { - q, - type: 'album', - ...filters, - }; - - if (returnAll === false) { - const limit = this.getNodeParameter('limit', i) as number; - qs.limit = limit; - responseData = await spotifyApiRequest.call(this, requestMethod, endpoint, body, qs); - responseData = responseData.albums.items; - } - } - - } else if (resource === 'artist') { - - // ----------------------------- - // Artist Operations - // ----------------------------- - - const uri = this.getNodeParameter('id', i, '') as string; - - const id = uri.replace('spotify:artist:', ''); - - if (operation === 'getAlbums') { - - endpoint = `/artists/${id}/albums`; - - returnAll = this.getNodeParameter('returnAll', i) as boolean; - - propertyName = 'items'; - - if (!returnAll) { - const limit = this.getNodeParameter('limit', i) as number; - - qs = { - limit, - }; - - responseData = await spotifyApiRequest.call(this, requestMethod, endpoint, body, qs); - - responseData = responseData.items; - } - - } else if (operation === 'getRelatedArtists') { - - endpoint = `/artists/${id}/related-artists`; - - responseData = await spotifyApiRequest.call(this, requestMethod, endpoint, body, qs); - - responseData = responseData.artists; - - } else if (operation === 'getTopTracks') { - const country = this.getNodeParameter('country', i) as string; - - qs = { - country, - }; - - endpoint = `/artists/${id}/top-tracks`; - - responseData = await spotifyApiRequest.call(this, requestMethod, endpoint, body, qs); - - responseData = responseData.tracks; - - } else if (operation === 'get') { - - requestMethod = 'GET'; - - endpoint = `/artists/${id}`; - - responseData = await spotifyApiRequest.call(this, requestMethod, endpoint, body, qs); - } else if (operation === 'search') { - requestMethod = 'GET'; - - endpoint = '/search'; - - propertyName = 'artists.items'; - - returnAll = this.getNodeParameter('returnAll', i) as boolean; - const q = this.getNodeParameter('query', i) as string; - const filters = this.getNodeParameter('filters', i) as IDataObject; - - qs = { - q, - limit: 50, - type: 'artist', - ...filters, - }; - - if (returnAll === false) { - const limit = this.getNodeParameter('limit', i) as number; - qs.limit = limit; - responseData = await spotifyApiRequest.call(this, requestMethod, endpoint, body, qs); - responseData = responseData.artists.items; - } - } - - } else if (resource === 'playlist') { - - // ----------------------------- - // Playlist Operations - // ----------------------------- - - if (['delete', 'get', 'getTracks', 'add'].includes(operation)) { - const uri = this.getNodeParameter('id', i) as string; - - const id = uri.replace('spotify:playlist:', ''); - - if (operation === 'delete') { - requestMethod = 'DELETE'; - const trackId = this.getNodeParameter('trackID', i) as string; - - body.tracks = [ - { - uri: trackId, - }, - ]; - - endpoint = `/playlists/${id}/tracks`; + endpoint = `/me/player/pause`; responseData = await spotifyApiRequest.call(this, requestMethod, endpoint, body, qs); responseData = { success: true }; - } else if (operation === 'get') { + } else if (operation === 'recentlyPlayed') { requestMethod = 'GET'; - endpoint = `/playlists/${id}`; + endpoint = `/me/player/recently-played`; + + const limit = this.getNodeParameter('limit', i) as number; + + qs = { + limit, + }; responseData = await spotifyApiRequest.call(this, requestMethod, endpoint, body, qs); - } else if (operation === 'getTracks') { + responseData = responseData.items; + + } else if (operation === 'currentlyPlaying') { requestMethod = 'GET'; - endpoint = `/playlists/${id}/tracks`; + endpoint = `/me/player/currently-playing`; + + responseData = await spotifyApiRequest.call(this, requestMethod, endpoint, body, qs); + + } else if (operation === 'nextSong') { + requestMethod = 'POST'; + + endpoint = `/me/player/next`; + + responseData = await spotifyApiRequest.call(this, requestMethod, endpoint, body, qs); + + responseData = { success: true }; + + } else if (operation === 'previousSong') { + requestMethod = 'POST'; + + endpoint = `/me/player/previous`; + + responseData = await spotifyApiRequest.call(this, requestMethod, endpoint, body, qs); + + responseData = { success: true }; + + } else if (operation === 'startMusic') { + requestMethod = 'PUT'; + + endpoint = `/me/player/play`; + + const id = this.getNodeParameter('id', i) as string; + + body.context_uri = id; + + responseData = await spotifyApiRequest.call(this, requestMethod, endpoint, body, qs); + + responseData = { success: true }; + + } else if (operation === 'addSongToQueue') { + requestMethod = 'POST'; + + endpoint = `/me/player/queue`; + + const id = this.getNodeParameter('id', i) as string; + + qs = { + uri: id, + }; + + responseData = await spotifyApiRequest.call(this, requestMethod, endpoint, body, qs); + + responseData = { success: true }; + } else if (operation === 'resume') { + requestMethod = 'PUT'; + + endpoint = `/me/player/play`; + + responseData = await spotifyApiRequest.call(this, requestMethod, endpoint, body, qs); + + responseData = { success: true }; + } else if (operation === 'volume') { + requestMethod = 'PUT'; + + endpoint = `/me/player/volume`; + + const volumePercent = this.getNodeParameter('volumePercent', i) as number; + + qs = { + volume_percent: volumePercent, + }; + + responseData = await spotifyApiRequest.call(this, requestMethod, endpoint, body, qs); + + responseData = { success: true }; + } + + } else if (resource === 'album') { + + // ----------------------------- + // Album Operations + // ----------------------------- + + if (operation === 'get') { + const uri = this.getNodeParameter('id', i) as string; + + const id = uri.replace('spotify:album:', ''); + + requestMethod = 'GET'; + + endpoint = `/albums/${id}`; + + responseData = await spotifyApiRequest.call(this, requestMethod, endpoint, body, qs); + + } else if (operation === 'getNewReleases') { + + endpoint = '/browse/new-releases'; + requestMethod = 'GET'; + + const filters = this.getNodeParameter('filters', i) as IDataObject; + + if (Object.keys(filters).length) { + Object.assign(qs, filters); + } + + returnAll = this.getNodeParameter('returnAll', i) as boolean; + + if (!returnAll) { + qs.limit = this.getNodeParameter('limit', i); + responseData = await spotifyApiRequest.call(this, requestMethod, endpoint, body, qs); + responseData = responseData.albums.items; + } + + } else if (operation === 'getTracks') { + const uri = this.getNodeParameter('id', i) as string; + + const id = uri.replace('spotify:album:', ''); + + requestMethod = 'GET'; + + endpoint = `/albums/${id}/tracks`; + + propertyName = 'tracks'; returnAll = this.getNodeParameter('returnAll', i) as boolean; @@ -1220,194 +1058,372 @@ export class Spotify implements INodeType { const limit = this.getNodeParameter('limit', i) as number; qs = { - 'limit': limit, + limit, }; responseData = await spotifyApiRequest.call(this, requestMethod, endpoint, body, qs); responseData = responseData.items; } - } else if (operation === 'add') { - requestMethod = 'POST'; + } else if (operation === 'search') { + requestMethod = 'GET'; - const trackId = this.getNodeParameter('trackID', i) as string; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + endpoint = '/search'; + + propertyName = 'albums.items'; + + returnAll = this.getNodeParameter('returnAll', i) as boolean; + const q = this.getNodeParameter('query', i) as string; + const filters = this.getNodeParameter('filters', i) as IDataObject; qs = { - uris: trackId, + q, + type: 'album', + ...filters, }; - if (additionalFields.position !== undefined) { - qs.position = additionalFields.position; + if (returnAll === false) { + const limit = this.getNodeParameter('limit', i) as number; + qs.limit = limit; + responseData = await spotifyApiRequest.call(this, requestMethod, endpoint, body, qs); + responseData = responseData.albums.items; + } + } + + } else if (resource === 'artist') { + + // ----------------------------- + // Artist Operations + // ----------------------------- + + const uri = this.getNodeParameter('id', i, '') as string; + + const id = uri.replace('spotify:artist:', ''); + + if (operation === 'getAlbums') { + + endpoint = `/artists/${id}/albums`; + + returnAll = this.getNodeParameter('returnAll', i) as boolean; + + propertyName = 'items'; + + if (!returnAll) { + const limit = this.getNodeParameter('limit', i) as number; + + qs = { + limit, + }; + + responseData = await spotifyApiRequest.call(this, requestMethod, endpoint, body, qs); + + responseData = responseData.items; } - endpoint = `/playlists/${id}/tracks`; + } else if (operation === 'getRelatedArtists') { + + endpoint = `/artists/${id}/related-artists`; responseData = await spotifyApiRequest.call(this, requestMethod, endpoint, body, qs); - } - } else if (operation === 'getUserPlaylists') { - requestMethod = 'GET'; - endpoint = '/me/playlists'; + responseData = responseData.artists; - returnAll = this.getNodeParameter('returnAll', i) as boolean; - - propertyName = 'items'; - - if (!returnAll) { - const limit = this.getNodeParameter('limit', i) as number; + } else if (operation === 'getTopTracks') { + const country = this.getNodeParameter('country', i) as string; qs = { - limit, + country, }; + endpoint = `/artists/${id}/top-tracks`; + responseData = await spotifyApiRequest.call(this, requestMethod, endpoint, body, qs); - responseData = responseData.items; - } + responseData = responseData.tracks; - } else if (operation === 'create') { + } else if (operation === 'get') { - // https://developer.spotify.com/console/post-playlists/ + requestMethod = 'GET'; - body.name = this.getNodeParameter('name', i) as string; + endpoint = `/artists/${id}`; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - - if (Object.keys(additionalFields).length) { - Object.assign(body, additionalFields); - } - - responseData = await spotifyApiRequest.call(this, 'POST', '/me/playlists', body, qs); - } else if (operation === 'search') { - requestMethod = 'GET'; - - endpoint = '/search'; - - propertyName = 'playlists.items'; - - returnAll = this.getNodeParameter('returnAll', i) as boolean; - const q = this.getNodeParameter('query', i) as string; - const filters = this.getNodeParameter('filters', i) as IDataObject; - - qs = { - q, - type: 'playlist', - limit: 50, - ...filters, - }; - - if (returnAll === false) { - const limit = this.getNodeParameter('limit', i) as number; - qs.limit = limit; responseData = await spotifyApiRequest.call(this, requestMethod, endpoint, body, qs); - responseData = responseData.playlists.items; - } - } + } else if (operation === 'search') { + requestMethod = 'GET'; - } else if (resource === 'track') { + endpoint = '/search'; - // ----------------------------- - // Track Operations - // ----------------------------- + propertyName = 'artists.items'; - const uri = this.getNodeParameter('id', i, '') as string; - - const id = uri.replace('spotify:track:', ''); - - requestMethod = 'GET'; - - if (operation === 'getAudioFeatures') { - endpoint = `/audio-features/${id}`; - responseData = await spotifyApiRequest.call(this, requestMethod, endpoint, body, qs); - } else if (operation === 'get') { - endpoint = `/tracks/${id}`; - responseData = await spotifyApiRequest.call(this, requestMethod, endpoint, body, qs); - } else if (operation === 'search') { - requestMethod = 'GET'; - - endpoint = '/search'; - - propertyName = 'tracks.items'; - - returnAll = this.getNodeParameter('returnAll', i) as boolean; - const q = this.getNodeParameter('query', i) as string; - const filters = this.getNodeParameter('filters', i) as IDataObject; - - qs = { - q, - type: 'track', - limit: 50, - ...filters, - }; - - if (returnAll === false) { - const limit = this.getNodeParameter('limit', i) as number; - qs.limit = limit; - responseData = await spotifyApiRequest.call(this, requestMethod, endpoint, body, qs); - responseData = responseData.tracks.items; - } - } - - } else if (resource === 'library') { - - // ----------------------------- - // Library Operations - // ----------------------------- - - if (operation === 'getLikedTracks') { - requestMethod = 'GET'; - - endpoint = '/me/tracks'; - - returnAll = this.getNodeParameter('returnAll', i) as boolean; - - propertyName = 'items'; - - if (!returnAll) { - const limit = this.getNodeParameter('limit', i) as number; + returnAll = this.getNodeParameter('returnAll', i) as boolean; + const q = this.getNodeParameter('query', i) as string; + const filters = this.getNodeParameter('filters', i) as IDataObject; qs = { - limit, - }; - - responseData = await spotifyApiRequest.call(this, requestMethod, endpoint, body, qs); - - responseData = responseData.items; - } - } - } else if (resource === 'myData') { - - if (operation === 'getFollowingArtists') { - requestMethod = 'GET'; - - endpoint = `/me/following`; - - propertyName = 'artists.items'; - - if (!returnAll) { - const limit = this.getNodeParameter('limit', i) as number; - qs = { + q, + limit: 50, type: 'artist', - limit, + ...filters, }; + + if (returnAll === false) { + const limit = this.getNodeParameter('limit', i) as number; + qs.limit = limit; + responseData = await spotifyApiRequest.call(this, requestMethod, endpoint, body, qs); + responseData = responseData.artists.items; + } + } + + } else if (resource === 'playlist') { + + // ----------------------------- + // Playlist Operations + // ----------------------------- + + if (['delete', 'get', 'getTracks', 'add'].includes(operation)) { + const uri = this.getNodeParameter('id', i) as string; + + const id = uri.replace('spotify:playlist:', ''); + + if (operation === 'delete') { + requestMethod = 'DELETE'; + const trackId = this.getNodeParameter('trackID', i) as string; + + body.tracks = [ + { + uri: trackId, + }, + ]; + + endpoint = `/playlists/${id}/tracks`; + + responseData = await spotifyApiRequest.call(this, requestMethod, endpoint, body, qs); + + responseData = { success: true }; + + } else if (operation === 'get') { + requestMethod = 'GET'; + + endpoint = `/playlists/${id}`; + + responseData = await spotifyApiRequest.call(this, requestMethod, endpoint, body, qs); + + } else if (operation === 'getTracks') { + requestMethod = 'GET'; + + endpoint = `/playlists/${id}/tracks`; + + returnAll = this.getNodeParameter('returnAll', i) as boolean; + + propertyName = 'items'; + + if (!returnAll) { + const limit = this.getNodeParameter('limit', i) as number; + + qs = { + 'limit': limit, + }; + + responseData = await spotifyApiRequest.call(this, requestMethod, endpoint, body, qs); + + responseData = responseData.items; + } + } else if (operation === 'add') { + requestMethod = 'POST'; + + const trackId = this.getNodeParameter('trackID', i) as string; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + + qs = { + uris: trackId, + }; + + if (additionalFields.position !== undefined) { + qs.position = additionalFields.position; + } + + endpoint = `/playlists/${id}/tracks`; + + responseData = await spotifyApiRequest.call(this, requestMethod, endpoint, body, qs); + } + } else if (operation === 'getUserPlaylists') { + requestMethod = 'GET'; + + endpoint = '/me/playlists'; + + returnAll = this.getNodeParameter('returnAll', i) as boolean; + + propertyName = 'items'; + + if (!returnAll) { + const limit = this.getNodeParameter('limit', i) as number; + + qs = { + limit, + }; + + responseData = await spotifyApiRequest.call(this, requestMethod, endpoint, body, qs); + + responseData = responseData.items; + } + + } else if (operation === 'create') { + + // https://developer.spotify.com/console/post-playlists/ + + body.name = this.getNodeParameter('name', i) as string; + + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + + if (Object.keys(additionalFields).length) { + Object.assign(body, additionalFields); + } + + responseData = await spotifyApiRequest.call(this, 'POST', '/me/playlists', body, qs); + } else if (operation === 'search') { + requestMethod = 'GET'; + + endpoint = '/search'; + + propertyName = 'playlists.items'; + + returnAll = this.getNodeParameter('returnAll', i) as boolean; + const q = this.getNodeParameter('query', i) as string; + const filters = this.getNodeParameter('filters', i) as IDataObject; + + qs = { + q, + type: 'playlist', + limit: 50, + ...filters, + }; + + if (returnAll === false) { + const limit = this.getNodeParameter('limit', i) as number; + qs.limit = limit; + responseData = await spotifyApiRequest.call(this, requestMethod, endpoint, body, qs); + responseData = responseData.playlists.items; + } + } + + } else if (resource === 'track') { + + // ----------------------------- + // Track Operations + // ----------------------------- + + const uri = this.getNodeParameter('id', i, '') as string; + + const id = uri.replace('spotify:track:', ''); + + requestMethod = 'GET'; + + if (operation === 'getAudioFeatures') { + endpoint = `/audio-features/${id}`; responseData = await spotifyApiRequest.call(this, requestMethod, endpoint, body, qs); - responseData = responseData.artists.items; + } else if (operation === 'get') { + endpoint = `/tracks/${id}`; + responseData = await spotifyApiRequest.call(this, requestMethod, endpoint, body, qs); + } else if (operation === 'search') { + requestMethod = 'GET'; + + endpoint = '/search'; + + propertyName = 'tracks.items'; + + returnAll = this.getNodeParameter('returnAll', i) as boolean; + const q = this.getNodeParameter('query', i) as string; + const filters = this.getNodeParameter('filters', i) as IDataObject; + + qs = { + q, + type: 'track', + limit: 50, + ...filters, + }; + + if (returnAll === false) { + const limit = this.getNodeParameter('limit', i) as number; + qs.limit = limit; + responseData = await spotifyApiRequest.call(this, requestMethod, endpoint, body, qs); + responseData = responseData.tracks.items; + } + } + + } else if (resource === 'library') { + + // ----------------------------- + // Library Operations + // ----------------------------- + + if (operation === 'getLikedTracks') { + requestMethod = 'GET'; + + endpoint = '/me/tracks'; + + returnAll = this.getNodeParameter('returnAll', i) as boolean; + + propertyName = 'items'; + + if (!returnAll) { + const limit = this.getNodeParameter('limit', i) as number; + + qs = { + limit, + }; + + responseData = await spotifyApiRequest.call(this, requestMethod, endpoint, body, qs); + + responseData = responseData.items; + } + } + } else if (resource === 'myData') { + + if (operation === 'getFollowingArtists') { + requestMethod = 'GET'; + + endpoint = `/me/following`; + + propertyName = 'artists.items'; + + if (!returnAll) { + const limit = this.getNodeParameter('limit', i) as number; + qs = { + type: 'artist', + limit, + }; + responseData = await spotifyApiRequest.call(this, requestMethod, endpoint, body, qs); + responseData = responseData.artists.items; + } } } - } - if (returnAll) { - responseData = await spotifyApiRequestAllItems.call(this, propertyName, requestMethod, endpoint, body, qs); - } + if (returnAll) { + responseData = await spotifyApiRequestAllItems.call(this, propertyName, requestMethod, endpoint, body, qs); + } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else { - returnData.push(responseData as IDataObject); + if (Array.isArray(responseData)) { + returnData.push.apply(returnData, responseData as IDataObject[]); + } else { + returnData.push(responseData as IDataObject); + } + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } } return [this.helpers.returnJsonArray(returnData)]; } } + + + + + + + + diff --git a/packages/nodes-base/nodes/SpreadsheetFile.node.ts b/packages/nodes-base/nodes/SpreadsheetFile.node.ts index 628aa0c882..b87dbde1ab 100644 --- a/packages/nodes-base/nodes/SpreadsheetFile.node.ts +++ b/packages/nodes-base/nodes/SpreadsheetFile.node.ts @@ -329,145 +329,166 @@ export class SpreadsheetFile implements INodeType { let item: INodeExecutionData; for (let i = 0; i < items.length; i++) { - item = items[i]; + try{ - const binaryPropertyName = this.getNodeParameter('binaryPropertyName', i) as string; - const options = this.getNodeParameter('options', i, {}) as IDataObject; + item = items[i]; - if (item.binary === undefined || item.binary[binaryPropertyName] === undefined) { - // Property did not get found on item - continue; - } + const binaryPropertyName = this.getNodeParameter('binaryPropertyName', i) as string; + const options = this.getNodeParameter('options', i, {}) as IDataObject; - // Read the binary spreadsheet data - const binaryData = Buffer.from(item.binary[binaryPropertyName].data, BINARY_ENCODING); - let workbook; - if (options.readAsString === true) { - workbook = xlsxRead(binaryData.toString(), { type: 'string', raw: options.rawData as boolean }); - } else { - workbook = xlsxRead(binaryData, { raw: options.rawData as boolean }); - } - - if (workbook.SheetNames.length === 0) { - throw new NodeOperationError(this.getNode(), 'Spreadsheet does not have any sheets!'); - } - - let sheetName = workbook.SheetNames[0]; - if (options.sheetName) { - if (!workbook.SheetNames.includes(options.sheetName as string)) { - throw new NodeOperationError(this.getNode(), `Spreadsheet does not contain sheet called "${options.sheetName}"!`); + if (item.binary === undefined || item.binary[binaryPropertyName] === undefined) { + // Property did not get found on item + continue; } - sheetName = options.sheetName as string; - } - // Convert it to json - const sheetToJsonOptions: Sheet2JSONOpts = {}; - if (options.range) { - if (isNaN(options.range as number)) { - sheetToJsonOptions.range = options.range; + // Read the binary spreadsheet data + const binaryData = Buffer.from(item.binary[binaryPropertyName].data, BINARY_ENCODING); + let workbook; + if (options.readAsString === true) { + workbook = xlsxRead(binaryData.toString(), { type: 'string', raw: options.rawData as boolean }); } else { - sheetToJsonOptions.range = parseInt(options.range as string, 10); + workbook = xlsxRead(binaryData, { raw: options.rawData as boolean }); } - } - if (options.includeEmptyCells) { - sheetToJsonOptions.defval = ''; - } - if (options.headerRow === false) { - sheetToJsonOptions.header = 1; // Consider the first row as a data row - } - - const sheetJson = xlsxUtils.sheet_to_json(workbook.Sheets[sheetName], sheetToJsonOptions); - - // Check if data could be found in file - if (sheetJson.length === 0) { - continue; - } - - // Add all the found data columns to the workflow data - if (options.headerRow === false) { - // Data was returned as an array - https://github.com/SheetJS/sheetjs#json - for (const rowData of sheetJson) { - newItems.push({ json: { row: rowData } } as INodeExecutionData); + if (workbook.SheetNames.length === 0) { + throw new NodeOperationError(this.getNode(), 'Spreadsheet does not have any sheets!'); } - } else { - for (const rowData of sheetJson) { - newItems.push({ json: rowData } as INodeExecutionData); + + let sheetName = workbook.SheetNames[0]; + if (options.sheetName) { + if (!workbook.SheetNames.includes(options.sheetName as string)) { + throw new NodeOperationError(this.getNode(), `Spreadsheet does not contain sheet called "${options.sheetName}"!`); + } + sheetName = options.sheetName as string; } + + // Convert it to json + const sheetToJsonOptions: Sheet2JSONOpts = {}; + if (options.range) { + if (isNaN(options.range as number)) { + sheetToJsonOptions.range = options.range; + } else { + sheetToJsonOptions.range = parseInt(options.range as string, 10); + } + } + + if (options.includeEmptyCells) { + sheetToJsonOptions.defval = ''; + } + if (options.headerRow === false) { + sheetToJsonOptions.header = 1; // Consider the first row as a data row + } + + const sheetJson = xlsxUtils.sheet_to_json(workbook.Sheets[sheetName], sheetToJsonOptions); + + // Check if data could be found in file + if (sheetJson.length === 0) { + continue; + } + + // Add all the found data columns to the workflow data + if (options.headerRow === false) { + // Data was returned as an array - https://github.com/SheetJS/sheetjs#json + for (const rowData of sheetJson) { + newItems.push({ json: { row: rowData } } as INodeExecutionData); + } + } else { + for (const rowData of sheetJson) { + newItems.push({ json: rowData } as INodeExecutionData); + } + } + + } catch (error) { + if (this.continueOnFail()) { + newItems.push({json:{ error: error.message }}); + continue; + } + throw error; } } return this.prepareOutputData(newItems); } else if (operation === 'toFile') { - // Write the workflow data to spreadsheet file - const binaryPropertyName = this.getNodeParameter('binaryPropertyName', 0) as string; - const fileFormat = this.getNodeParameter('fileFormat', 0) as string; - const options = this.getNodeParameter('options', 0, {}) as IDataObject; + try { - // Get the json data of the items and flatten it - let item: INodeExecutionData; - const itemData: IDataObject[] = []; - for (let itemIndex = 0; itemIndex < items.length; itemIndex++) { - item = items[itemIndex]; - itemData.push(flattenObject(item.json)); - } + // Write the workflow data to spreadsheet file + const binaryPropertyName = this.getNodeParameter('binaryPropertyName', 0) as string; + const fileFormat = this.getNodeParameter('fileFormat', 0) as string; + const options = this.getNodeParameter('options', 0, {}) as IDataObject; - const ws = xlsxUtils.json_to_sheet(itemData); - - const wopts: WritingOptions = { - bookSST: false, - type: 'buffer', - }; - - if (fileFormat === 'csv') { - wopts.bookType = 'csv'; - } else if (fileFormat === 'html') { - wopts.bookType = 'html'; - } else if (fileFormat === 'rtf') { - wopts.bookType = 'rtf'; - } else if (fileFormat === 'ods') { - wopts.bookType = 'ods'; - if (options.compression) { - wopts.compression = true; + // Get the json data of the items and flatten it + let item: INodeExecutionData; + const itemData: IDataObject[] = []; + for (let itemIndex = 0; itemIndex < items.length; itemIndex++) { + item = items[itemIndex]; + itemData.push(flattenObject(item.json)); } - } else if (fileFormat === 'xls') { - wopts.bookType = 'xls'; - } else if (fileFormat === 'xlsx') { - wopts.bookType = 'xlsx'; - if (options.compression) { - wopts.compression = true; + + const ws = xlsxUtils.json_to_sheet(itemData); + + const wopts: WritingOptions = { + bookSST: false, + type: 'buffer', + }; + + if (fileFormat === 'csv') { + wopts.bookType = 'csv'; + } else if (fileFormat === 'html') { + wopts.bookType = 'html'; + } else if (fileFormat === 'rtf') { + wopts.bookType = 'rtf'; + } else if (fileFormat === 'ods') { + wopts.bookType = 'ods'; + if (options.compression) { + wopts.compression = true; + } + } else if (fileFormat === 'xls') { + wopts.bookType = 'xls'; + } else if (fileFormat === 'xlsx') { + wopts.bookType = 'xlsx'; + if (options.compression) { + wopts.compression = true; + } + } + + // Convert the data in the correct format + const sheetName = options.sheetName as string || 'Sheet'; + const wb: WorkBook = { + SheetNames: [sheetName], + Sheets: { + [sheetName]: ws, + }, + }; + const wbout = xlsxWrite(wb, wopts); + + // Create a new item with only the binary spreadsheet data + const newItem: INodeExecutionData = { + json: {}, + binary: {}, + }; + + let fileName = `spreadsheet.${fileFormat}`; + if (options.fileName !== undefined) { + fileName = options.fileName as string; + } + + newItem.binary![binaryPropertyName] = await this.helpers.prepareBinaryData(wbout, fileName); + + newItems.push(newItem); + } catch (error) { + if (this.continueOnFail()) { + newItems.push({json:{ error: error.message }}); + } else { + throw error; } } - - // Convert the data in the correct format - const sheetName = options.sheetName as string || 'Sheet'; - const wb: WorkBook = { - SheetNames: [sheetName], - Sheets: { - [sheetName]: ws, - }, - }; - const wbout = xlsxWrite(wb, wopts); - - // Create a new item with only the binary spreadsheet data - const newItem: INodeExecutionData = { - json: {}, - binary: {}, - }; - - let fileName = `spreadsheet.${fileFormat}`; - if (options.fileName !== undefined) { - fileName = options.fileName as string; - } - - newItem.binary![binaryPropertyName] = await this.helpers.prepareBinaryData(wbout, fileName); - - const newItems = []; - newItems.push(newItem); - - return this.prepareOutputData(newItems); } else { - throw new NodeOperationError(this.getNode(), `The operation "${operation}" is not supported!`); + if (this.continueOnFail()) { + return this.prepareOutputData([{json:{ error: `The operation "${operation}" is not supported!` }}]); + }else{ + throw new NodeOperationError(this.getNode(), `The operation "${operation}" is not supported!`); + } } + return this.prepareOutputData(newItems); } } diff --git a/packages/nodes-base/nodes/Stackby/Stackby.node.ts b/packages/nodes-base/nodes/Stackby/Stackby.node.ts index 6e595cd12e..3db8ec3e7d 100644 --- a/packages/nodes-base/nodes/Stackby/Stackby.node.ts +++ b/packages/nodes-base/nodes/Stackby/Stackby.node.ts @@ -196,83 +196,115 @@ export class Stackby implements INodeType { const operation = this.getNodeParameter('operation', 0) as string; if (operation === 'read') { for (let i = 0; i < length; i++) { - const stackId = this.getNodeParameter('stackId', i) as string; - const table = encodeURI(this.getNodeParameter('table', i) as string); - const rowIds = this.getNodeParameter('id', i) as string; - qs.rowIds = [rowIds]; - responseData = await apiRequest.call(this, 'GET', `/rowlist/${stackId}/${table}`, {}, qs); - // tslint:disable-next-line: no-any - returnData.push.apply(returnData, responseData.map((data: any) => data.field)); + try { + const stackId = this.getNodeParameter('stackId', i) as string; + const table = encodeURI(this.getNodeParameter('table', i) as string); + const rowIds = this.getNodeParameter('id', i) as string; + qs.rowIds = [rowIds]; + responseData = await apiRequest.call(this, 'GET', `/rowlist/${stackId}/${table}`, {}, qs); + // tslint:disable-next-line: no-any + returnData.push.apply(returnData, responseData.map((data: any) => data.field)); + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; + } } } if (operation === 'delete') { for (let i = 0; i < length; i++) { - const stackId = this.getNodeParameter('stackId', i) as string; - const table = encodeURI(this.getNodeParameter('table', i) as string); - const rowIds = this.getNodeParameter('id', i) as string; - qs.rowIds = [rowIds]; + try { + const stackId = this.getNodeParameter('stackId', i) as string; + const table = encodeURI(this.getNodeParameter('table', i) as string); + const rowIds = this.getNodeParameter('id', i) as string; + qs.rowIds = [rowIds]; - responseData = await apiRequest.call(this, 'DELETE', `/rowdelete/${stackId}/${table}`, {}, qs); - responseData = responseData.records; - returnData.push.apply(returnData, responseData); + responseData = await apiRequest.call(this, 'DELETE', `/rowdelete/${stackId}/${table}`, {}, qs); + responseData = responseData.records; + returnData.push.apply(returnData, responseData); + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; + } } } if (operation === 'append') { - const records: { [key: string]: IRecord[] } = {}; - let key = ''; - for (let i = 0; i < length; i++) { - const stackId = this.getNodeParameter('stackId', i) as string; - const table = encodeURI(this.getNodeParameter('table', i) as string); - const columns = this.getNodeParameter('columns', i) as string; - const columnList = columns.split(',').map(column => column.trim()); + try { + const records: { [key: string]: IRecord[] } = {}; + let key = ''; + for (let i = 0; i < length; i++) { + const stackId = this.getNodeParameter('stackId', i) as string; + const table = encodeURI(this.getNodeParameter('table', i) as string); + const columns = this.getNodeParameter('columns', i) as string; + const columnList = columns.split(',').map(column => column.trim()); - // tslint:disable-next-line: no-any - const record: { [key: string]: any } = {}; - for (const column of columnList) { - if (items[i].json[column] === undefined) { - throw new NodeOperationError(this.getNode(), `Column ${column} does not exist on input`); - } else { - record[column] = items[i].json[column]; + // tslint:disable-next-line: no-any + const record: { [key: string]: any } = {}; + for (const column of columnList) { + if (items[i].json[column] === undefined) { + throw new NodeOperationError(this.getNode(), `Column ${column} does not exist on input`); + } else { + record[column] = items[i].json[column]; + } } - } - key = `${stackId}/${table}`; + key = `${stackId}/${table}`; - if (records[key] === undefined) { - records[key] = []; - } - records[key].push({ field: record }); - } - - for (const key of Object.keys(records)) { - responseData = await apiRequest.call(this, 'POST', `/rowcreate/${key}`, { records: records[key] }); - } - - // tslint:disable-next-line: no-any - returnData.push.apply(returnData, responseData.map((data: any) => data.field)); - } - - if (operation === 'list') { - for (let i = 0; i < length; i++) { - const stackId = this.getNodeParameter('stackId', i) as string; - const table = encodeURI(this.getNodeParameter('table', i) as string); - const returnAll = this.getNodeParameter('returnAll', 0) as boolean; - - const additionalFields = this.getNodeParameter('additionalFields', i, {}) as IDataObject; - - if (additionalFields.view) { - qs.view = additionalFields.view; + if (records[key] === undefined) { + records[key] = []; + } + records[key].push({ field: record }); } - if (returnAll === true) { - responseData = await apiRequestAllItems.call(this, 'GET', `/rowlist/${stackId}/${table}`, {}, qs); - } else { - qs.maxrecord = this.getNodeParameter('limit', 0) as number; - responseData = await apiRequest.call(this, 'GET', `/rowlist/${stackId}/${table}`, {}, qs); + for (const key of Object.keys(records)) { + responseData = await apiRequest.call(this, 'POST', `/rowcreate/${key}`, { records: records[key] }); } // tslint:disable-next-line: no-any returnData.push.apply(returnData, responseData.map((data: any) => data.field)); + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + } else { + throw error; + } + } + } + + if (operation === 'list') { + for (let i = 0; i < length; i++) { + try { + const stackId = this.getNodeParameter('stackId', i) as string; + const table = encodeURI(this.getNodeParameter('table', i) as string); + const returnAll = this.getNodeParameter('returnAll', 0) as boolean; + + const additionalFields = this.getNodeParameter('additionalFields', i, {}) as IDataObject; + + if (additionalFields.view) { + qs.view = additionalFields.view; + } + + if (returnAll === true) { + responseData = await apiRequestAllItems.call(this, 'GET', `/rowlist/${stackId}/${table}`, {}, qs); + } else { + qs.maxrecord = this.getNodeParameter('limit', 0) as number; + responseData = await apiRequest.call(this, 'GET', `/rowlist/${stackId}/${table}`, {}, qs); + } + + // tslint:disable-next-line: no-any + returnData.push.apply(returnData, responseData.map((data: any) => data.field)); + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; + } } } return [this.helpers.returnJsonArray(returnData)]; diff --git a/packages/nodes-base/nodes/Storyblok/Storyblok.node.ts b/packages/nodes-base/nodes/Storyblok/Storyblok.node.ts index fac9331865..8937fa9a21 100644 --- a/packages/nodes-base/nodes/Storyblok/Storyblok.node.ts +++ b/packages/nodes-base/nodes/Storyblok/Storyblok.node.ts @@ -187,146 +187,154 @@ export class Storyblok implements INodeType { const resource = this.getNodeParameter('resource', 0) as string; const operation = this.getNodeParameter('operation', 0) as string; for (let i = 0; i < length; i++) { - if (source === 'contentApi') { - if (resource === 'story') { - if (operation === 'get') { - const identifier = this.getNodeParameter('identifier', i) as string; + try { + if (source === 'contentApi') { + if (resource === 'story') { + if (operation === 'get') { + const identifier = this.getNodeParameter('identifier', i) as string; - responseData = await storyblokApiRequest.call(this, 'GET', `/v1/cdn/stories/${identifier}`); - responseData = responseData.story; - } - if (operation === 'getAll') { - const filters = this.getNodeParameter('filters', i) as string; - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - Object.assign(qs, filters); + responseData = await storyblokApiRequest.call(this, 'GET', `/v1/cdn/stories/${identifier}`); + responseData = responseData.story; + } + if (operation === 'getAll') { + const filters = this.getNodeParameter('filters', i) as string; + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + Object.assign(qs, filters); - if (returnAll) { - responseData = await storyblokApiRequestAllItems.call(this, 'stories', 'GET', '/v1/cdn/stories', {}, qs); - } else { - const limit = this.getNodeParameter('limit', i) as number; - qs.per_page = limit; - responseData = await storyblokApiRequest.call(this, 'GET', `/v1/cdn/stories`, {}, qs); - responseData = responseData.stories; + if (returnAll) { + responseData = await storyblokApiRequestAllItems.call(this, 'stories', 'GET', '/v1/cdn/stories', {}, qs); + } else { + const limit = this.getNodeParameter('limit', i) as number; + qs.per_page = limit; + responseData = await storyblokApiRequest.call(this, 'GET', `/v1/cdn/stories`, {}, qs); + responseData = responseData.stories; + } } } } - } - if (source === 'managementApi') { - if (resource === 'story') { - // if (operation === 'create') { - // const space = this.getNodeParameter('space', i) as string; - // const name = this.getNodeParameter('name', i) as string; - // const slug = this.getNodeParameter('slug', i) as string; - // const jsonParameters = this.getNodeParameter('jsonParameters', i) as boolean; - // const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - // const body: IDataObject = { - // name, - // slug, - // }; + if (source === 'managementApi') { + if (resource === 'story') { + // if (operation === 'create') { + // const space = this.getNodeParameter('space', i) as string; + // const name = this.getNodeParameter('name', i) as string; + // const slug = this.getNodeParameter('slug', i) as string; + // const jsonParameters = this.getNodeParameter('jsonParameters', i) as boolean; + // const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + // const body: IDataObject = { + // name, + // slug, + // }; - // if (jsonParameters) { - // if (additionalFields.contentJson) { - // const json = validateJSON(additionalFields.contentJson as string); - // body.content = json; - // } - // } else { - // if (additionalFields.contentUi) { - // const contentValue = (additionalFields.contentUi as IDataObject).contentValue as IDataObject; - // const content: { component: string, body: IDataObject[] } = { component: '', body: [] }; - // if (contentValue) { - // content.component = contentValue.component as string; - // const elementValues = (contentValue.elementUi as IDataObject).elementValues as IDataObject[]; - // for (const elementValue of elementValues) { - // const body: IDataObject = {}; - // body._uid = uuidv4(); - // body.component = elementValue.component; - // if (elementValue.dataUi) { - // const dataValues = (elementValue.dataUi as IDataObject).dataValues as IDataObject[]; - // for (const dataValue of dataValues) { - // body[dataValue.key as string] = dataValue.value; - // } - // } - // content.body.push(body); - // } - // } - // body.content = content; - // } - // } + // if (jsonParameters) { + // if (additionalFields.contentJson) { + // const json = validateJSON(additionalFields.contentJson as string); + // body.content = json; + // } + // } else { + // if (additionalFields.contentUi) { + // const contentValue = (additionalFields.contentUi as IDataObject).contentValue as IDataObject; + // const content: { component: string, body: IDataObject[] } = { component: '', body: [] }; + // if (contentValue) { + // content.component = contentValue.component as string; + // const elementValues = (contentValue.elementUi as IDataObject).elementValues as IDataObject[]; + // for (const elementValue of elementValues) { + // const body: IDataObject = {}; + // body._uid = uuidv4(); + // body.component = elementValue.component; + // if (elementValue.dataUi) { + // const dataValues = (elementValue.dataUi as IDataObject).dataValues as IDataObject[]; + // for (const dataValue of dataValues) { + // body[dataValue.key as string] = dataValue.value; + // } + // } + // content.body.push(body); + // } + // } + // body.content = content; + // } + // } - // if (additionalFields.parentId) { - // body.parent_id = additionalFields.parentId as string; - // } - // if (additionalFields.path) { - // body.path = additionalFields.path as string; - // } - // if (additionalFields.isStartpage) { - // body.is_startpage = additionalFields.isStartpage as string; - // } - // if (additionalFields.firstPublishedAt) { - // body.first_published_at = additionalFields.firstPublishedAt as string; - // } + // if (additionalFields.parentId) { + // body.parent_id = additionalFields.parentId as string; + // } + // if (additionalFields.path) { + // body.path = additionalFields.path as string; + // } + // if (additionalFields.isStartpage) { + // body.is_startpage = additionalFields.isStartpage as string; + // } + // if (additionalFields.firstPublishedAt) { + // body.first_published_at = additionalFields.firstPublishedAt as string; + // } - // responseData = await storyblokApiRequest.call(this, 'POST', `/v1/spaces/${space}/stories`, { story: body }); - // responseData = responseData.story; - // } - if (operation === 'delete') { - const space = this.getNodeParameter('space', i) as string; - const storyId = this.getNodeParameter('storyId', i) as string; + // responseData = await storyblokApiRequest.call(this, 'POST', `/v1/spaces/${space}/stories`, { story: body }); + // responseData = responseData.story; + // } + if (operation === 'delete') { + const space = this.getNodeParameter('space', i) as string; + const storyId = this.getNodeParameter('storyId', i) as string; - responseData = await storyblokApiRequest.call(this, 'DELETE', `/v1/spaces/${space}/stories/${storyId}`); - responseData = responseData.story; - } - if (operation === 'get') { - const space = this.getNodeParameter('space', i) as string; - const storyId = this.getNodeParameter('storyId', i) as string; - - responseData = await storyblokApiRequest.call(this, 'GET', `/v1/spaces/${space}/stories/${storyId}`); - responseData = responseData.story; - } - if (operation === 'getAll') { - const space = this.getNodeParameter('space', i) as string; - const filters = this.getNodeParameter('filters', i) as string; - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - Object.assign(qs, filters); - - if (returnAll) { - responseData = await storyblokApiRequestAllItems.call(this, 'stories', 'GET', `/v1/spaces/${space}/stories`, {}, qs); - } else { - const limit = this.getNodeParameter('limit', i) as number; - qs.per_page = limit; - responseData = await storyblokApiRequest.call(this, 'GET', `/v1/spaces/${space}/stories`, {}, qs); - responseData = responseData.stories; - } - } - if (operation === 'publish') { - const space = this.getNodeParameter('space', i) as string; - const storyId = this.getNodeParameter('storyId', i) as string; - const options = this.getNodeParameter('options', i) as IDataObject; - const query: IDataObject = {}; - // Not sure if these two options work - if (options.releaseId) { - query.release_id = options.releaseId as string; - } - if (options.language) { - query.lang = options.language as string; + responseData = await storyblokApiRequest.call(this, 'DELETE', `/v1/spaces/${space}/stories/${storyId}`); + responseData = responseData.story; } + if (operation === 'get') { + const space = this.getNodeParameter('space', i) as string; + const storyId = this.getNodeParameter('storyId', i) as string; - responseData = await storyblokApiRequest.call(this, 'GET', `/v1/spaces/${space}/stories/${storyId}/publish`, {}, query); - responseData = responseData.story; - } - if (operation === 'unpublish') { - const space = this.getNodeParameter('space', i) as string; - const storyId = this.getNodeParameter('storyId', i) as string; + responseData = await storyblokApiRequest.call(this, 'GET', `/v1/spaces/${space}/stories/${storyId}`); + responseData = responseData.story; + } + if (operation === 'getAll') { + const space = this.getNodeParameter('space', i) as string; + const filters = this.getNodeParameter('filters', i) as string; + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + Object.assign(qs, filters); - responseData = await storyblokApiRequest.call(this, 'GET', `/v1/spaces/${space}/stories/${storyId}/unpublish`); - responseData = responseData.story; + if (returnAll) { + responseData = await storyblokApiRequestAllItems.call(this, 'stories', 'GET', `/v1/spaces/${space}/stories`, {}, qs); + } else { + const limit = this.getNodeParameter('limit', i) as number; + qs.per_page = limit; + responseData = await storyblokApiRequest.call(this, 'GET', `/v1/spaces/${space}/stories`, {}, qs); + responseData = responseData.stories; + } + } + if (operation === 'publish') { + const space = this.getNodeParameter('space', i) as string; + const storyId = this.getNodeParameter('storyId', i) as string; + const options = this.getNodeParameter('options', i) as IDataObject; + const query: IDataObject = {}; + // Not sure if these two options work + if (options.releaseId) { + query.release_id = options.releaseId as string; + } + if (options.language) { + query.lang = options.language as string; + } + + responseData = await storyblokApiRequest.call(this, 'GET', `/v1/spaces/${space}/stories/${storyId}/publish`, {}, query); + responseData = responseData.story; + } + if (operation === 'unpublish') { + const space = this.getNodeParameter('space', i) as string; + const storyId = this.getNodeParameter('storyId', i) as string; + + responseData = await storyblokApiRequest.call(this, 'GET', `/v1/spaces/${space}/stories/${storyId}/unpublish`); + responseData = responseData.story; + } } } - } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else { - returnData.push(responseData as IDataObject); + if (Array.isArray(responseData)) { + returnData.push.apply(returnData, responseData as IDataObject[]); + } else { + returnData.push(responseData as IDataObject); + } + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } } return [this.helpers.returnJsonArray(returnData)]; diff --git a/packages/nodes-base/nodes/Strapi/Strapi.node.ts b/packages/nodes-base/nodes/Strapi/Strapi.node.ts index 2091df3a9e..943a62a4ff 100644 --- a/packages/nodes-base/nodes/Strapi/Strapi.node.ts +++ b/packages/nodes-base/nodes/Strapi/Strapi.node.ts @@ -75,117 +75,116 @@ export class Strapi implements INodeType { const { jwt } = await getToken.call(this); headers.Authorization = `Bearer ${jwt}`; + for (let i = 0; i < length; i++) { + try { + if (resource === 'entry') { + if (operation === 'create') { - if (resource === 'entry') { - if (operation === 'create') { - for (let i = 0; i < length; i++) { + const body: IDataObject = {}; - const body: IDataObject = {}; + const contentType = this.getNodeParameter('contentType', i) as string; - const contentType = this.getNodeParameter('contentType', i) as string; + const columns = this.getNodeParameter('columns', i) as string; - const columns = this.getNodeParameter('columns', i) as string; + const columnList = columns.split(',').map(column => column.trim()); - const columnList = columns.split(',').map(column => column.trim()); - - for (const key of Object.keys(items[i].json)) { - if (columnList.includes(key)) { - body[key] = items[i].json[key]; + for (const key of Object.keys(items[i].json)) { + if (columnList.includes(key)) { + body[key] = items[i].json[key]; + } } - } - responseData = await strapiApiRequest.call(this, 'POST', `/${contentType}`, body, qs, undefined, headers); + responseData = await strapiApiRequest.call(this, 'POST', `/${contentType}`, body, qs, undefined, headers); - returnData.push(responseData); - } - } - - if (operation === 'delete') { - for (let i = 0; i < length; i++) { - const contentType = this.getNodeParameter('contentType', i) as string; - - const entryId = this.getNodeParameter('entryId', i) as string; - - responseData = await strapiApiRequest.call(this, 'DELETE', `/${contentType}/${entryId}`, {}, qs, undefined, headers); - - returnData.push(responseData); - } - } - - if (operation === 'getAll') { - for (let i = 0; i < length; i++) { - - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - - const contentType = this.getNodeParameter('contentType', i) as string; - - const options = this.getNodeParameter('options', i) as IDataObject; - - if (options.sort && (options.sort as string[]).length !== 0) { - const sortFields = options.sort as string[]; - qs._sort = sortFields.join(','); + returnData.push(responseData); } - if (options.where) { - const query = validateJSON(options.where as string); - if (query !== undefined) { - qs._where = query; + if (operation === 'delete') { + const contentType = this.getNodeParameter('contentType', i) as string; + + const entryId = this.getNodeParameter('entryId', i) as string; + + responseData = await strapiApiRequest.call(this, 'DELETE', `/${contentType}/${entryId}`, {}, qs, undefined, headers); + + returnData.push(responseData); + } + + if (operation === 'getAll') { + + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + + const contentType = this.getNodeParameter('contentType', i) as string; + + const options = this.getNodeParameter('options', i) as IDataObject; + + if (options.sort && (options.sort as string[]).length !== 0) { + const sortFields = options.sort as string[]; + qs._sort = sortFields.join(','); + } + + if (options.where) { + const query = validateJSON(options.where as string); + if (query !== undefined) { + qs._where = query; + } else { + throw new NodeOperationError(this.getNode(), 'Query must be a valid JSON'); + } + } + + if (options.publicationState) { + qs._publicationState = options.publicationState as string; + } + + if (returnAll) { + responseData = await strapiApiRequestAllItems.call(this, 'GET', `/${contentType}`, {}, qs, headers); } else { - throw new NodeOperationError(this.getNode(), 'Query must be a valid JSON'); + qs._limit = this.getNodeParameter('limit', i) as number; + + responseData = await strapiApiRequest.call(this, 'GET', `/${contentType}`, {}, qs, undefined, headers); } + returnData.push.apply(returnData, responseData); } - if (options.publicationState) { - qs._publicationState = options.publicationState as string; + if (operation === 'get') { + + const contentType = this.getNodeParameter('contentType', i) as string; + + const entryId = this.getNodeParameter('entryId', i) as string; + + responseData = await strapiApiRequest.call(this, 'GET', `/${contentType}/${entryId}`, {}, qs, undefined, headers); + + returnData.push(responseData); } - if (returnAll) { - responseData = await strapiApiRequestAllItems.call(this, 'GET', `/${contentType}`, {}, qs, headers); - } else { - qs._limit = this.getNodeParameter('limit', i) as number; + if (operation === 'update') { - responseData = await strapiApiRequest.call(this, 'GET', `/${contentType}`, {}, qs, undefined, headers); - } - returnData.push.apply(returnData, responseData); - } - } + const body: IDataObject = {}; - if (operation === 'get') { - for (let i = 0; i < length; i++) { + const contentType = this.getNodeParameter('contentType', i) as string; - const contentType = this.getNodeParameter('contentType', i) as string; + const columns = this.getNodeParameter('columns', i) as string; - const entryId = this.getNodeParameter('entryId', i) as string; + const updateKey = this.getNodeParameter('updateKey', i) as string; - responseData = await strapiApiRequest.call(this, 'GET', `/${contentType}/${entryId}`, {}, qs, undefined, headers); + const columnList = columns.split(',').map(column => column.trim()); - returnData.push(responseData); - } - } + const entryId = items[i].json[updateKey]; - if (operation === 'update') { - for (let i = 0; i < length; i++) { - - const body: IDataObject = {}; - - const contentType = this.getNodeParameter('contentType', i) as string; - - const columns = this.getNodeParameter('columns', i) as string; - - const updateKey = this.getNodeParameter('updateKey', i) as string; - - const columnList = columns.split(',').map(column => column.trim()); - - const entryId = items[i].json[updateKey]; - - for (const key of Object.keys(items[i].json)) { - if (columnList.includes(key)) { - body[key] = items[i].json[key]; + for (const key of Object.keys(items[i].json)) { + if (columnList.includes(key)) { + body[key] = items[i].json[key]; + } } - } - responseData = await strapiApiRequest.call(this, 'PUT', `/${contentType}/${entryId}`, body, qs, undefined, headers); + responseData = await strapiApiRequest.call(this, 'PUT', `/${contentType}/${entryId}`, body, qs, undefined, headers); - returnData.push(responseData); + returnData.push(responseData); + } } + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } } return [this.helpers.returnJsonArray(returnData)]; diff --git a/packages/nodes-base/nodes/Strava/Strava.node.ts b/packages/nodes-base/nodes/Strava/Strava.node.ts index b420c0f519..d32f5f887b 100644 --- a/packages/nodes-base/nodes/Strava/Strava.node.ts +++ b/packages/nodes-base/nodes/Strava/Strava.node.ts @@ -71,105 +71,113 @@ export class Strava implements INodeType { const operation = this.getNodeParameter('operation', 0) as string; for (let i = 0; i < length; i++) { - if (resource === 'activity') { - //https://developers.strava.com/docs/reference/#api-Activities-createActivity - if (operation === 'create') { - const name = this.getNodeParameter('name', i) as string; + try { + if (resource === 'activity') { + //https://developers.strava.com/docs/reference/#api-Activities-createActivity + if (operation === 'create') { + const name = this.getNodeParameter('name', i) as string; - const type = this.getNodeParameter('type', i) as string; + const type = this.getNodeParameter('type', i) as string; - const startDate = this.getNodeParameter('startDate', i) as string; + const startDate = this.getNodeParameter('startDate', i) as string; - const elapsedTime = this.getNodeParameter('elapsedTime', i) as number; + const elapsedTime = this.getNodeParameter('elapsedTime', i) as number; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - if (additionalFields.trainer === true) { - additionalFields.trainer = 1; + if (additionalFields.trainer === true) { + additionalFields.trainer = 1; + } + + if (additionalFields.commute === true) { + additionalFields.commute = 1; + } + + const body: IDataObject = { + name, + type, + start_date_local: moment(startDate).toISOString(), + elapsed_time: elapsedTime, + }; + + Object.assign(body, additionalFields); + + responseData = await stravaApiRequest.call(this, 'POST', '/activities', body); } + //https://developers.strava.com/docs/reference/#api-Activities-getActivityById + if (operation === 'get') { + const activityId = this.getNodeParameter('activityId', i) as string; - if (additionalFields.commute === true) { - additionalFields.commute = 1; + responseData = await stravaApiRequest.call(this, 'GET', `/activities/${activityId}`); } + if (['getLaps', 'getZones', 'getKudos', 'getComments'].includes(operation)) { - const body: IDataObject = { - name, - type, - start_date_local: moment(startDate).toISOString(), - elapsed_time: elapsedTime, - }; + const path: IDataObject = { + 'getComments': 'comments', + 'getZones': 'zones', + 'getKudos': 'kudos', + 'getLaps': 'laps', + }; - Object.assign(body, additionalFields); + const activityId = this.getNodeParameter('activityId', i) as string; - responseData = await stravaApiRequest.call(this, 'POST', '/activities', body); - } - //https://developers.strava.com/docs/reference/#api-Activities-getActivityById - if (operation === 'get') { - const activityId = this.getNodeParameter('activityId', i) as string; + const returnAll = this.getNodeParameter('returnAll', i) as boolean; - responseData = await stravaApiRequest.call(this, 'GET', `/activities/${activityId}`); - } - if (['getLaps', 'getZones', 'getKudos', 'getComments'].includes(operation)) { + responseData = await stravaApiRequest.call(this, 'GET', `/activities/${activityId}/${path[operation]}`); - const path: IDataObject = { - 'getComments': 'comments', - 'getZones': 'zones', - 'getKudos': 'kudos', - 'getLaps': 'laps', - }; + if (returnAll === false) { + const limit = this.getNodeParameter('limit', i) as number; + responseData = responseData.splice(0, limit); + } + } + //https://developers.mailerlite.com/reference#subscribers + if (operation === 'getAll') { + const returnAll = this.getNodeParameter('returnAll', i) as boolean; - const activityId = this.getNodeParameter('activityId', i) as string; + if (returnAll) { - const returnAll = this.getNodeParameter('returnAll', i) as boolean; + responseData = await stravaApiRequestAllItems.call(this, 'GET', `/activities`, {}, qs); + } else { + qs.per_page = this.getNodeParameter('limit', i) as number; - responseData = await stravaApiRequest.call(this, 'GET', `/activities/${activityId}/${path[operation]}`); + responseData = await stravaApiRequest.call(this, 'GET', `/activities`, {}, qs); + } + } + //https://developers.strava.com/docs/reference/#api-Activities-updateActivityById + if (operation === 'update') { + const activityId = this.getNodeParameter('activityId', i) as string; - if (returnAll === false) { - const limit = this.getNodeParameter('limit', i) as number; - responseData = responseData.splice(0, limit); + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + + if (updateFields.trainer === true) { + updateFields.trainer = 1; + } + + if (updateFields.commute === true) { + updateFields.commute = 1; + } + + const body: IDataObject = {}; + + Object.assign(body, updateFields); + + responseData = await stravaApiRequest.call(this, 'PUT', `/activities/${activityId}`, body); } } - //https://developers.mailerlite.com/reference#subscribers - if (operation === 'getAll') { - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - - if (returnAll) { - - responseData = await stravaApiRequestAllItems.call(this, 'GET', `/activities`, {}, qs); - } else { - qs.per_page = this.getNodeParameter('limit', i) as number; - - responseData = await stravaApiRequest.call(this, 'GET', `/activities`, {}, qs); - } + if (Array.isArray(responseData)) { + returnData.push.apply(returnData, responseData as IDataObject[]); + } else if (responseData !== undefined) { + returnData.push(responseData as IDataObject); } - //https://developers.strava.com/docs/reference/#api-Activities-updateActivityById - if (operation === 'update') { - const activityId = this.getNodeParameter('activityId', i) as string; - - const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; - - if (updateFields.trainer === true) { - updateFields.trainer = 1; - } - - if (updateFields.commute === true) { - updateFields.commute = 1; - } - - const body: IDataObject = {}; - - Object.assign(body, updateFields); - - responseData = await stravaApiRequest.call(this, 'PUT', `/activities/${activityId}`, body); + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; } + throw error; } } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else if (responseData !== undefined) { - returnData.push(responseData as IDataObject); - } return [this.helpers.returnJsonArray(returnData)]; } } diff --git a/packages/nodes-base/nodes/Switch.node.ts b/packages/nodes-base/nodes/Switch.node.ts index 8d90399324..431bb2978f 100644 --- a/packages/nodes-base/nodes/Switch.node.ts +++ b/packages/nodes-base/nodes/Switch.node.ts @@ -621,50 +621,60 @@ export class Switch implements INodeType { // Itterate over all items to check to which output they should be routed to itemLoop: for (let itemIndex = 0; itemIndex < items.length; itemIndex++) { - item = items[itemIndex]; - mode = this.getNodeParameter('mode', itemIndex) as string; + try { - if (mode === 'expression') { - // One expression decides how to route item + item = items[itemIndex]; + mode = this.getNodeParameter('mode', itemIndex) as string; - outputIndex = this.getNodeParameter('output', itemIndex) as number; - checkIndexRange(outputIndex); - - returnData[outputIndex].push(item); - } else if (mode === 'rules') { - // Rules decide how to route item - - const dataType = this.getNodeParameter('dataType', 0) as string; - - value1 = this.getNodeParameter('value1', itemIndex) as NodeParameterValue; - if (dataType === 'dateTime') { - value1 = convertDateTime(value1); - } - - for (ruleData of this.getNodeParameter('rules.rules', itemIndex, []) as INodeParameters[]) { - // Check if the values passes - - value2 = ruleData.value2 as NodeParameterValue; - if (dataType === 'dateTime') { - value2 = convertDateTime(value2); - } - - compareOperationResult = compareOperationFunctions[ruleData.operation as string](value1, value2); - - if (compareOperationResult === true) { - // If rule matches add it to the correct output and continue with next item - checkIndexRange(ruleData.output as number); - returnData[ruleData.output as number].push(item); - continue itemLoop; - } - } - - // Check if a fallback output got defined and route accordingly - outputIndex = this.getNodeParameter('fallbackOutput', itemIndex) as number; - if (outputIndex !== -1) { + if (mode === 'expression') { + // One expression decides how to route item + + outputIndex = this.getNodeParameter('output', itemIndex) as number; checkIndexRange(outputIndex); + returnData[outputIndex].push(item); + } else if (mode === 'rules') { + // Rules decide how to route item + + const dataType = this.getNodeParameter('dataType', 0) as string; + + value1 = this.getNodeParameter('value1', itemIndex) as NodeParameterValue; + if (dataType === 'dateTime') { + value1 = convertDateTime(value1); + } + + for (ruleData of this.getNodeParameter('rules.rules', itemIndex, []) as INodeParameters[]) { + // Check if the values passes + + value2 = ruleData.value2 as NodeParameterValue; + if (dataType === 'dateTime') { + value2 = convertDateTime(value2); + } + + compareOperationResult = compareOperationFunctions[ruleData.operation as string](value1, value2); + + if (compareOperationResult === true) { + // If rule matches add it to the correct output and continue with next item + checkIndexRange(ruleData.output as number); + returnData[ruleData.output as number].push(item); + continue itemLoop; + } + } + + // Check if a fallback output got defined and route accordingly + outputIndex = this.getNodeParameter('fallbackOutput', itemIndex) as number; + if (outputIndex !== -1) { + checkIndexRange(outputIndex); + returnData[outputIndex].push(item); + } } + + } catch (error) { + if (this.continueOnFail()) { + returnData[0].push({json:{ error: error.message }}); + continue; + } + throw error; } } diff --git a/packages/nodes-base/nodes/Taiga/Taiga.node.ts b/packages/nodes-base/nodes/Taiga/Taiga.node.ts index b3eed338d3..90a49ba780 100644 --- a/packages/nodes-base/nodes/Taiga/Taiga.node.ts +++ b/packages/nodes-base/nodes/Taiga/Taiga.node.ts @@ -550,4 +550,4 @@ export class Taiga implements INodeType { return [this.helpers.returnJsonArray(returnData)]; } -} +} \ No newline at end of file diff --git a/packages/nodes-base/nodes/Tapfiliate/Tapfiliate.node.ts b/packages/nodes-base/nodes/Tapfiliate/Tapfiliate.node.ts index 43d5fc574d..141243cf8b 100644 --- a/packages/nodes-base/nodes/Tapfiliate/Tapfiliate.node.ts +++ b/packages/nodes-base/nodes/Tapfiliate/Tapfiliate.node.ts @@ -110,170 +110,156 @@ export class Tapfiliate implements INodeType { const returnData: IDataObject[] = []; const resource = this.getNodeParameter('resource', 0) as string; const operation = this.getNodeParameter('operation', 0) as string; - if (resource === 'affiliate') { - if (operation === 'create') { - //https://tapfiliate.com/docs/rest/#affiliates-affiliates-collection-post - for (let i = 0; i < length; i++) { - const firstname = this.getNodeParameter('firstname', i) as string; - const lastname = this.getNodeParameter('lastname', i) as string; - const email = this.getNodeParameter('email', i) as string; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const body: IDataObject = { - firstname, - lastname, - email, - }; - Object.assign(body, additionalFields); - - if (body.addressUi) { - body.address = (body.addressUi as IDataObject).addressValues as IDataObject; - delete body.addressUi; - if ((body.address as IDataObject).country) { - (body.address as IDataObject).country = { - code: (body.address as IDataObject).country, - }; - } - } - - if (body.companyName) { - body.company = { - name: body.companyName, + for (let i = 0; i < length; i++) { + try { + if (resource === 'affiliate') { + if (operation === 'create') { + //https://tapfiliate.com/docs/rest/#affiliates-affiliates-collection-post + const firstname = this.getNodeParameter('firstname', i) as string; + const lastname = this.getNodeParameter('lastname', i) as string; + const email = this.getNodeParameter('email', i) as string; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const body: IDataObject = { + firstname, + lastname, + email, }; - delete body.companyName; - } - responseData = await tapfiliateApiRequest.call(this, 'POST', '/affiliates/', body); - returnData.push(responseData); - } - } - if (operation === 'delete') { - //https://tapfiliate.com/docs/rest/#affiliates-affiliate-delete - for (let i = 0; i < length; i++) { - const affiliateId = this.getNodeParameter('affiliateId', i) as string; - responseData = await tapfiliateApiRequest.call(this, 'DELETE', `/affiliates/${affiliateId}/`); - returnData.push({ success: true }); - } - } - if (operation === 'get') { - //https://tapfiliate.com/docs/rest/#affiliates-affiliate-get - for (let i = 0; i < length; i++) { - const affiliateId = this.getNodeParameter('affiliateId', i) as string; - responseData = await tapfiliateApiRequest.call(this, 'GET', `/affiliates/${affiliateId}/`); - returnData.push(responseData); - } - } - if (operation === 'getAll') { - //https://tapfiliate.com/docs/rest/#affiliates-affiliates-collection-get - for (let i = 0; i < length; i++) { - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - const filters = this.getNodeParameter('filters', i) as IDataObject; - Object.assign(qs, filters); - if (returnAll) { - responseData = await tapfiliateApiRequestAllItems.call(this, 'GET', `/affiliates/`, {}, qs); - } else { - const limit = this.getNodeParameter('limit', i) as number; - responseData = await tapfiliateApiRequest.call(this, 'GET', `/affiliates/`, {}, qs); - responseData = responseData.splice(0, limit); - } - returnData.push.apply(returnData, responseData); - } - } - } - if (resource === 'affiliateMetadata') { - if (operation === 'add') { - //https://tapfiliate.com/docs/rest/#affiliates-meta-data-key-put - for (let i = 0; i < length; i++) { - const affiliateId = this.getNodeParameter('affiliateId', i) as string; - const metadata = (this.getNodeParameter('metadataUi', i) as IDataObject || {}).metadataValues as IDataObject[] || []; - if (metadata.length === 0) { - throw new NodeOperationError(this.getNode(), 'Metadata cannot be empty.'); - } - for (const { key, value } of metadata) { - await tapfiliateApiRequest.call(this, 'PUT', `/affiliates/${affiliateId}/meta-data/${key}/`, { value }); - } - returnData.push({ success: true }); - } - } - if (operation === 'remove') { - //https://tapfiliate.com/docs/rest/#affiliates-meta-data-key-delete - for (let i = 0; i < length; i++) { - const affiliateId = this.getNodeParameter('affiliateId', i) as string; - const key = this.getNodeParameter('key', i) as string; - responseData = await tapfiliateApiRequest.call(this, 'DELETE', `/affiliates/${affiliateId}/meta-data/${key}/`); - returnData.push({ success: true }); - } - } - if (operation === 'update') { - //https://tapfiliate.com/docs/rest/#affiliates-notes-collection-get - for (let i = 0; i < length; i++) { - const affiliateId = this.getNodeParameter('affiliateId', i) as string; - const key = this.getNodeParameter('key', i) as string; - const value = this.getNodeParameter('value', i) as string; - responseData = await tapfiliateApiRequest.call(this, 'PUT', `/affiliates/${affiliateId}/meta-data/`, { [key]: value }); - returnData.push(responseData); - } - } - } - if (resource === 'programAffiliate') { - if (operation === 'add') { - //https://tapfiliate.com/docs/rest/#programs-program-affiliates-collection-post - for (let i = 0; i < length; i++) { - const programId = this.getNodeParameter('programId', i) as string; - const affiliateId = this.getNodeParameter('affiliateId', i) as string; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const body: IDataObject = { - affiliate: { - id: affiliateId, - }, - }; - Object.assign(body, additionalFields); + Object.assign(body, additionalFields); - responseData = await tapfiliateApiRequest.call(this, 'POST', `/programs/${programId}/affiliates/`, body); - returnData.push(responseData); - } - } - if (operation === 'approve') { - //https://tapfiliate.com/docs/rest/#programs-approve-an-affiliate-for-a-program-put - for (let i = 0; i < length; i++) { - const programId = this.getNodeParameter('programId', i) as string; - const affiliateId = this.getNodeParameter('affiliateId', i) as string; - responseData = await tapfiliateApiRequest.call(this, 'PUT', `/programs/${programId}/affiliates/${affiliateId}/approved/`); - returnData.push(responseData); - } - } - if (operation === 'disapprove') { - //https://tapfiliate.com/docs/rest/#programs-approve-an-affiliate-for-a-program-delete - for (let i = 0; i < length; i++) { - const programId = this.getNodeParameter('programId', i) as string; - const affiliateId = this.getNodeParameter('affiliateId', i) as string; - responseData = await tapfiliateApiRequest.call(this, 'DELETE', `/programs/${programId}/affiliates/${affiliateId}/approved/`); - returnData.push(responseData); - } - } - if (operation === 'get') { - //https://tapfiliate.com/docs/rest/#programs-affiliate-in-program-get - for (let i = 0; i < length; i++) { - const programId = this.getNodeParameter('programId', i) as string; - const affiliateId = this.getNodeParameter('affiliateId', i) as string; - responseData = await tapfiliateApiRequest.call(this, 'GET', `/programs/${programId}/affiliates/${affiliateId}/`); - returnData.push(responseData); - } - } - if (operation === 'getAll') { - //https://tapfiliate.com/docs/rest/#programs-program-affiliates-collection-get - for (let i = 0; i < length; i++) { - const programId = this.getNodeParameter('programId', i) as string; - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - const filters = this.getNodeParameter('filters', i) as IDataObject; - Object.assign(qs, filters); - if (returnAll) { - responseData = await tapfiliateApiRequestAllItems.call(this, 'GET', `/programs/${programId}/affiliates/`, {}, qs); - } else { - const limit = this.getNodeParameter('limit', i) as number; - responseData = await tapfiliateApiRequest.call(this, 'GET', `/programs/${programId}/affiliates/`, {}, qs); - responseData = responseData.splice(0, limit); + if (body.addressUi) { + body.address = (body.addressUi as IDataObject).addressValues as IDataObject; + delete body.addressUi; + if ((body.address as IDataObject).country) { + (body.address as IDataObject).country = { + code: (body.address as IDataObject).country, + }; + } + } + + if (body.companyName) { + body.company = { + name: body.companyName, + }; + delete body.companyName; + } + responseData = await tapfiliateApiRequest.call(this, 'POST', '/affiliates/', body); + returnData.push(responseData); + } + if (operation === 'delete') { + //https://tapfiliate.com/docs/rest/#affiliates-affiliate-delete + const affiliateId = this.getNodeParameter('affiliateId', i) as string; + responseData = await tapfiliateApiRequest.call(this, 'DELETE', `/affiliates/${affiliateId}/`); + returnData.push({ success: true }); + } + if (operation === 'get') { + //https://tapfiliate.com/docs/rest/#affiliates-affiliate-get + const affiliateId = this.getNodeParameter('affiliateId', i) as string; + responseData = await tapfiliateApiRequest.call(this, 'GET', `/affiliates/${affiliateId}/`); + returnData.push(responseData); + } + if (operation === 'getAll') { + //https://tapfiliate.com/docs/rest/#affiliates-affiliates-collection-get + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + const filters = this.getNodeParameter('filters', i) as IDataObject; + Object.assign(qs, filters); + if (returnAll) { + responseData = await tapfiliateApiRequestAllItems.call(this, 'GET', `/affiliates/`, {}, qs); + } else { + const limit = this.getNodeParameter('limit', i) as number; + responseData = await tapfiliateApiRequest.call(this, 'GET', `/affiliates/`, {}, qs); + responseData = responseData.splice(0, limit); + } + returnData.push.apply(returnData, responseData); } - returnData.push.apply(returnData, responseData); } + if (resource === 'affiliateMetadata') { + if (operation === 'add') { + //https://tapfiliate.com/docs/rest/#affiliates-meta-data-key-put + const affiliateId = this.getNodeParameter('affiliateId', i) as string; + const metadata = (this.getNodeParameter('metadataUi', i) as IDataObject || {}).metadataValues as IDataObject[] || []; + if (metadata.length === 0) { + throw new NodeOperationError(this.getNode(), 'Metadata cannot be empty.'); + } + for (const { key, value } of metadata) { + await tapfiliateApiRequest.call(this, 'PUT', `/affiliates/${affiliateId}/meta-data/${key}/`, { value }); + } + returnData.push({ success: true }); + } + if (operation === 'remove') { + //https://tapfiliate.com/docs/rest/#affiliates-meta-data-key-delete + const affiliateId = this.getNodeParameter('affiliateId', i) as string; + const key = this.getNodeParameter('key', i) as string; + responseData = await tapfiliateApiRequest.call(this, 'DELETE', `/affiliates/${affiliateId}/meta-data/${key}/`); + returnData.push({ success: true }); + } + if (operation === 'update') { + //https://tapfiliate.com/docs/rest/#affiliates-notes-collection-get + const affiliateId = this.getNodeParameter('affiliateId', i) as string; + const key = this.getNodeParameter('key', i) as string; + const value = this.getNodeParameter('value', i) as string; + responseData = await tapfiliateApiRequest.call(this, 'PUT', `/affiliates/${affiliateId}/meta-data/`, { [key]: value }); + returnData.push(responseData); + } + } + if (resource === 'programAffiliate') { + if (operation === 'add') { + //https://tapfiliate.com/docs/rest/#programs-program-affiliates-collection-post + const programId = this.getNodeParameter('programId', i) as string; + const affiliateId = this.getNodeParameter('affiliateId', i) as string; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const body: IDataObject = { + affiliate: { + id: affiliateId, + }, + }; + Object.assign(body, additionalFields); + + responseData = await tapfiliateApiRequest.call(this, 'POST', `/programs/${programId}/affiliates/`, body); + returnData.push(responseData); + } + if (operation === 'approve') { + //https://tapfiliate.com/docs/rest/#programs-approve-an-affiliate-for-a-program-put + const programId = this.getNodeParameter('programId', i) as string; + const affiliateId = this.getNodeParameter('affiliateId', i) as string; + responseData = await tapfiliateApiRequest.call(this, 'PUT', `/programs/${programId}/affiliates/${affiliateId}/approved/`); + returnData.push(responseData); + } + if (operation === 'disapprove') { + //https://tapfiliate.com/docs/rest/#programs-approve-an-affiliate-for-a-program-delete + const programId = this.getNodeParameter('programId', i) as string; + const affiliateId = this.getNodeParameter('affiliateId', i) as string; + responseData = await tapfiliateApiRequest.call(this, 'DELETE', `/programs/${programId}/affiliates/${affiliateId}/approved/`); + returnData.push(responseData); + } + if (operation === 'get') { + //https://tapfiliate.com/docs/rest/#programs-affiliate-in-program-get + const programId = this.getNodeParameter('programId', i) as string; + const affiliateId = this.getNodeParameter('affiliateId', i) as string; + responseData = await tapfiliateApiRequest.call(this, 'GET', `/programs/${programId}/affiliates/${affiliateId}/`); + returnData.push(responseData); + } + if (operation === 'getAll') { + //https://tapfiliate.com/docs/rest/#programs-program-affiliates-collection-get + const programId = this.getNodeParameter('programId', i) as string; + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + const filters = this.getNodeParameter('filters', i) as IDataObject; + Object.assign(qs, filters); + if (returnAll) { + responseData = await tapfiliateApiRequestAllItems.call(this, 'GET', `/programs/${programId}/affiliates/`, {}, qs); + } else { + const limit = this.getNodeParameter('limit', i) as number; + responseData = await tapfiliateApiRequest.call(this, 'GET', `/programs/${programId}/affiliates/`, {}, qs); + responseData = responseData.splice(0, limit); + } + returnData.push.apply(returnData, responseData); + } + } + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } } return [this.helpers.returnJsonArray(returnData)]; diff --git a/packages/nodes-base/nodes/Telegram/Telegram.node.ts b/packages/nodes-base/nodes/Telegram/Telegram.node.ts index f07cce57e8..e386aea911 100644 --- a/packages/nodes-base/nodes/Telegram/Telegram.node.ts +++ b/packages/nodes-base/nodes/Telegram/Telegram.node.ts @@ -1753,342 +1753,350 @@ export class Telegram implements INodeType { const resource = this.getNodeParameter('resource', 0) as string; for (let i = 0; i < items.length; i++) { - // Reset all values - requestMethod = 'POST'; - endpoint = ''; - body = {}; - qs = {}; + try { + // Reset all values + requestMethod = 'POST'; + endpoint = ''; + body = {}; + qs = {}; - if (resource === 'callback') { - if (operation === 'answerQuery') { - // ---------------------------------- - // callback:answerQuery - // ---------------------------------- + if (resource === 'callback') { + if (operation === 'answerQuery') { + // ---------------------------------- + // callback:answerQuery + // ---------------------------------- - endpoint = 'answerCallbackQuery'; + endpoint = 'answerCallbackQuery'; - body.callback_query_id = this.getNodeParameter('queryId', i) as string; + body.callback_query_id = this.getNodeParameter('queryId', i) as string; - // Add additional fields - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - Object.assign(body, additionalFields); + // Add additional fields + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + Object.assign(body, additionalFields); - } else if (operation === 'answerInlineQuery') { - // ----------------------------------------------- - // callback:answerInlineQuery - // ----------------------------------------------- + } else if (operation === 'answerInlineQuery') { + // ----------------------------------------------- + // callback:answerInlineQuery + // ----------------------------------------------- - endpoint = 'answerInlineQuery'; + endpoint = 'answerInlineQuery'; - body.inline_query_id = this.getNodeParameter('queryId', i) as string; - body.results = this.getNodeParameter('results', i) as string; + body.inline_query_id = this.getNodeParameter('queryId', i) as string; + body.results = this.getNodeParameter('results', i) as string; - // Add additional fields - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - Object.assign(body, additionalFields); - } + // Add additional fields + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + Object.assign(body, additionalFields); + } - } else if (resource === 'chat') { - if (operation === 'get') { - // ---------------------------------- - // chat:get - // ---------------------------------- + } else if (resource === 'chat') { + if (operation === 'get') { + // ---------------------------------- + // chat:get + // ---------------------------------- - endpoint = 'getChat'; + endpoint = 'getChat'; - body.chat_id = this.getNodeParameter('chatId', i) as string; + body.chat_id = this.getNodeParameter('chatId', i) as string; - } else if (operation === 'leave') { - // ---------------------------------- - // chat:leave - // ---------------------------------- + } else if (operation === 'leave') { + // ---------------------------------- + // chat:leave + // ---------------------------------- - endpoint = 'leaveChat'; + endpoint = 'leaveChat'; - body.chat_id = this.getNodeParameter('chatId', i) as string; + body.chat_id = this.getNodeParameter('chatId', i) as string; - } else if (operation === 'member') { - // ---------------------------------- - // chat:member - // ---------------------------------- + } else if (operation === 'member') { + // ---------------------------------- + // chat:member + // ---------------------------------- - endpoint = 'getChatMember'; + endpoint = 'getChatMember'; - body.chat_id = this.getNodeParameter('chatId', i) as string; - body.user_id = this.getNodeParameter('userId', i) as string; + body.chat_id = this.getNodeParameter('chatId', i) as string; + body.user_id = this.getNodeParameter('userId', i) as string; - } else if (operation === 'setDescription') { - // ---------------------------------- - // chat:setDescription - // ---------------------------------- + } else if (operation === 'setDescription') { + // ---------------------------------- + // chat:setDescription + // ---------------------------------- - endpoint = 'setChatDescription'; + endpoint = 'setChatDescription'; - body.chat_id = this.getNodeParameter('chatId', i) as string; - body.description = this.getNodeParameter('description', i) as string; + body.chat_id = this.getNodeParameter('chatId', i) as string; + body.description = this.getNodeParameter('description', i) as string; - } else if (operation === 'setTitle') { - // ---------------------------------- - // chat:setTitle - // ---------------------------------- + } else if (operation === 'setTitle') { + // ---------------------------------- + // chat:setTitle + // ---------------------------------- - endpoint = 'setChatTitle'; + endpoint = 'setChatTitle'; - body.chat_id = this.getNodeParameter('chatId', i) as string; - body.title = this.getNodeParameter('title', i) as string; + body.chat_id = this.getNodeParameter('chatId', i) as string; + body.title = this.getNodeParameter('title', i) as string; - } - // } else if (resource === 'bot') { - // if (operation === 'info') { - // endpoint = 'getUpdates'; - // } - } else if (resource === 'file') { + } + // } else if (resource === 'bot') { + // if (operation === 'info') { + // endpoint = 'getUpdates'; + // } + } else if (resource === 'file') { - if (operation === 'get') { - // ---------------------------------- - // file:get - // ---------------------------------- + if (operation === 'get') { + // ---------------------------------- + // file:get + // ---------------------------------- - endpoint = 'getFile'; + endpoint = 'getFile'; - body.file_id = this.getNodeParameter('fileId', i) as string; - } + body.file_id = this.getNodeParameter('fileId', i) as string; + } - } else if (resource === 'message') { + } else if (resource === 'message') { - if (operation === 'editMessageText') { - // ---------------------------------- - // message:editMessageText - // ---------------------------------- - - endpoint = 'editMessageText'; - - const messageType = this.getNodeParameter('messageType', i) as string; - - if (messageType === 'inlineMessage') { - body.inline_message_id = this.getNodeParameter('inlineMessageId', i) as string; - } else { + if (operation === 'editMessageText') { + // ---------------------------------- + // message:editMessageText + // ---------------------------------- + + endpoint = 'editMessageText'; + + const messageType = this.getNodeParameter('messageType', i) as string; + + if (messageType === 'inlineMessage') { + body.inline_message_id = this.getNodeParameter('inlineMessageId', i) as string; + } else { + body.chat_id = this.getNodeParameter('chatId', i) as string; + body.message_id = this.getNodeParameter('messageId', i) as string; + } + + body.text = this.getNodeParameter('text', i) as string; + + // Add additional fields and replyMarkup + addAdditionalFields.call(this, body, i); + + } else if (operation === 'deleteMessage') { + // ---------------------------------- + // message:deleteMessage + // ---------------------------------- + + endpoint = 'deleteMessage'; + body.chat_id = this.getNodeParameter('chatId', i) as string; body.message_id = this.getNodeParameter('messageId', i) as string; - } - - body.text = this.getNodeParameter('text', i) as string; - - // Add additional fields and replyMarkup - addAdditionalFields.call(this, body, i); - - } else if (operation === 'deleteMessage') { - // ---------------------------------- - // message:deleteMessage - // ---------------------------------- - - endpoint = 'deleteMessage'; - - body.chat_id = this.getNodeParameter('chatId', i) as string; - body.message_id = this.getNodeParameter('messageId', i) as string; - - } else if (operation === 'pinChatMessage') { - // ---------------------------------- - // message:pinChatMessage - // ---------------------------------- - - endpoint = 'pinChatMessage'; - - body.chat_id = this.getNodeParameter('chatId', i) as string; - body.message_id = this.getNodeParameter('messageId', i) as string; - - const { disable_notification } = this.getNodeParameter('additionalFields', i) as IDataObject; - if (disable_notification) { - body.disable_notification = true; - } - - } else if (operation === 'unpinChatMessage') { - // ---------------------------------- - // message:unpinChatMessage - // ---------------------------------- - - endpoint = 'unpinChatMessage'; - - body.chat_id = this.getNodeParameter('chatId', i) as string; - body.message_id = this.getNodeParameter('messageId', i) as string; - - } else if (operation === 'sendAnimation') { - // ---------------------------------- - // message:sendAnimation - // ---------------------------------- - - endpoint = 'sendAnimation'; - - body.chat_id = this.getNodeParameter('chatId', i) as string; - body.animation = this.getNodeParameter('file', i) as string; - - // Add additional fields and replyMarkup - addAdditionalFields.call(this, body, i); - - - } else if (operation === 'sendAudio') { - // ---------------------------------- - // message:sendAudio - // ---------------------------------- - - endpoint = 'sendAudio'; - - body.chat_id = this.getNodeParameter('chatId', i) as string; - body.audio = this.getNodeParameter('file', i) as string; - - // Add additional fields and replyMarkup - addAdditionalFields.call(this, body, i); - - } else if (operation === 'sendChatAction') { - // ---------------------------------- - // message:sendChatAction - // ---------------------------------- - - endpoint = 'sendChatAction'; - - body.chat_id = this.getNodeParameter('chatId', i) as string; - body.action = this.getNodeParameter('action', i) as string; - - } else if (operation === 'sendDocument') { - // ---------------------------------- - // message:sendDocument - // ---------------------------------- - - endpoint = 'sendDocument'; - - body.chat_id = this.getNodeParameter('chatId', i) as string; - body.document = this.getNodeParameter('file', i) as string; - - // Add additional fields and replyMarkup - addAdditionalFields.call(this, body, i); - - } else if (operation === 'sendLocation') { - // ---------------------------------- - // message:sendLocation - // ---------------------------------- - - endpoint = 'sendLocation'; - - body.chat_id = this.getNodeParameter('chatId', i) as string; - body.latitude = this.getNodeParameter('latitude', i) as string; - body.longitude = this.getNodeParameter('longitude', i) as string; - - // Add additional fields and replyMarkup - addAdditionalFields.call(this, body, i); - - } else if (operation === 'sendMessage') { - // ---------------------------------- - // message:sendMessage - // ---------------------------------- - - endpoint = 'sendMessage'; - - body.chat_id = this.getNodeParameter('chatId', i) as string; - body.text = this.getNodeParameter('text', i) as string; - - // Add additional fields and replyMarkup - addAdditionalFields.call(this, body, i); - - } else if (operation === 'sendMediaGroup') { - // ---------------------------------- - // message:sendMediaGroup - // ---------------------------------- - - endpoint = 'sendMediaGroup'; - - body.chat_id = this.getNodeParameter('chatId', i) as string; - - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - Object.assign(body, additionalFields); - - const mediaItems = this.getNodeParameter('media', i) as IDataObject; - body.media = []; - for (const mediaItem of mediaItems.media as IDataObject[]) { - if (mediaItem.additionalFields !== undefined) { - Object.assign(mediaItem, mediaItem.additionalFields); - delete mediaItem.additionalFields; + + } else if (operation === 'pinChatMessage') { + // ---------------------------------- + // message:pinChatMessage + // ---------------------------------- + + endpoint = 'pinChatMessage'; + + body.chat_id = this.getNodeParameter('chatId', i) as string; + body.message_id = this.getNodeParameter('messageId', i) as string; + + const { disable_notification } = this.getNodeParameter('additionalFields', i) as IDataObject; + if (disable_notification) { + body.disable_notification = true; } - (body.media as IDataObject[]).push(mediaItem); + + } else if (operation === 'unpinChatMessage') { + // ---------------------------------- + // message:unpinChatMessage + // ---------------------------------- + + endpoint = 'unpinChatMessage'; + + body.chat_id = this.getNodeParameter('chatId', i) as string; + body.message_id = this.getNodeParameter('messageId', i) as string; + + } else if (operation === 'sendAnimation') { + // ---------------------------------- + // message:sendAnimation + // ---------------------------------- + + endpoint = 'sendAnimation'; + + body.chat_id = this.getNodeParameter('chatId', i) as string; + body.animation = this.getNodeParameter('file', i) as string; + + // Add additional fields and replyMarkup + addAdditionalFields.call(this, body, i); + + + } else if (operation === 'sendAudio') { + // ---------------------------------- + // message:sendAudio + // ---------------------------------- + + endpoint = 'sendAudio'; + + body.chat_id = this.getNodeParameter('chatId', i) as string; + body.audio = this.getNodeParameter('file', i) as string; + + // Add additional fields and replyMarkup + addAdditionalFields.call(this, body, i); + + } else if (operation === 'sendChatAction') { + // ---------------------------------- + // message:sendChatAction + // ---------------------------------- + + endpoint = 'sendChatAction'; + + body.chat_id = this.getNodeParameter('chatId', i) as string; + body.action = this.getNodeParameter('action', i) as string; + + } else if (operation === 'sendDocument') { + // ---------------------------------- + // message:sendDocument + // ---------------------------------- + + endpoint = 'sendDocument'; + + body.chat_id = this.getNodeParameter('chatId', i) as string; + body.document = this.getNodeParameter('file', i) as string; + + // Add additional fields and replyMarkup + addAdditionalFields.call(this, body, i); + + } else if (operation === 'sendLocation') { + // ---------------------------------- + // message:sendLocation + // ---------------------------------- + + endpoint = 'sendLocation'; + + body.chat_id = this.getNodeParameter('chatId', i) as string; + body.latitude = this.getNodeParameter('latitude', i) as string; + body.longitude = this.getNodeParameter('longitude', i) as string; + + // Add additional fields and replyMarkup + addAdditionalFields.call(this, body, i); + + } else if (operation === 'sendMessage') { + // ---------------------------------- + // message:sendMessage + // ---------------------------------- + + endpoint = 'sendMessage'; + + body.chat_id = this.getNodeParameter('chatId', i) as string; + body.text = this.getNodeParameter('text', i) as string; + + // Add additional fields and replyMarkup + addAdditionalFields.call(this, body, i); + + } else if (operation === 'sendMediaGroup') { + // ---------------------------------- + // message:sendMediaGroup + // ---------------------------------- + + endpoint = 'sendMediaGroup'; + + body.chat_id = this.getNodeParameter('chatId', i) as string; + + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + Object.assign(body, additionalFields); + + const mediaItems = this.getNodeParameter('media', i) as IDataObject; + body.media = []; + for (const mediaItem of mediaItems.media as IDataObject[]) { + if (mediaItem.additionalFields !== undefined) { + Object.assign(mediaItem, mediaItem.additionalFields); + delete mediaItem.additionalFields; + } + (body.media as IDataObject[]).push(mediaItem); + } + + } else if (operation === 'sendPhoto') { + // ---------------------------------- + // message:sendPhoto + // ---------------------------------- + + endpoint = 'sendPhoto'; + + body.chat_id = this.getNodeParameter('chatId', i) as string; + body.photo = this.getNodeParameter('file', i) as string; + + // Add additional fields and replyMarkup + addAdditionalFields.call(this, body, i); + + } else if (operation === 'sendSticker') { + // ---------------------------------- + // message:sendSticker + // ---------------------------------- + + endpoint = 'sendSticker'; + + body.chat_id = this.getNodeParameter('chatId', i) as string; + body.sticker = this.getNodeParameter('file', i) as string; + + // Add additional fields and replyMarkup + addAdditionalFields.call(this, body, i); + + } else if (operation === 'sendVideo') { + // ---------------------------------- + // message:sendVideo + // ---------------------------------- + + endpoint = 'sendVideo'; + + body.chat_id = this.getNodeParameter('chatId', i) as string; + body.video = this.getNodeParameter('file', i) as string; + + // Add additional fields and replyMarkup + addAdditionalFields.call(this, body, i); + } - - } else if (operation === 'sendPhoto') { - // ---------------------------------- - // message:sendPhoto - // ---------------------------------- - - endpoint = 'sendPhoto'; - - body.chat_id = this.getNodeParameter('chatId', i) as string; - body.photo = this.getNodeParameter('file', i) as string; - - // Add additional fields and replyMarkup - addAdditionalFields.call(this, body, i); - - } else if (operation === 'sendSticker') { - // ---------------------------------- - // message:sendSticker - // ---------------------------------- - - endpoint = 'sendSticker'; - - body.chat_id = this.getNodeParameter('chatId', i) as string; - body.sticker = this.getNodeParameter('file', i) as string; - - // Add additional fields and replyMarkup - addAdditionalFields.call(this, body, i); - - } else if (operation === 'sendVideo') { - // ---------------------------------- - // message:sendVideo - // ---------------------------------- - - endpoint = 'sendVideo'; - - body.chat_id = this.getNodeParameter('chatId', i) as string; - body.video = this.getNodeParameter('file', i) as string; - - // Add additional fields and replyMarkup - addAdditionalFields.call(this, body, i); - + } else { + throw new NodeOperationError(this.getNode(), `The resource "${resource}" is not known!`); } - } else { - throw new NodeOperationError(this.getNode(), `The resource "${resource}" is not known!`); - } - const responseData = await apiRequest.call(this, requestMethod, endpoint, body, qs); + const responseData = await apiRequest.call(this, requestMethod, endpoint, body, qs); - if (resource === 'file' && operation === 'get') { - if (this.getNodeParameter('download', i, false) as boolean === true) { - const filePath = responseData.result.file_path; + if (resource === 'file' && operation === 'get') { + if (this.getNodeParameter('download', i, false) as boolean === true) { + const filePath = responseData.result.file_path; - const credentials = this.getCredentials('telegramApi'); + const credentials = this.getCredentials('telegramApi'); - if (credentials === undefined) { - throw new NodeOperationError(this.getNode(), 'No credentials got returned!'); + if (credentials === undefined) { + throw new NodeOperationError(this.getNode(), 'No credentials got returned!'); + } + const file = await apiRequest.call(this, 'GET', '', {}, {}, { json: false, encoding: null, uri: `https://api.telegram.org/file/bot${credentials.accessToken}/${filePath}`, resolveWithFullResponse: true }); + + const fileName = filePath.split('/').pop(); + const binaryData = await this.helpers.prepareBinaryData(Buffer.from(file.body as string), fileName); + + returnData.push({ + json: responseData, + binary: { + data: binaryData, + }, + }); + continue; } - const file = await apiRequest.call(this, 'GET', '', {}, {}, { json: false, encoding: null, uri: `https://api.telegram.org/file/bot${credentials.accessToken}/${filePath}`, resolveWithFullResponse: true }); + } - const fileName = filePath.split('/').pop(); - const binaryData = await this.helpers.prepareBinaryData(Buffer.from(file.body as string), fileName); + // if (resource === 'bot' && operation === 'info') { + // responseData = { + // user: responseData.result[0].message.from, + // chat: responseData.result[0].message.chat, + // }; + // } - returnData.push({ - json: responseData, - binary: { - data: binaryData, - }, - }); + returnData.push({ json: responseData }); + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ json: { error: error.message } }); continue; } + throw error; } - - // if (resource === 'bot' && operation === 'info') { - // responseData = { - // user: responseData.result[0].message.from, - // chat: responseData.result[0].message.chat, - // }; - // } - - returnData.push({ json: responseData }); } return this.prepareOutputData(returnData); diff --git a/packages/nodes-base/nodes/TheHive/TheHive.node.ts b/packages/nodes-base/nodes/TheHive/TheHive.node.ts index 0db28ce56c..554b22dd20 100644 --- a/packages/nodes-base/nodes/TheHive/TheHive.node.ts +++ b/packages/nodes-base/nodes/TheHive/TheHive.node.ts @@ -321,1563 +321,608 @@ export class TheHive implements INodeType { const operation = this.getNodeParameter('operation', 0) as string; for (let i = 0; i < length; i++) { - if (resource === 'alert') { - if (operation === 'count') { - const filters = this.getNodeParameter('filters', i, {}) as INodeParameters; - const countQueryAttributs: any = prepareOptional(filters); // tslint:disable-line:no-any - - const _countSearchQuery: IQueryObject = And(); + try { + if (resource === 'alert') { + if (operation === 'count') { + const filters = this.getNodeParameter('filters', i, {}) as INodeParameters; + const countQueryAttributs: any = prepareOptional(filters); // tslint:disable-line:no-any + + const _countSearchQuery: IQueryObject = And(); - if ('customFieldsUi' in filters) { - const customFields = await prepareCustomFields.call(this, filters) as IDataObject; - const searchQueries = buildCustomFieldSearch(customFields); - (_countSearchQuery['_and'] as IQueryObject[]).push(...searchQueries); - } - - for (const key of Object.keys(countQueryAttributs)) { - if (key === 'tags') { - (_countSearchQuery['_and'] as IQueryObject[]).push( - In(key, countQueryAttributs[key] as string[]), - ); - } else if (key === 'description' || key === 'title') { - (_countSearchQuery['_and'] as IQueryObject[]).push( - ContainsString(key, countQueryAttributs[key] as string), - ); - } else { - (_countSearchQuery['_and'] as IQueryObject[]).push( - Eq(key, countQueryAttributs[key] as string), - ); + if ('customFieldsUi' in filters) { + const customFields = await prepareCustomFields.call(this, filters) as IDataObject; + const searchQueries = buildCustomFieldSearch(customFields); + (_countSearchQuery['_and'] as IQueryObject[]).push(...searchQueries); } - } - const body = { - 'query': [ - { - '_name': 'listAlert', - }, - { - '_name': 'filter', - '_and': _countSearchQuery['_and'], - }, - ], - }; - - body['query'].push( - { - '_name': 'count', - }, - ); - - qs.name = 'count-Alert'; - - responseData = await theHiveApiRequest.call( - this, - 'POST', - '/v1/query', - body, - qs, - ); - - responseData = { count: responseData }; - } - - if (operation === 'create') { - const additionalFields = this.getNodeParameter('additionalFields', i) as INodeParameters; - const jsonParameters = this.getNodeParameter('jsonParameters', i) as boolean; - - const customFields = await prepareCustomFields.call(this, additionalFields, jsonParameters); - const body: IDataObject = { - title: this.getNodeParameter('title', i), - description: this.getNodeParameter('description', i), - severity: this.getNodeParameter('severity', i), - date: Date.parse(this.getNodeParameter('date', i) as string), - tags: splitTags(this.getNodeParameter('tags', i) as string), - tlp: this.getNodeParameter('tlp', i), - status: this.getNodeParameter('status', i), - type: this.getNodeParameter('type', i), - source: this.getNodeParameter('source', i), - sourceRef: this.getNodeParameter('sourceRef', i), - follow: this.getNodeParameter('follow', i, true), - customFields, - ...prepareOptional(additionalFields), - }; - - const artifactUi = this.getNodeParameter('artifactUi', i) as IDataObject; - - if (artifactUi) { - - const artifactValues = (artifactUi as IDataObject).artifactValues as IDataObject[]; - - if (artifactValues) { - - const artifactData = []; - - for (const artifactvalue of artifactValues) { - - const element: IDataObject = {}; - - element.message = artifactvalue.message as string; - - element.tags = (artifactvalue.tags as string).split(',') as string[]; - - element.dataType = artifactvalue.dataType as string; - - element.data = artifactvalue.data as string; - - if (artifactvalue.dataType === 'file') { - - const item = items[i]; - - if (item.binary === undefined) { - throw new NodeOperationError(this.getNode(), 'No binary data exists on item!'); - } - - const binaryPropertyName = artifactvalue.binaryProperty as string; - - if (item.binary[binaryPropertyName] === undefined) { - throw new NodeOperationError(this.getNode(), `No binary data property '${binaryPropertyName}' does not exists on item!`); - } - - const binaryData = item.binary[binaryPropertyName] as IBinaryData; - - element.data = `${binaryData.fileName};${binaryData.mimeType};${binaryData.data}`; - } - - artifactData.push(element); + for (const key of Object.keys(countQueryAttributs)) { + if (key === 'tags') { + (_countSearchQuery['_and'] as IQueryObject[]).push( + In(key, countQueryAttributs[key] as string[]), + ); + } else if (key === 'description' || key === 'title') { + (_countSearchQuery['_and'] as IQueryObject[]).push( + ContainsString(key, countQueryAttributs[key] as string), + ); + } else { + (_countSearchQuery['_and'] as IQueryObject[]).push( + Eq(key, countQueryAttributs[key] as string), + ); } - body.artifacts = artifactData; } - } - responseData = await theHiveApiRequest.call( - this, - 'POST', - '/alert' as string, - body, - ); - } - - /* - Execute responder feature differs from Cortex execute responder - if it doesn't interfere with n8n standards then we should keep it - */ - - if (operation === 'executeResponder') { - const alertId = this.getNodeParameter('id', i); - const responderId = this.getNodeParameter('responder', i) as string; - let body: IDataObject; - let response; - responseData = []; - body = { - responderId, - objectId: alertId, - objectType: 'alert', - }; - response = await theHiveApiRequest.call( - this, - 'POST', - '/connector/cortex/action' as string, - body, - ); - body = { - query: [ - { - '_name': 'listAction', - }, - { - '_name': 'filter', - '_and': [ - { - '_field': 'cortexId', - '_value': response.cortexId, - }, - { - '_field': 'objectId', - '_value': response.objectId, - }, - { - '_field': 'startDate', - '_value': response.startDate, - }, - - ], - }, - ], - }; - qs.name = 'log-actions'; - do { - response = await theHiveApiRequest.call( - this, - 'POST', - `/v1/query`, - body, - qs, - ); - } while (response.status === 'Waiting' || response.status === 'InProgress'); - - responseData = response; - } - - if (operation === 'get') { - const alertId = this.getNodeParameter('id', i) as string; - - responseData = await theHiveApiRequest.call( - this, - 'GET', - `/alert/${alertId}`, - {}, - ); - } - - if (operation === 'getAll') { - const credentials = this.getCredentials('theHiveApi') as IDataObject; - - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - - const version = credentials.apiVersion; - - const filters = this.getNodeParameter('filters', i, {}) as INodeParameters; - const queryAttributs: any = prepareOptional(filters); // tslint:disable-line:no-any - const options = this.getNodeParameter('options', i) as IDataObject; - - const _searchQuery: IQueryObject = And(); - - if ('customFieldsUi' in filters) { - const customFields = await prepareCustomFields.call(this, filters) as IDataObject; - const searchQueries = buildCustomFieldSearch(customFields); - (_searchQuery['_and'] as IQueryObject[]).push(...searchQueries); - } - - for (const key of Object.keys(queryAttributs)) { - if (key === 'tags') { - (_searchQuery['_and'] as IQueryObject[]).push( - In(key, queryAttributs[key] as string[]), - ); - } else if (key === 'description' || key === 'title') { - (_searchQuery['_and'] as IQueryObject[]).push( - ContainsString(key, queryAttributs[key] as string), - ); - } else { - (_searchQuery['_and'] as IQueryObject[]).push( - Eq(key, queryAttributs[key] as string), - ); - } - } - - let endpoint; - - let method; - - let body: IDataObject = {}; - - let limit = undefined; - - if (returnAll === false) { - limit = this.getNodeParameter('limit', i) as number; - } - - if (version === 'v1') { - endpoint = '/v1/query'; - - method = 'POST'; - - body = { + const body = { 'query': [ { '_name': 'listAlert', }, { '_name': 'filter', - '_and': _searchQuery['_and'], + '_and': _countSearchQuery['_and'], }, ], }; - //@ts-ignore - prepareSortQuery(options.sort, body); + body['query'].push( + { + '_name': 'count', + }, + ); - if (limit !== undefined) { - //@ts-ignore - prepareRangeQuery(`0-${limit}`, body); - } + qs.name = 'count-Alert'; - qs.name = 'alerts'; - - } else { - method = 'POST'; - - endpoint = '/alert/_search'; - - if (limit !== undefined) { - qs.range = `0-${limit}`; - } - - body.query = _searchQuery; - - Object.assign(qs, prepareOptional(options)); + responseData = await theHiveApiRequest.call( + this, + 'POST', + '/v1/query', + body, + qs, + ); + responseData = { count: responseData }; } - responseData = await theHiveApiRequest.call( - this, - method, - endpoint as string, - body, - qs, - ); - } + if (operation === 'create') { + const additionalFields = this.getNodeParameter('additionalFields', i) as INodeParameters; + const jsonParameters = this.getNodeParameter('jsonParameters', i) as boolean; - if (operation === 'markAsRead') { - const alertId = this.getNodeParameter('id', i) as string; + const customFields = await prepareCustomFields.call(this, additionalFields, jsonParameters); + const body: IDataObject = { + title: this.getNodeParameter('title', i), + description: this.getNodeParameter('description', i), + severity: this.getNodeParameter('severity', i), + date: Date.parse(this.getNodeParameter('date', i) as string), + tags: splitTags(this.getNodeParameter('tags', i) as string), + tlp: this.getNodeParameter('tlp', i), + status: this.getNodeParameter('status', i), + type: this.getNodeParameter('type', i), + source: this.getNodeParameter('source', i), + sourceRef: this.getNodeParameter('sourceRef', i), + follow: this.getNodeParameter('follow', i, true), + customFields, + ...prepareOptional(additionalFields), + }; - responseData = await theHiveApiRequest.call( - this, - 'POST', - `/alert/${alertId}/markAsRead`, - ); - } + const artifactUi = this.getNodeParameter('artifactUi', i) as IDataObject; - if (operation === 'markAsUnread') { - const alertId = this.getNodeParameter('id', i) as string; + if (artifactUi) { - responseData = await theHiveApiRequest.call( - this, - 'POST', - `/alert/${alertId}/markAsUnread`, - ); - } + const artifactValues = (artifactUi as IDataObject).artifactValues as IDataObject[]; - if (operation === 'merge') { - const alertId = this.getNodeParameter('id', i) as string; + if (artifactValues) { - const caseId = this.getNodeParameter('caseId', i) as string; + const artifactData = []; - responseData = await theHiveApiRequest.call( - this, - 'POST', - `/alert/${alertId}/merge/${caseId}`, - {}, - ); - } + for (const artifactvalue of artifactValues) { - if (operation === 'promote') { - const alertId = this.getNodeParameter('id', i) as string; + const element: IDataObject = {}; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + element.message = artifactvalue.message as string; - const body: IDataObject = {}; + element.tags = (artifactvalue.tags as string).split(',') as string[]; - Object.assign(body, additionalFields); + element.dataType = artifactvalue.dataType as string; - responseData = await theHiveApiRequest.call( - this, - 'POST', - `/alert/${alertId}/createCase`, - body, - ); - } + element.data = artifactvalue.data as string; - if (operation === 'update') { - const alertId = this.getNodeParameter('id', i) as string; - const jsonParameters = this.getNodeParameter('jsonParameters', i) as boolean; + if (artifactvalue.dataType === 'file') { - const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; - const customFields = await prepareCustomFields.call(this, updateFields, jsonParameters); + const item = items[i]; - const artifactUi = updateFields.artifactUi as IDataObject; + if (item.binary === undefined) { + throw new NodeOperationError(this.getNode(), 'No binary data exists on item!'); + } - delete updateFields.artifactUi; + const binaryPropertyName = artifactvalue.binaryProperty as string; - const body: IDataObject = { - customFields, - }; + if (item.binary[binaryPropertyName] === undefined) { + throw new NodeOperationError(this.getNode(), `No binary data property '${binaryPropertyName}' does not exists on item!`); + } - Object.assign(body, updateFields); + const binaryData = item.binary[binaryPropertyName] as IBinaryData; - if (artifactUi) { - const artifactValues = (artifactUi as IDataObject).artifactValues as IDataObject[]; - - if (artifactValues) { - const artifactData = []; - - for (const artifactvalue of artifactValues) { - - const element: IDataObject = {}; - - element.message = artifactvalue.message as string; - - element.tags = (artifactvalue.tags as string).split(',') as string[]; - - element.dataType = artifactvalue.dataType as string; - - element.data = artifactvalue.data as string; - - if (artifactvalue.dataType === 'file') { - const item = items[i]; - - if (item.binary === undefined) { - throw new NodeOperationError(this.getNode(), 'No binary data exists on item!'); + element.data = `${binaryData.fileName};${binaryData.mimeType};${binaryData.data}`; } - const binaryPropertyName = artifactvalue.binaryProperty as string; - - if (item.binary[binaryPropertyName] === undefined) { - throw new NodeOperationError(this.getNode(), `No binary data property '${binaryPropertyName}' does not exists on item!`); - } - - const binaryData = item.binary[binaryPropertyName] as IBinaryData; - - element.data = `${binaryData.fileName};${binaryData.mimeType};${binaryData.data}`; + artifactData.push(element); } - - artifactData.push(element); + body.artifacts = artifactData; } - body.artifacts = artifactData; } + + responseData = await theHiveApiRequest.call( + this, + 'POST', + '/alert' as string, + body, + ); } - responseData = await theHiveApiRequest.call( - this, - 'PATCH', - `/alert/${alertId}` as string, - body, - ); - } - } + /* + Execute responder feature differs from Cortex execute responder + if it doesn't interfere with n8n standards then we should keep it + */ - if (resource === 'observable') { - if (operation === 'count') { - const countQueryAttributs: any = prepareOptional(this.getNodeParameter('filters', i, {}) as INodeParameters); // tslint:disable-line:no-any - - const _countSearchQuery: IQueryObject = And(); - - for (const key of Object.keys(countQueryAttributs)) { - if (key === 'dataType' || key === 'tags') { - (_countSearchQuery['_and'] as IQueryObject[]).push( - In(key, countQueryAttributs[key] as string[]), - ); - } else if (key === 'description' || key === 'keywork' || key === 'message') { - (_countSearchQuery['_and'] as IQueryObject[]).push( - ContainsString(key, countQueryAttributs[key] as string), - ); - } else if (key === 'range') { - (_countSearchQuery['_and'] as IQueryObject[]).push( - Between( - 'startDate', - countQueryAttributs['range']['dateRange']['fromDate'], - countQueryAttributs['range']['dateRange']['toDate'], - ), - ); - } else { - (_countSearchQuery['_and'] as IQueryObject[]).push( - Eq(key, countQueryAttributs[key] as string), - ); - } - } - - const body = { - 'query': [ - { - '_name': 'listObservable', - }, - { - '_name': 'filter', - '_and': _countSearchQuery['_and'], - }, - ], - }; - - body['query'].push( - { - '_name': 'count', - }, - ); - - qs.name = 'count-observables'; - - responseData = await theHiveApiRequest.call( - this, - 'POST', - '/v1/query', - body, - qs, - ); - - responseData = { count: responseData }; - } - - if (operation === 'executeAnalyzer') { - const observableId = this.getNodeParameter('id', i); - const analyzers = (this.getNodeParameter('analyzers', i) as string[]) - .map(analyzer => { - const parts = analyzer.split('::'); - return { - analyzerId: parts[0], - cortexId: parts[1], - }; - }); - let response: any; // tslint:disable-line:no-any - let body: IDataObject; - responseData = []; - for (const analyzer of analyzers) { + if (operation === 'executeResponder') { + const alertId = this.getNodeParameter('id', i); + const responderId = this.getNodeParameter('responder', i) as string; + let body: IDataObject; + let response; + responseData = []; body = { - ...analyzer, - artifactId: observableId, + responderId, + objectId: alertId, + objectType: 'alert', }; - // execute the analyzer response = await theHiveApiRequest.call( this, 'POST', - '/connector/cortex/job' as string, + '/connector/cortex/action' as string, body, - qs, ); - const jobId = response.id; - qs.name = 'observable-jobs'; - // query the job result (including the report) + body = { + query: [ + { + '_name': 'listAction', + }, + { + '_name': 'filter', + '_and': [ + { + '_field': 'cortexId', + '_value': response.cortexId, + }, + { + '_field': 'objectId', + '_value': response.objectId, + }, + { + '_field': 'startDate', + '_value': response.startDate, + }, + + ], + }, + ], + }; + qs.name = 'log-actions'; do { - responseData = await theHiveApiRequest.call(this, 'GET', `/connector/cortex/job/${jobId}`, body, qs); - } while (responseData.status === 'Waiting' || responseData.status === 'InProgress'); + response = await theHiveApiRequest.call( + this, + 'POST', + `/v1/query`, + body, + qs, + ); + } while (response.status === 'Waiting' || response.status === 'InProgress'); + + responseData = response; } - } + if (operation === 'get') { + const alertId = this.getNodeParameter('id', i) as string; - if (operation === 'executeResponder') { - const observableId = this.getNodeParameter('id', i); - const responderId = this.getNodeParameter('responder', i) as string; - let body: IDataObject; - let response; - responseData = []; - body = { - responderId, - objectId: observableId, - objectType: 'case_artifact', - }; - response = await theHiveApiRequest.call( - this, - 'POST', - '/connector/cortex/action' as string, - body, - ); - body = { - query: [ - { - '_name': 'listAction', - }, - { - '_name': 'filter', - '_and': [ - { - '_field': 'cortexId', - '_value': response.cortexId, - }, - { - '_field': 'objectId', - '_value': response.objectId, - }, - { - '_field': 'startDate', - '_value': response.startDate, - }, - - ], - }, - ], - }; - qs.name = 'log-actions'; - do { - response = await theHiveApiRequest.call( + responseData = await theHiveApiRequest.call( this, - 'POST', - `/v1/query`, + 'GET', + `/alert/${alertId}`, + {}, + ); + } + + if (operation === 'getAll') { + const credentials = this.getCredentials('theHiveApi') as IDataObject; + + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + + const version = credentials.apiVersion; + + const filters = this.getNodeParameter('filters', i, {}) as INodeParameters; + const queryAttributs: any = prepareOptional(filters); // tslint:disable-line:no-any + const options = this.getNodeParameter('options', i) as IDataObject; + + const _searchQuery: IQueryObject = And(); + + if ('customFieldsUi' in filters) { + const customFields = await prepareCustomFields.call(this, filters) as IDataObject; + const searchQueries = buildCustomFieldSearch(customFields); + (_searchQuery['_and'] as IQueryObject[]).push(...searchQueries); + } + + for (const key of Object.keys(queryAttributs)) { + if (key === 'tags') { + (_searchQuery['_and'] as IQueryObject[]).push( + In(key, queryAttributs[key] as string[]), + ); + } else if (key === 'description' || key === 'title') { + (_searchQuery['_and'] as IQueryObject[]).push( + ContainsString(key, queryAttributs[key] as string), + ); + } else { + (_searchQuery['_and'] as IQueryObject[]).push( + Eq(key, queryAttributs[key] as string), + ); + } + } + + let endpoint; + + let method; + + let body: IDataObject = {}; + + let limit = undefined; + + if (returnAll === false) { + limit = this.getNodeParameter('limit', i) as number; + } + + if (version === 'v1') { + endpoint = '/v1/query'; + + method = 'POST'; + + body = { + 'query': [ + { + '_name': 'listAlert', + }, + { + '_name': 'filter', + '_and': _searchQuery['_and'], + }, + ], + }; + + //@ts-ignore + prepareSortQuery(options.sort, body); + + if (limit !== undefined) { + //@ts-ignore + prepareRangeQuery(`0-${limit}`, body); + } + + qs.name = 'alerts'; + + } else { + method = 'POST'; + + endpoint = '/alert/_search'; + + if (limit !== undefined) { + qs.range = `0-${limit}`; + } + + body.query = _searchQuery; + + Object.assign(qs, prepareOptional(options)); + + } + + responseData = await theHiveApiRequest.call( + this, + method, + endpoint as string, body, qs, ); - } while (response.status === 'Waiting' || response.status === 'InProgress'); - - responseData = response; - } - - if (operation === 'create') { - const caseId = this.getNodeParameter('caseId', i); - - let body: IDataObject = { - dataType: this.getNodeParameter('dataType', i) as string, - message: this.getNodeParameter('message', i) as string, - startDate: Date.parse(this.getNodeParameter('startDate', i) as string), - tlp: this.getNodeParameter('tlp', i) as number, - ioc: this.getNodeParameter('ioc', i) as boolean, - sighted: this.getNodeParameter('sighted', i) as boolean, - status: this.getNodeParameter('status', i) as string, - ...prepareOptional(this.getNodeParameter('options', i, {}) as INodeParameters), - }; - - let options: IDataObject = {}; - - if (body.dataType === 'file') { - const item = items[i]; - - if (item.binary === undefined) { - throw new NodeOperationError(this.getNode(), 'No binary data exists on item!'); - } - - const binaryPropertyName = this.getNodeParameter('binaryProperty', i) as string; - - if (item.binary[binaryPropertyName] === undefined) { - throw new NodeOperationError(this.getNode(), `No binary data property '${binaryPropertyName}' does not exists on item!`); - } - - const binaryData = item.binary[binaryPropertyName] as IBinaryData; - - options = { - formData: { - attachment: { - value: Buffer.from(binaryData.data, BINARY_ENCODING), - options: { - contentType: binaryData.mimeType, - filename: binaryData.fileName, - }, - }, - _json: JSON.stringify(body), - }, - }; - body = {}; - } else { - body.data = this.getNodeParameter('data', i) as string; } - responseData = await theHiveApiRequest.call( - this, - 'POST', - `/case/${caseId}/artifact` as string, - body, - qs, - '', - options, - ); - } + if (operation === 'markAsRead') { + const alertId = this.getNodeParameter('id', i) as string; - if (operation === 'get') { - const observableId = this.getNodeParameter('id', i) as string; + responseData = await theHiveApiRequest.call( + this, + 'POST', + `/alert/${alertId}/markAsRead`, + ); + } - const credentials = this.getCredentials('theHiveApi') as IDataObject; + if (operation === 'markAsUnread') { + const alertId = this.getNodeParameter('id', i) as string; - const version = credentials.apiVersion; + responseData = await theHiveApiRequest.call( + this, + 'POST', + `/alert/${alertId}/markAsUnread`, + ); + } - let endpoint; + if (operation === 'merge') { + const alertId = this.getNodeParameter('id', i) as string; - let method; + const caseId = this.getNodeParameter('caseId', i) as string; - let body: IDataObject = {}; + responseData = await theHiveApiRequest.call( + this, + 'POST', + `/alert/${alertId}/merge/${caseId}`, + {}, + ); + } - if (version === 'v1') { + if (operation === 'promote') { + const alertId = this.getNodeParameter('id', i) as string; - endpoint = '/v1/query'; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - method = 'POST'; + const body: IDataObject = {}; - body = { - 'query': [ - { - '_name': 'getObservable', - 'idOrName': observableId, - }, - ], + Object.assign(body, additionalFields); + + responseData = await theHiveApiRequest.call( + this, + 'POST', + `/alert/${alertId}/createCase`, + body, + ); + } + + if (operation === 'update') { + const alertId = this.getNodeParameter('id', i) as string; + const jsonParameters = this.getNodeParameter('jsonParameters', i) as boolean; + + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + const customFields = await prepareCustomFields.call(this, updateFields, jsonParameters); + + const artifactUi = updateFields.artifactUi as IDataObject; + + delete updateFields.artifactUi; + + const body: IDataObject = { + customFields, }; - qs.name = `get-observable-${observableId}`; + Object.assign(body, updateFields); - } else { + if (artifactUi) { + const artifactValues = (artifactUi as IDataObject).artifactValues as IDataObject[]; - method = 'GET'; + if (artifactValues) { + const artifactData = []; - endpoint = `/case/artifact/${observableId}`; + for (const artifactvalue of artifactValues) { + const element: IDataObject = {}; + + element.message = artifactvalue.message as string; + + element.tags = (artifactvalue.tags as string).split(',') as string[]; + + element.dataType = artifactvalue.dataType as string; + + element.data = artifactvalue.data as string; + + if (artifactvalue.dataType === 'file') { + const item = items[i]; + + if (item.binary === undefined) { + throw new NodeOperationError(this.getNode(), 'No binary data exists on item!'); + } + + const binaryPropertyName = artifactvalue.binaryProperty as string; + + if (item.binary[binaryPropertyName] === undefined) { + throw new NodeOperationError(this.getNode(), `No binary data property '${binaryPropertyName}' does not exists on item!`); + } + + const binaryData = item.binary[binaryPropertyName] as IBinaryData; + + element.data = `${binaryData.fileName};${binaryData.mimeType};${binaryData.data}`; + } + + artifactData.push(element); + } + body.artifacts = artifactData; + } + } + + responseData = await theHiveApiRequest.call( + this, + 'PATCH', + `/alert/${alertId}` as string, + body, + ); } - - responseData = await theHiveApiRequest.call( - this, - method, - endpoint as string, - body, - qs, - ); } - if (operation === 'getAll') { - const credentials = this.getCredentials('theHiveApi') as IDataObject; + if (resource === 'observable') { + if (operation === 'count') { + const countQueryAttributs: any = prepareOptional(this.getNodeParameter('filters', i, {}) as INodeParameters); // tslint:disable-line:no-any - const returnAll = this.getNodeParameter('returnAll', i) as boolean; + const _countSearchQuery: IQueryObject = And(); - const version = credentials.apiVersion; - - const options = this.getNodeParameter('options', i) as IDataObject; - - const caseId = this.getNodeParameter('caseId', i); - - let endpoint; - - let method; - - let body: IDataObject = {}; - - let limit = undefined; - - if (returnAll === false) { - limit = this.getNodeParameter('limit', i) as number; - } - - if (version === 'v1') { - endpoint = '/v1/query'; - - method = 'POST'; - - body = { - 'query': [ - { - '_name': 'getCase', - 'idOrName': caseId, - }, - { - '_name': 'observables', - }, - ], - }; - - //@ts-ignore - prepareSortQuery(options.sort, body); - - if (limit !== undefined) { - //@ts-ignore - prepareRangeQuery(`0-${limit}`, body); + for (const key of Object.keys(countQueryAttributs)) { + if (key === 'dataType' || key === 'tags') { + (_countSearchQuery['_and'] as IQueryObject[]).push( + In(key, countQueryAttributs[key] as string[]), + ); + } else if (key === 'description' || key === 'keywork' || key === 'message') { + (_countSearchQuery['_and'] as IQueryObject[]).push( + ContainsString(key, countQueryAttributs[key] as string), + ); + } else if (key === 'range') { + (_countSearchQuery['_and'] as IQueryObject[]).push( + Between( + 'startDate', + countQueryAttributs['range']['dateRange']['fromDate'], + countQueryAttributs['range']['dateRange']['toDate'], + ), + ); + } else { + (_countSearchQuery['_and'] as IQueryObject[]).push( + Eq(key, countQueryAttributs[key] as string), + ); + } } - qs.name = 'observables'; - - } else { - method = 'POST'; - - endpoint = '/case/artifact/_search'; - - if (limit !== undefined) { - qs.range = `0-${limit}`; - } - - body.query = Parent('case', Id(caseId as string)); - - Object.assign(qs, prepareOptional(options)); - } - - responseData = await theHiveApiRequest.call( - this, - method, - endpoint as string, - body, - qs, - ); - } - - if (operation === 'search') { - const credentials = this.getCredentials('theHiveApi') as IDataObject; - - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - - const version = credentials.apiVersion; - - const queryAttributs: any = prepareOptional(this.getNodeParameter('filters', i, {}) as INodeParameters); // tslint:disable-line:no-any - - const _searchQuery: IQueryObject = And(); - - const options = this.getNodeParameter('options', i) as IDataObject; - - for (const key of Object.keys(queryAttributs)) { - if (key === 'dataType' || key === 'tags') { - (_searchQuery['_and'] as IQueryObject[]).push( - In(key, queryAttributs[key] as string[]), - ); - } else if (key === 'description' || key === 'keywork' || key === 'message') { - (_searchQuery['_and'] as IQueryObject[]).push( - ContainsString(key, queryAttributs[key] as string), - ); - } else if (key === 'range') { - (_searchQuery['_and'] as IQueryObject[]).push( - Between( - 'startDate', - queryAttributs['range']['dateRange']['fromDate'], - queryAttributs['range']['dateRange']['toDate'], - ), - ); - } else { - (_searchQuery['_and'] as IQueryObject[]).push( - Eq(key, queryAttributs[key] as string), - ); - } - } - - let endpoint; - - let method; - - let body: IDataObject = {}; - - let limit = undefined; - - if (returnAll === false) { - limit = this.getNodeParameter('limit', i) as number; - } - - if (version === 'v1') { - endpoint = '/v1/query'; - - method = 'POST'; - - body = { + const body = { 'query': [ { '_name': 'listObservable', }, { '_name': 'filter', - '_and': _searchQuery['_and'], + '_and': _countSearchQuery['_and'], }, ], }; - //@ts-ignore - prepareSortQuery(options.sort, body); - - if (limit !== undefined) { - //@ts-ignore - prepareRangeQuery(`0-${limit}`, body); - } - - qs.name = 'observables'; - - } else { - method = 'POST'; - - endpoint = '/case/artifact/_search'; - - if (limit !== undefined) { - qs.range = `0-${limit}`; - } - - body.query = _searchQuery; - - Object.assign(qs, prepareOptional(options)); - - } - - responseData = await theHiveApiRequest.call( - this, - method, - endpoint as string, - body, - qs, - ); - } - - if (operation === 'update') { - const id = this.getNodeParameter('id', i) as string; - - const body: IDataObject = { - ...prepareOptional(this.getNodeParameter('updateFields', i, {}) as INodeParameters), - }; - - responseData = await theHiveApiRequest.call( - this, - 'PATCH', - `/case/artifact/${id}` as string, - body, - qs, - ); - - responseData = { success: true }; - } - } - - if (resource === 'case') { - if (operation === 'count') { - const filters = this.getNodeParameter('filters', i, {}) as INodeParameters; - const countQueryAttributs: any = prepareOptional(filters); // tslint:disable-line:no-any - - const _countSearchQuery: IQueryObject = And(); - - if ('customFieldsUi' in filters) { - const customFields = await prepareCustomFields.call(this, filters) as IDataObject; - const searchQueries = buildCustomFieldSearch(customFields); - (_countSearchQuery['_and'] as IQueryObject[]).push(...searchQueries); - } - - for (const key of Object.keys(countQueryAttributs)) { - if (key === 'tags') { - (_countSearchQuery['_and'] as IQueryObject[]).push( - In(key, countQueryAttributs[key] as string[]), - ); - } else if (key === 'description' || key === 'summary' || key === 'title') { - (_countSearchQuery['_and'] as IQueryObject[]).push( - ContainsString(key, countQueryAttributs[key] as string), - ); - } else { - (_countSearchQuery['_and'] as IQueryObject[]).push( - Eq(key, countQueryAttributs[key] as string), - ); - } - } - - const body = { - 'query': [ + body['query'].push( { - '_name': 'listCase', + '_name': 'count', }, - { - '_name': 'filter', - '_and': _countSearchQuery['_and'], - }, - ], - }; + ); - body['query'].push( - { - '_name': 'count', - }, - ); + qs.name = 'count-observables'; - qs.name = 'count-cases'; - - - responseData = await theHiveApiRequest.call( - this, - 'POST', - '/v1/query', - body, - qs, - ); - - responseData = { count: responseData }; - } - - if (operation === 'executeResponder') { - const caseId = this.getNodeParameter('id', i); - const responderId = this.getNodeParameter('responder', i) as string; - let body: IDataObject; - let response; - responseData = []; - body = { - responderId, - objectId: caseId, - objectType: 'case', - }; - response = await theHiveApiRequest.call( - this, - 'POST', - '/connector/cortex/action' as string, - body, - ); - body = { - query: [ - { - '_name': 'listAction', - }, - { - '_name': 'filter', - '_and': [ - { - '_field': 'cortexId', - '_value': response.cortexId, - }, - { - '_field': 'objectId', - '_value': response.objectId, - }, - { - '_field': 'startDate', - '_value': response.startDate, - }, - - ], - }, - ], - }; - qs.name = 'log-actions'; - do { - response = await theHiveApiRequest.call( + responseData = await theHiveApiRequest.call( this, 'POST', - `/v1/query`, + '/v1/query', body, qs, ); - } while (response.status === 'Waiting' || response.status === 'InProgress'); - responseData = response; - } + responseData = { count: responseData }; + } - if (operation === 'create') { - const options = this.getNodeParameter('options', i, {}) as INodeParameters; - const jsonParameters = this.getNodeParameter('jsonParameters', i) as boolean; - const customFields = await prepareCustomFields.call(this, options, jsonParameters); + if (operation === 'executeAnalyzer') { + const observableId = this.getNodeParameter('id', i); + const analyzers = (this.getNodeParameter('analyzers', i) as string[]) + .map(analyzer => { + const parts = analyzer.split('::'); + return { + analyzerId: parts[0], + cortexId: parts[1], + }; + }); + let response: any; // tslint:disable-line:no-any + let body: IDataObject; + responseData = []; + for (const analyzer of analyzers) { + body = { + ...analyzer, + artifactId: observableId, + }; + // execute the analyzer + response = await theHiveApiRequest.call( + this, + 'POST', + '/connector/cortex/job' as string, + body, + qs, + ); + const jobId = response.id; + qs.name = 'observable-jobs'; + // query the job result (including the report) + do { + responseData = await theHiveApiRequest.call(this, 'GET', `/connector/cortex/job/${jobId}`, body, qs); + } while (responseData.status === 'Waiting' || responseData.status === 'InProgress'); + } - const body: IDataObject = { - title: this.getNodeParameter('title', i), - description: this.getNodeParameter('description', i), - severity: this.getNodeParameter('severity', i), - startDate: Date.parse(this.getNodeParameter('startDate', i) as string), - owner: this.getNodeParameter('owner', i), - flag: this.getNodeParameter('flag', i), - tlp: this.getNodeParameter('tlp', i), - tags: splitTags(this.getNodeParameter('tags', i) as string), - customFields, - ...prepareOptional(options), - }; - - responseData = await theHiveApiRequest.call( - this, - 'POST', - '/case' as string, - body, - ); - } - - if (operation === 'get') { - const caseId = this.getNodeParameter('id', i) as string; - - const credentials = this.getCredentials('theHiveApi') as IDataObject; - - const version = credentials.apiVersion; - - let endpoint; - - let method; - - let body: IDataObject = {}; - - if (version === 'v1') { - - endpoint = '/v1/query'; - - method = 'POST'; + } + if (operation === 'executeResponder') { + const observableId = this.getNodeParameter('id', i); + const responderId = this.getNodeParameter('responder', i) as string; + let body: IDataObject; + let response; + responseData = []; body = { - 'query': [ - { - '_name': 'getCase', - 'idOrName': caseId, - }, - ], + responderId, + objectId: observableId, + objectType: 'case_artifact', }; - - qs.name = `get-case-${caseId}`; - - } else { - - method = 'GET'; - - endpoint = `/case/${caseId}`; - - } - - responseData = await theHiveApiRequest.call( - this, - method, - endpoint as string, - body, - qs, - ); - } - - if (operation === 'getAll') { - const credentials = this.getCredentials('theHiveApi') as IDataObject; - - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - - const version = credentials.apiVersion; - - const filters = this.getNodeParameter('filters', i, {}) as INodeParameters; - const queryAttributs: any = prepareOptional(filters); // tslint:disable-line:no-any - - const _searchQuery: IQueryObject = And(); - - const options = this.getNodeParameter('options', i) as IDataObject; - - if ('customFieldsUi' in filters) { - const customFields = await prepareCustomFields.call(this, filters) as IDataObject; - const searchQueries = buildCustomFieldSearch(customFields); - (_searchQuery['_and'] as IQueryObject[]).push(...searchQueries); - } - - for (const key of Object.keys(queryAttributs)) { - if (key === 'tags') { - (_searchQuery['_and'] as IQueryObject[]).push( - In(key, queryAttributs[key] as string[]), - ); - } else if (key === 'description' || key === 'summary' || key === 'title') { - (_searchQuery['_and'] as IQueryObject[]).push( - ContainsString(key, queryAttributs[key] as string), - ); - } else { - (_searchQuery['_and'] as IQueryObject[]).push( - Eq(key, queryAttributs[key] as string), - ); - } - } - - let endpoint; - - let method; - - let body: IDataObject = {}; - - let limit = undefined; - - if (returnAll === false) { - limit = this.getNodeParameter('limit', i) as number; - } - - if (version === 'v1') { - endpoint = '/v1/query'; - - method = 'POST'; - - body = { - 'query': [ - { - '_name': 'listCase', - }, - { - '_name': 'filter', - '_and': _searchQuery['_and'], - }, - ], - }; - - //@ts-ignore - prepareSortQuery(options.sort, body); - - if (limit !== undefined) { - //@ts-ignore - prepareRangeQuery(`0-${limit}`, body); - } - - qs.name = 'cases'; - - } else { - method = 'POST'; - - endpoint = '/case/_search'; - - if (limit !== undefined) { - qs.range = `0-${limit}`; - } - - body.query = _searchQuery; - - Object.assign(qs, prepareOptional(options)); - } - - responseData = await theHiveApiRequest.call( - this, - method, - endpoint as string, - body, - qs, - ); - } - - if (operation === 'update') { - const id = this.getNodeParameter('id', i) as string; - const updateFields = this.getNodeParameter('updateFields', i, {}) as INodeParameters; - const jsonParameters = this.getNodeParameter('jsonParameters', i) as boolean; - - const customFields = await prepareCustomFields.call(this, updateFields, jsonParameters); - - const body: IDataObject = { - customFields, - ...prepareOptional(updateFields), - }; - - responseData = await theHiveApiRequest.call( - this, - 'PATCH', - `/case/${id}` as string, - body, - ); - } - } - - if (resource === 'task') { - if (operation === 'count') { - const countQueryAttributs: any = prepareOptional(this.getNodeParameter('filters', i, {}) as INodeParameters); // tslint:disable-line:no-any - - const _countSearchQuery: IQueryObject = And(); - - for (const key of Object.keys(countQueryAttributs)) { - if (key === 'title' || key === 'description') { - (_countSearchQuery['_and'] as IQueryObject[]).push( - ContainsString(key, countQueryAttributs[key] as string), - ); - } else { - (_countSearchQuery['_and'] as IQueryObject[]).push( - Eq(key, countQueryAttributs[key] as string), - ); - } - } - - const body = { - 'query': [ - { - '_name': 'listTask', - }, - { - '_name': 'filter', - '_and': _countSearchQuery['_and'], - }, - ], - }; - - body['query'].push( - { - '_name': 'count', - }, - ); - - qs.name = 'count-tasks'; - - responseData = await theHiveApiRequest.call( - this, - 'POST', - '/v1/query', - body, - qs, - ); - - responseData = { count: responseData }; - } - - if (operation === 'create') { - const caseId = this.getNodeParameter('caseId', i) as string; - - const body: IDataObject = { - title: this.getNodeParameter('title', i) as string, - status: this.getNodeParameter('status', i) as string, - flag: this.getNodeParameter('flag', i), - ...prepareOptional(this.getNodeParameter('options', i, {}) as INodeParameters), - }; - - responseData = await theHiveApiRequest.call( - this, - 'POST', - `/case/${caseId}/task` as string, - body, - ); - } - - if (operation === 'executeResponder') { - const taskId = this.getNodeParameter('id', i); - const responderId = this.getNodeParameter('responder', i) as string; - let body: IDataObject; - let response; - responseData = []; - body = { - responderId, - objectId: taskId, - objectType: 'case_task', - }; - response = await theHiveApiRequest.call( - this, - 'POST', - '/connector/cortex/action' as string, - body, - ); - body = { - query: [ - { - '_name': 'listAction', - }, - { - '_name': 'filter', - '_and': [ - { - '_field': 'cortexId', - '_value': response.cortexId, - }, - { - '_field': 'objectId', - '_value': response.objectId, - }, - { - '_field': 'startDate', - '_value': response.startDate, - }, - - ], - }, - ], - }; - qs.name = 'task-actions'; - do { response = await theHiveApiRequest.call( this, 'POST', - `/v1/query`, + '/connector/cortex/action' as string, body, - qs, ); - } while (response.status === 'Waiting' || response.status === 'InProgress'); - - responseData = response; - } - - if (operation === 'get') { - const taskId = this.getNodeParameter('id', i) as string; - - const credentials = this.getCredentials('theHiveApi') as IDataObject; - - const version = credentials.apiVersion; - - let endpoint; - - let method; - - let body: IDataObject = {}; - - if (version === 'v1') { - endpoint = '/v1/query'; - - method = 'POST'; - body = { - 'query': [ + query: [ { - '_name': 'getTask', - 'idOrName': taskId, - }, - ], - }; - - qs.name = `get-task-${taskId}`; - - } else { - method = 'GET'; - - endpoint = `/case/task/${taskId}`; - - } - - responseData = await theHiveApiRequest.call( - this, - method, - endpoint as string, - body, - qs, - ); - } - - if (operation === 'getAll') { - // get all require a case id (it retursn all tasks for a specific case) - const credentials = this.getCredentials('theHiveApi') as IDataObject; - - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - - const version = credentials.apiVersion; - - const caseId = this.getNodeParameter('caseId', i) as string; - - const options = this.getNodeParameter('options', i) as IDataObject; - - let endpoint; - - let method; - - let body: IDataObject = {}; - - let limit = undefined; - - if (returnAll === false) { - limit = this.getNodeParameter('limit', i) as number; - } - - if (version === 'v1') { - endpoint = '/v1/query'; - - method = 'POST'; - - body = { - 'query': [ - { - '_name': 'getCase', - 'idOrName': caseId, - }, - { - '_name': 'tasks', - }, - ], - }; - - //@ts-ignore - prepareSortQuery(options.sort, body); - - if (limit !== undefined) { - //@ts-ignore - prepareRangeQuery(`0-${limit}`, body); - } - - qs.name = 'case-tasks'; - - } else { - method = 'POST'; - - endpoint = '/case/task/_search'; - - - if (limit !== undefined) { - qs.range = `0-${limit}`; - } - - body.query = And(Parent('case', Id(caseId))); - - Object.assign(qs, prepareOptional(options)); - - } - - responseData = await theHiveApiRequest.call( - this, - method, - endpoint as string, - body, - qs, - ); - } - - if (operation === 'search') { - const credentials = this.getCredentials('theHiveApi') as IDataObject; - - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - - const version = credentials.apiVersion; - - const queryAttributs: any = prepareOptional(this.getNodeParameter('filters', i, {}) as INodeParameters); // tslint:disable-line:no-any - - const _searchQuery: IQueryObject = And(); - - const options = this.getNodeParameter('options', i) as IDataObject; - - for (const key of Object.keys(queryAttributs)) { - if (key === 'title' || key === 'description') { - (_searchQuery['_and'] as IQueryObject[]).push( - ContainsString(key, queryAttributs[key] as string), - ); - } else { - (_searchQuery['_and'] as IQueryObject[]).push( - Eq(key, queryAttributs[key] as string), - ); - } - } - - let endpoint; - - let method; - - let body: IDataObject = {}; - - let limit = undefined; - - if (returnAll === false) { - limit = this.getNodeParameter('limit', i) as number; - } - - if (version === 'v1') { - endpoint = '/v1/query'; - - method = 'POST'; - - body = { - 'query': [ - { - '_name': 'listTask', + '_name': 'listAction', }, { '_name': 'filter', - '_and': _searchQuery['_and'], + '_and': [ + { + '_field': 'cortexId', + '_value': response.cortexId, + }, + { + '_field': 'objectId', + '_value': response.objectId, + }, + { + '_field': 'startDate', + '_value': response.startDate, + }, + + ], }, ], }; + qs.name = 'log-actions'; + do { + response = await theHiveApiRequest.call( + this, + 'POST', + `/v1/query`, + body, + qs, + ); + } while (response.status === 'Waiting' || response.status === 'InProgress'); - //@ts-ignore - prepareSortQuery(options.sort, body); - - if (limit !== undefined) { - //@ts-ignore - prepareRangeQuery(`0-${limit}`, body); - } - - qs.name = 'tasks'; - - } else { - method = 'POST'; - - endpoint = '/case/task/_search'; - - if (limit !== undefined) { - qs.range = `0-${limit}`; - } - - body.query = _searchQuery; - - Object.assign(qs, prepareOptional(options)); - + responseData = response; } - responseData = await theHiveApiRequest.call( - this, - method, - endpoint as string, - body, - qs, - ); - } + if (operation === 'create') { + const caseId = this.getNodeParameter('caseId', i); - if (operation === 'update') { - const id = this.getNodeParameter('id', i) as string; + let body: IDataObject = { + dataType: this.getNodeParameter('dataType', i) as string, + message: this.getNodeParameter('message', i) as string, + startDate: Date.parse(this.getNodeParameter('startDate', i) as string), + tlp: this.getNodeParameter('tlp', i) as number, + ioc: this.getNodeParameter('ioc', i) as boolean, + sighted: this.getNodeParameter('sighted', i) as boolean, + status: this.getNodeParameter('status', i) as string, + ...prepareOptional(this.getNodeParameter('options', i, {}) as INodeParameters), + }; - const body: IDataObject = { - ...prepareOptional(this.getNodeParameter('updateFields', i, {}) as INodeParameters), - }; + let options: IDataObject = {}; - responseData = await theHiveApiRequest.call( - this, - 'PATCH', - `/case/task/${id}` as string, - body, - ); - } - } - - if (resource === 'log') { - if (operation === 'create') { - - const taskId = this.getNodeParameter('taskId', i) as string; - - let body: IDataObject = { - message: this.getNodeParameter('message', i), - startDate: Date.parse(this.getNodeParameter('startDate', i) as string), - status: this.getNodeParameter('status', i), - }; - const optionals = this.getNodeParameter('options', i) as IDataObject; - - let options: IDataObject = {}; - - if (optionals.attachementUi) { - const attachmentValues = (optionals.attachementUi as IDataObject).attachmentValues as IDataObject; - - if (attachmentValues) { + if (body.dataType === 'file') { const item = items[i]; if (item.binary === undefined) { throw new NodeOperationError(this.getNode(), 'No binary data exists on item!'); } - const binaryPropertyName = attachmentValues.binaryProperty as string; + const binaryPropertyName = this.getNodeParameter('binaryProperty', i) as string; if (item.binary[binaryPropertyName] === undefined) { throw new NodeOperationError(this.getNode(), `No binary data property '${binaryPropertyName}' does not exists on item!`); @@ -1897,201 +942,1168 @@ export class TheHive implements INodeType { _json: JSON.stringify(body), }, }; - body = {}; + } else { + body.data = this.getNodeParameter('data', i) as string; } - } - responseData = await theHiveApiRequest.call( - this, - 'POST', - `/case/task/${taskId}/log` as string, - body, - qs, - '', - options, - ); - } - - if (operation === 'executeResponder') { - const logId = this.getNodeParameter('id', i); - const responderId = this.getNodeParameter('responder', i) as string; - let body: IDataObject; - let response; - responseData = []; - body = { - responderId, - objectId: logId, - objectType: 'case_task_log', - }; - response = await theHiveApiRequest.call( - this, - 'POST', - '/connector/cortex/action' as string, - body, - ); - body = { - query: [ - { - '_name': 'listAction', - }, - { - '_name': 'filter', - '_and': [ - { - '_field': 'cortexId', - '_value': response.cortexId, - }, - { - '_field': 'objectId', - '_value': response.objectId, - }, - { - '_field': 'startDate', - '_value': response.startDate, - }, - - ], - }, - ], - }; - qs.name = 'log-actions'; - do { - response = await theHiveApiRequest.call( + responseData = await theHiveApiRequest.call( this, 'POST', - `/v1/query`, + `/case/${caseId}/artifact` as string, + body, + qs, + '', + options, + ); + } + + if (operation === 'get') { + const observableId = this.getNodeParameter('id', i) as string; + + const credentials = this.getCredentials('theHiveApi') as IDataObject; + + const version = credentials.apiVersion; + + let endpoint; + + let method; + + let body: IDataObject = {}; + + if (version === 'v1') { + + endpoint = '/v1/query'; + + method = 'POST'; + + body = { + 'query': [ + { + '_name': 'getObservable', + 'idOrName': observableId, + }, + ], + }; + + qs.name = `get-observable-${observableId}`; + + } else { + + method = 'GET'; + + endpoint = `/case/artifact/${observableId}`; + + } + + responseData = await theHiveApiRequest.call( + this, + method, + endpoint as string, body, qs, ); - } while (response.status === 'Waiting' || response.status === 'InProgress'); + } - responseData = response; + if (operation === 'getAll') { + const credentials = this.getCredentials('theHiveApi') as IDataObject; + + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + + const version = credentials.apiVersion; + + const options = this.getNodeParameter('options', i) as IDataObject; + + const caseId = this.getNodeParameter('caseId', i); + + let endpoint; + + let method; + + let body: IDataObject = {}; + + let limit = undefined; + + if (returnAll === false) { + limit = this.getNodeParameter('limit', i) as number; + } + + if (version === 'v1') { + endpoint = '/v1/query'; + + method = 'POST'; + + body = { + 'query': [ + { + '_name': 'getCase', + 'idOrName': caseId, + }, + { + '_name': 'observables', + }, + ], + }; + + //@ts-ignore + prepareSortQuery(options.sort, body); + + if (limit !== undefined) { + //@ts-ignore + prepareRangeQuery(`0-${limit}`, body); + } + + qs.name = 'observables'; + + } else { + method = 'POST'; + + endpoint = '/case/artifact/_search'; + + if (limit !== undefined) { + qs.range = `0-${limit}`; + } + + body.query = Parent('case', Id(caseId as string)); + + Object.assign(qs, prepareOptional(options)); + } + + responseData = await theHiveApiRequest.call( + this, + method, + endpoint as string, + body, + qs, + ); + } + + if (operation === 'search') { + const credentials = this.getCredentials('theHiveApi') as IDataObject; + + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + + const version = credentials.apiVersion; + + const queryAttributs: any = prepareOptional(this.getNodeParameter('filters', i, {}) as INodeParameters); // tslint:disable-line:no-any + + const _searchQuery: IQueryObject = And(); + + const options = this.getNodeParameter('options', i) as IDataObject; + + for (const key of Object.keys(queryAttributs)) { + if (key === 'dataType' || key === 'tags') { + (_searchQuery['_and'] as IQueryObject[]).push( + In(key, queryAttributs[key] as string[]), + ); + } else if (key === 'description' || key === 'keywork' || key === 'message') { + (_searchQuery['_and'] as IQueryObject[]).push( + ContainsString(key, queryAttributs[key] as string), + ); + } else if (key === 'range') { + (_searchQuery['_and'] as IQueryObject[]).push( + Between( + 'startDate', + queryAttributs['range']['dateRange']['fromDate'], + queryAttributs['range']['dateRange']['toDate'], + ), + ); + } else { + (_searchQuery['_and'] as IQueryObject[]).push( + Eq(key, queryAttributs[key] as string), + ); + } + } + + let endpoint; + + let method; + + let body: IDataObject = {}; + + let limit = undefined; + + if (returnAll === false) { + limit = this.getNodeParameter('limit', i) as number; + } + + if (version === 'v1') { + endpoint = '/v1/query'; + + method = 'POST'; + + body = { + 'query': [ + { + '_name': 'listObservable', + }, + { + '_name': 'filter', + '_and': _searchQuery['_and'], + }, + ], + }; + + //@ts-ignore + prepareSortQuery(options.sort, body); + + if (limit !== undefined) { + //@ts-ignore + prepareRangeQuery(`0-${limit}`, body); + } + + qs.name = 'observables'; + + } else { + method = 'POST'; + + endpoint = '/case/artifact/_search'; + + if (limit !== undefined) { + qs.range = `0-${limit}`; + } + + body.query = _searchQuery; + + Object.assign(qs, prepareOptional(options)); + + } + + responseData = await theHiveApiRequest.call( + this, + method, + endpoint as string, + body, + qs, + ); + } + + if (operation === 'update') { + const id = this.getNodeParameter('id', i) as string; + + const body: IDataObject = { + ...prepareOptional(this.getNodeParameter('updateFields', i, {}) as INodeParameters), + }; + + responseData = await theHiveApiRequest.call( + this, + 'PATCH', + `/case/artifact/${id}` as string, + body, + qs, + ); + + responseData = { success: true }; + } } - if (operation === 'get') { - const logId = this.getNodeParameter('id', i) as string; + if (resource === 'case') { + if (operation === 'count') { + const filters = this.getNodeParameter('filters', i, {}) as INodeParameters; + const countQueryAttributs: any = prepareOptional(filters); // tslint:disable-line:no-any - const credentials = this.getCredentials('theHiveApi') as IDataObject; + const _countSearchQuery: IQueryObject = And(); - const version = credentials.apiVersion; + if ('customFieldsUi' in filters) { + const customFields = await prepareCustomFields.call(this, filters) as IDataObject; + const searchQueries = buildCustomFieldSearch(customFields); + (_countSearchQuery['_and'] as IQueryObject[]).push(...searchQueries); + } - let endpoint; + for (const key of Object.keys(countQueryAttributs)) { + if (key === 'tags') { + (_countSearchQuery['_and'] as IQueryObject[]).push( + In(key, countQueryAttributs[key] as string[]), + ); + } else if (key === 'description' || key === 'summary' || key === 'title') { + (_countSearchQuery['_and'] as IQueryObject[]).push( + ContainsString(key, countQueryAttributs[key] as string), + ); + } else { + (_countSearchQuery['_and'] as IQueryObject[]).push( + Eq(key, countQueryAttributs[key] as string), + ); + } + } - let method; + const body = { + 'query': [ + { + '_name': 'listCase', + }, + { + '_name': 'filter', + '_and': _countSearchQuery['_and'], + }, + ], + }; - let body: IDataObject = {}; + body['query'].push( + { + '_name': 'count', + }, + ); - if (version === 'v1') { + qs.name = 'count-cases'; - endpoint = '/v1/query'; - method = 'POST'; + responseData = await theHiveApiRequest.call( + this, + 'POST', + '/v1/query', + body, + qs, + ); + responseData = { count: responseData }; + } + + if (operation === 'executeResponder') { + const caseId = this.getNodeParameter('id', i); + const responderId = this.getNodeParameter('responder', i) as string; + let body: IDataObject; + let response; + responseData = []; + body = { + responderId, + objectId: caseId, + objectType: 'case', + }; + response = await theHiveApiRequest.call( + this, + 'POST', + '/connector/cortex/action' as string, + body, + ); body = { query: [ { - _name: 'getLog', - idOrName: logId, + '_name': 'listAction', + }, + { + '_name': 'filter', + '_and': [ + { + '_field': 'cortexId', + '_value': response.cortexId, + }, + { + '_field': 'objectId', + '_value': response.objectId, + }, + { + '_field': 'startDate', + '_value': response.startDate, + }, + + ], }, ], }; + qs.name = 'log-actions'; + do { + response = await theHiveApiRequest.call( + this, + 'POST', + `/v1/query`, + body, + qs, + ); + } while (response.status === 'Waiting' || response.status === 'InProgress'); - qs.name = `get-log-${logId}`; - } else { - method = 'POST'; - - endpoint = '/case/task/log/_search'; - - body.query = { _id: logId }; + responseData = response; } - responseData = await theHiveApiRequest.call( - this, - method, - endpoint as string, - body, - qs, - ); + if (operation === 'create') { + const options = this.getNodeParameter('options', i, {}) as INodeParameters; + const jsonParameters = this.getNodeParameter('jsonParameters', i) as boolean; + const customFields = await prepareCustomFields.call(this, options, jsonParameters); + + const body: IDataObject = { + title: this.getNodeParameter('title', i), + description: this.getNodeParameter('description', i), + severity: this.getNodeParameter('severity', i), + startDate: Date.parse(this.getNodeParameter('startDate', i) as string), + owner: this.getNodeParameter('owner', i), + flag: this.getNodeParameter('flag', i), + tlp: this.getNodeParameter('tlp', i), + tags: splitTags(this.getNodeParameter('tags', i) as string), + customFields, + ...prepareOptional(options), + }; + + responseData = await theHiveApiRequest.call( + this, + 'POST', + '/case' as string, + body, + ); + } + + if (operation === 'get') { + const caseId = this.getNodeParameter('id', i) as string; + + const credentials = this.getCredentials('theHiveApi') as IDataObject; + + const version = credentials.apiVersion; + + let endpoint; + + let method; + + let body: IDataObject = {}; + + if (version === 'v1') { + + endpoint = '/v1/query'; + + method = 'POST'; + + body = { + 'query': [ + { + '_name': 'getCase', + 'idOrName': caseId, + }, + ], + }; + + qs.name = `get-case-${caseId}`; + + } else { + + method = 'GET'; + + endpoint = `/case/${caseId}`; + + } + + responseData = await theHiveApiRequest.call( + this, + method, + endpoint as string, + body, + qs, + ); + } + + if (operation === 'getAll') { + const credentials = this.getCredentials('theHiveApi') as IDataObject; + + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + + const version = credentials.apiVersion; + + const filters = this.getNodeParameter('filters', i, {}) as INodeParameters; + const queryAttributs: any = prepareOptional(filters); // tslint:disable-line:no-any + + const _searchQuery: IQueryObject = And(); + + const options = this.getNodeParameter('options', i) as IDataObject; + + if ('customFieldsUi' in filters) { + const customFields = await prepareCustomFields.call(this, filters) as IDataObject; + const searchQueries = buildCustomFieldSearch(customFields); + (_searchQuery['_and'] as IQueryObject[]).push(...searchQueries); + } + + for (const key of Object.keys(queryAttributs)) { + if (key === 'tags') { + (_searchQuery['_and'] as IQueryObject[]).push( + In(key, queryAttributs[key] as string[]), + ); + } else if (key === 'description' || key === 'summary' || key === 'title') { + (_searchQuery['_and'] as IQueryObject[]).push( + ContainsString(key, queryAttributs[key] as string), + ); + } else { + (_searchQuery['_and'] as IQueryObject[]).push( + Eq(key, queryAttributs[key] as string), + ); + } + } + + let endpoint; + + let method; + + let body: IDataObject = {}; + + let limit = undefined; + + if (returnAll === false) { + limit = this.getNodeParameter('limit', i) as number; + } + + if (version === 'v1') { + endpoint = '/v1/query'; + + method = 'POST'; + + body = { + 'query': [ + { + '_name': 'listCase', + }, + { + '_name': 'filter', + '_and': _searchQuery['_and'], + }, + ], + }; + + //@ts-ignore + prepareSortQuery(options.sort, body); + + if (limit !== undefined) { + //@ts-ignore + prepareRangeQuery(`0-${limit}`, body); + } + + qs.name = 'cases'; + + } else { + method = 'POST'; + + endpoint = '/case/_search'; + + if (limit !== undefined) { + qs.range = `0-${limit}`; + } + + body.query = _searchQuery; + + Object.assign(qs, prepareOptional(options)); + } + + responseData = await theHiveApiRequest.call( + this, + method, + endpoint as string, + body, + qs, + ); + } + + if (operation === 'update') { + const id = this.getNodeParameter('id', i) as string; + const updateFields = this.getNodeParameter('updateFields', i, {}) as INodeParameters; + const jsonParameters = this.getNodeParameter('jsonParameters', i) as boolean; + + const customFields = await prepareCustomFields.call(this, updateFields, jsonParameters); + + const body: IDataObject = { + customFields, + ...prepareOptional(updateFields), + }; + + responseData = await theHiveApiRequest.call( + this, + 'PATCH', + `/case/${id}` as string, + body, + ); + } } - if (operation === 'getAll') { - const credentials = this.getCredentials('theHiveApi') as IDataObject; + if (resource === 'task') { + if (operation === 'count') { + const countQueryAttributs: any = prepareOptional(this.getNodeParameter('filters', i, {}) as INodeParameters); // tslint:disable-line:no-any - const returnAll = this.getNodeParameter('returnAll', i) as boolean; + const _countSearchQuery: IQueryObject = And(); - const version = credentials.apiVersion; + for (const key of Object.keys(countQueryAttributs)) { + if (key === 'title' || key === 'description') { + (_countSearchQuery['_and'] as IQueryObject[]).push( + ContainsString(key, countQueryAttributs[key] as string), + ); + } else { + (_countSearchQuery['_and'] as IQueryObject[]).push( + Eq(key, countQueryAttributs[key] as string), + ); + } + } - const taskId = this.getNodeParameter('taskId', i) as string; - - let endpoint; - - let method; - - let body: IDataObject = {}; - - let limit = undefined; - - if (returnAll === false) { - limit = this.getNodeParameter('limit', i) as number; - } - - if (version === 'v1') { - endpoint = '/v1/query'; - - method = 'POST'; - - body = { + const body = { 'query': [ { - '_name': 'getTask', - 'idOrName': taskId, + '_name': 'listTask', }, { - '_name': 'logs', + '_name': 'filter', + '_and': _countSearchQuery['_and'], }, ], }; - if (limit !== undefined) { - //@ts-ignore - prepareRangeQuery(`0-${limit}`, body); - } + body['query'].push( + { + '_name': 'count', + }, + ); - qs.name = 'case-task-logs'; + qs.name = 'count-tasks'; - } else { - method = 'POST'; + responseData = await theHiveApiRequest.call( + this, + 'POST', + '/v1/query', + body, + qs, + ); - endpoint = '/case/task/log/_search'; - - if (limit !== undefined) { - qs.range = `0-${limit}`; - } - - body.query = And(Parent( - 'task', - Id(taskId), - )); + responseData = { count: responseData }; } - responseData = await theHiveApiRequest.call( - this, - method, - endpoint as string, - body, - qs, - ); + if (operation === 'create') { + const caseId = this.getNodeParameter('caseId', i) as string; + + const body: IDataObject = { + title: this.getNodeParameter('title', i) as string, + status: this.getNodeParameter('status', i) as string, + flag: this.getNodeParameter('flag', i), + ...prepareOptional(this.getNodeParameter('options', i, {}) as INodeParameters), + }; + + responseData = await theHiveApiRequest.call( + this, + 'POST', + `/case/${caseId}/task` as string, + body, + ); + } + + if (operation === 'executeResponder') { + const taskId = this.getNodeParameter('id', i); + const responderId = this.getNodeParameter('responder', i) as string; + let body: IDataObject; + let response; + responseData = []; + body = { + responderId, + objectId: taskId, + objectType: 'case_task', + }; + response = await theHiveApiRequest.call( + this, + 'POST', + '/connector/cortex/action' as string, + body, + ); + body = { + query: [ + { + '_name': 'listAction', + }, + { + '_name': 'filter', + '_and': [ + { + '_field': 'cortexId', + '_value': response.cortexId, + }, + { + '_field': 'objectId', + '_value': response.objectId, + }, + { + '_field': 'startDate', + '_value': response.startDate, + }, + + ], + }, + ], + }; + qs.name = 'task-actions'; + do { + response = await theHiveApiRequest.call( + this, + 'POST', + `/v1/query`, + body, + qs, + ); + } while (response.status === 'Waiting' || response.status === 'InProgress'); + + responseData = response; + } + + if (operation === 'get') { + const taskId = this.getNodeParameter('id', i) as string; + + const credentials = this.getCredentials('theHiveApi') as IDataObject; + + const version = credentials.apiVersion; + + let endpoint; + + let method; + + let body: IDataObject = {}; + + if (version === 'v1') { + endpoint = '/v1/query'; + + method = 'POST'; + + body = { + 'query': [ + { + '_name': 'getTask', + 'idOrName': taskId, + }, + ], + }; + + qs.name = `get-task-${taskId}`; + + } else { + method = 'GET'; + + endpoint = `/case/task/${taskId}`; + + } + + responseData = await theHiveApiRequest.call( + this, + method, + endpoint as string, + body, + qs, + ); + } + + if (operation === 'getAll') { + // get all require a case id (it retursn all tasks for a specific case) + const credentials = this.getCredentials('theHiveApi') as IDataObject; + + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + + const version = credentials.apiVersion; + + const caseId = this.getNodeParameter('caseId', i) as string; + + const options = this.getNodeParameter('options', i) as IDataObject; + + let endpoint; + + let method; + + let body: IDataObject = {}; + + let limit = undefined; + + if (returnAll === false) { + limit = this.getNodeParameter('limit', i) as number; + } + + if (version === 'v1') { + endpoint = '/v1/query'; + + method = 'POST'; + + body = { + 'query': [ + { + '_name': 'getCase', + 'idOrName': caseId, + }, + { + '_name': 'tasks', + }, + ], + }; + + //@ts-ignore + prepareSortQuery(options.sort, body); + + if (limit !== undefined) { + //@ts-ignore + prepareRangeQuery(`0-${limit}`, body); + } + + qs.name = 'case-tasks'; + + } else { + method = 'POST'; + + endpoint = '/case/task/_search'; + + + if (limit !== undefined) { + qs.range = `0-${limit}`; + } + + body.query = And(Parent('case', Id(caseId))); + + Object.assign(qs, prepareOptional(options)); + + } + + responseData = await theHiveApiRequest.call( + this, + method, + endpoint as string, + body, + qs, + ); + } + + if (operation === 'search') { + const credentials = this.getCredentials('theHiveApi') as IDataObject; + + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + + const version = credentials.apiVersion; + + const queryAttributs: any = prepareOptional(this.getNodeParameter('filters', i, {}) as INodeParameters); // tslint:disable-line:no-any + + const _searchQuery: IQueryObject = And(); + + const options = this.getNodeParameter('options', i) as IDataObject; + + for (const key of Object.keys(queryAttributs)) { + if (key === 'title' || key === 'description') { + (_searchQuery['_and'] as IQueryObject[]).push( + ContainsString(key, queryAttributs[key] as string), + ); + } else { + (_searchQuery['_and'] as IQueryObject[]).push( + Eq(key, queryAttributs[key] as string), + ); + } + } + + let endpoint; + + let method; + + let body: IDataObject = {}; + + let limit = undefined; + + if (returnAll === false) { + limit = this.getNodeParameter('limit', i) as number; + } + + if (version === 'v1') { + endpoint = '/v1/query'; + + method = 'POST'; + + body = { + 'query': [ + { + '_name': 'listTask', + }, + { + '_name': 'filter', + '_and': _searchQuery['_and'], + }, + ], + }; + + //@ts-ignore + prepareSortQuery(options.sort, body); + + if (limit !== undefined) { + //@ts-ignore + prepareRangeQuery(`0-${limit}`, body); + } + + qs.name = 'tasks'; + + } else { + method = 'POST'; + + endpoint = '/case/task/_search'; + + if (limit !== undefined) { + qs.range = `0-${limit}`; + } + + body.query = _searchQuery; + + Object.assign(qs, prepareOptional(options)); + + } + + responseData = await theHiveApiRequest.call( + this, + method, + endpoint as string, + body, + qs, + ); + } + + if (operation === 'update') { + const id = this.getNodeParameter('id', i) as string; + + const body: IDataObject = { + ...prepareOptional(this.getNodeParameter('updateFields', i, {}) as INodeParameters), + }; + + responseData = await theHiveApiRequest.call( + this, + 'PATCH', + `/case/task/${id}` as string, + body, + ); + } } - } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); + if (resource === 'log') { + if (operation === 'create') { - } else if (responseData !== undefined) { - returnData.push(responseData as IDataObject); + const taskId = this.getNodeParameter('taskId', i) as string; + + let body: IDataObject = { + message: this.getNodeParameter('message', i), + startDate: Date.parse(this.getNodeParameter('startDate', i) as string), + status: this.getNodeParameter('status', i), + }; + const optionals = this.getNodeParameter('options', i) as IDataObject; + + let options: IDataObject = {}; + + if (optionals.attachementUi) { + const attachmentValues = (optionals.attachementUi as IDataObject).attachmentValues as IDataObject; + + if (attachmentValues) { + const item = items[i]; + + if (item.binary === undefined) { + throw new NodeOperationError(this.getNode(), 'No binary data exists on item!'); + } + + const binaryPropertyName = attachmentValues.binaryProperty as string; + + if (item.binary[binaryPropertyName] === undefined) { + throw new NodeOperationError(this.getNode(), `No binary data property '${binaryPropertyName}' does not exists on item!`); + } + + const binaryData = item.binary[binaryPropertyName] as IBinaryData; + + options = { + formData: { + attachment: { + value: Buffer.from(binaryData.data, BINARY_ENCODING), + options: { + contentType: binaryData.mimeType, + filename: binaryData.fileName, + }, + }, + _json: JSON.stringify(body), + }, + }; + + body = {}; + } + } + + responseData = await theHiveApiRequest.call( + this, + 'POST', + `/case/task/${taskId}/log` as string, + body, + qs, + '', + options, + ); + } + + if (operation === 'executeResponder') { + const logId = this.getNodeParameter('id', i); + const responderId = this.getNodeParameter('responder', i) as string; + let body: IDataObject; + let response; + responseData = []; + body = { + responderId, + objectId: logId, + objectType: 'case_task_log', + }; + response = await theHiveApiRequest.call( + this, + 'POST', + '/connector/cortex/action' as string, + body, + ); + body = { + query: [ + { + '_name': 'listAction', + }, + { + '_name': 'filter', + '_and': [ + { + '_field': 'cortexId', + '_value': response.cortexId, + }, + { + '_field': 'objectId', + '_value': response.objectId, + }, + { + '_field': 'startDate', + '_value': response.startDate, + }, + + ], + }, + ], + }; + qs.name = 'log-actions'; + do { + response = await theHiveApiRequest.call( + this, + 'POST', + `/v1/query`, + body, + qs, + ); + } while (response.status === 'Waiting' || response.status === 'InProgress'); + + responseData = response; + } + + if (operation === 'get') { + const logId = this.getNodeParameter('id', i) as string; + + const credentials = this.getCredentials('theHiveApi') as IDataObject; + + const version = credentials.apiVersion; + + let endpoint; + + let method; + + let body: IDataObject = {}; + + if (version === 'v1') { + + endpoint = '/v1/query'; + + method = 'POST'; + + body = { + query: [ + { + _name: 'getLog', + idOrName: logId, + }, + ], + }; + + qs.name = `get-log-${logId}`; + } else { + method = 'POST'; + + endpoint = '/case/task/log/_search'; + + body.query = { _id: logId }; + } + + responseData = await theHiveApiRequest.call( + this, + method, + endpoint as string, + body, + qs, + ); + } + + if (operation === 'getAll') { + const credentials = this.getCredentials('theHiveApi') as IDataObject; + + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + + const version = credentials.apiVersion; + + const taskId = this.getNodeParameter('taskId', i) as string; + + let endpoint; + + let method; + + let body: IDataObject = {}; + + let limit = undefined; + + if (returnAll === false) { + limit = this.getNodeParameter('limit', i) as number; + } + + if (version === 'v1') { + endpoint = '/v1/query'; + + method = 'POST'; + + body = { + 'query': [ + { + '_name': 'getTask', + 'idOrName': taskId, + }, + { + '_name': 'logs', + }, + ], + }; + + if (limit !== undefined) { + //@ts-ignore + prepareRangeQuery(`0-${limit}`, body); + } + + qs.name = 'case-task-logs'; + + } else { + method = 'POST'; + + endpoint = '/case/task/log/_search'; + + if (limit !== undefined) { + qs.range = `0-${limit}`; + } + + body.query = And(Parent( + 'task', + Id(taskId), + )); + } + + responseData = await theHiveApiRequest.call( + this, + method, + endpoint as string, + body, + qs, + ); + } + } + + if (Array.isArray(responseData)) { + returnData.push.apply(returnData, responseData as IDataObject[]); + + } else if (responseData !== undefined) { + returnData.push(responseData as IDataObject); + } + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } } return [this.helpers.returnJsonArray(returnData)]; } } + + + + diff --git a/packages/nodes-base/nodes/Todoist/Todoist.node.ts b/packages/nodes-base/nodes/Todoist/Todoist.node.ts index 39732d0d50..4aeca39d81 100644 --- a/packages/nodes-base/nodes/Todoist/Todoist.node.ts +++ b/packages/nodes-base/nodes/Todoist/Todoist.node.ts @@ -477,106 +477,114 @@ export class Todoist implements INodeType { for (let i = 0; i < length; i++) { - if (resource === 'task') { - if (operation === 'create') { - //https://developer.todoist.com/rest/v1/#create-a-new-task - const content = this.getNodeParameter('content', i) as string; - const projectId = this.getNodeParameter('project', i) as number; - const labels = this.getNodeParameter('labels', i) as number[]; - const options = this.getNodeParameter('options', i) as IDataObject; - - const body: IBodyCreateTask = { - content, - project_id: projectId, - priority: (options.priority!) ? parseInt(options.priority as string, 10) : 1, - }; - - if (options.description) { - body.description = options.description as string; + try { + if (resource === 'task') { + if (operation === 'create') { + //https://developer.todoist.com/rest/v1/#create-a-new-task + const content = this.getNodeParameter('content', i) as string; + const projectId = this.getNodeParameter('project', i) as number; + const labels = this.getNodeParameter('labels', i) as number[]; + const options = this.getNodeParameter('options', i) as IDataObject; + + const body: IBodyCreateTask = { + content, + project_id: projectId, + priority: (options.priority!) ? parseInt(options.priority as string, 10) : 1, + }; + + if (options.description) { + body.description = options.description as string; + } + + if (options.dueDateTime) { + body.due_datetime = options.dueDateTime as string; + } + + if (options.dueString) { + body.due_string = options.dueString as string; + } + + if (labels !== undefined && labels.length !== 0) { + body.label_ids = labels; + } + + if (options.section) { + body.section_id = options.section as number; + } + + responseData = await todoistApiRequest.call(this, 'POST', '/tasks', body); } + if (operation === 'close') { + //https://developer.todoist.com/rest/v1/#close-a-task + const id = this.getNodeParameter('taskId', i) as string; + + responseData = await todoistApiRequest.call(this, 'POST', `/tasks/${id}/close`); + + responseData = { success: true }; - if (options.dueDateTime) { - body.due_datetime = options.dueDateTime as string; } + if (operation === 'delete') { + //https://developer.todoist.com/rest/v1/#delete-a-task + const id = this.getNodeParameter('taskId', i) as string; + + responseData = await todoistApiRequest.call(this, 'DELETE', `/tasks/${id}`); + + responseData = { success: true }; - if (options.dueString) { - body.due_string = options.dueString as string; } + if (operation === 'get') { + //https://developer.todoist.com/rest/v1/#get-an-active-task + const id = this.getNodeParameter('taskId', i) as string; - if (labels !== undefined && labels.length !== 0) { - body.label_ids = labels; + responseData = await todoistApiRequest.call(this, 'GET', `/tasks/${id}`); } + if (operation === 'getAll') { + //https://developer.todoist.com/rest/v1/#get-active-tasks + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + const filters = this.getNodeParameter('filters', i) as IDataObject; + if (filters.projectId) { + qs.project_id = filters.projectId as string; + } + if (filters.labelId) { + qs.label_id = filters.labelId as string; + } + if (filters.filter) { + qs.filter = filters.filter as string; + } + if (filters.lang) { + qs.lang = filters.lang as string; + } + if (filters.ids) { + qs.ids = filters.ids as string; + } - if (options.section) { - body.section_id = options.section as number; + responseData = await todoistApiRequest.call(this, 'GET', '/tasks', {}, qs); + + if (!returnAll) { + const limit = this.getNodeParameter('limit', i) as number; + responseData = responseData.splice(0, limit); + } } + if (operation === 'reopen') { + //https://developer.todoist.com/rest/v1/#get-an-active-task + const id = this.getNodeParameter('taskId', i) as string; - responseData = await todoistApiRequest.call(this, 'POST', '/tasks', body); - } - if (operation === 'close') { - //https://developer.todoist.com/rest/v1/#close-a-task - const id = this.getNodeParameter('taskId', i) as string; + responseData = await todoistApiRequest.call(this, 'POST', `/tasks/${id}/reopen`); - responseData = await todoistApiRequest.call(this, 'POST', `/tasks/${id}/close`); - - responseData = { success: true }; - - } - if (operation === 'delete') { - //https://developer.todoist.com/rest/v1/#delete-a-task - const id = this.getNodeParameter('taskId', i) as string; - - responseData = await todoistApiRequest.call(this, 'DELETE', `/tasks/${id}`); - - responseData = { success: true }; - - } - if (operation === 'get') { - //https://developer.todoist.com/rest/v1/#get-an-active-task - const id = this.getNodeParameter('taskId', i) as string; - - responseData = await todoistApiRequest.call(this, 'GET', `/tasks/${id}`); - } - if (operation === 'getAll') { - //https://developer.todoist.com/rest/v1/#get-active-tasks - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - const filters = this.getNodeParameter('filters', i) as IDataObject; - if (filters.projectId) { - qs.project_id = filters.projectId as string; - } - if (filters.labelId) { - qs.label_id = filters.labelId as string; - } - if (filters.filter) { - qs.filter = filters.filter as string; - } - if (filters.lang) { - qs.lang = filters.lang as string; - } - if (filters.ids) { - qs.ids = filters.ids as string; - } - - responseData = await todoistApiRequest.call(this, 'GET', '/tasks', {}, qs); - - if (!returnAll) { - const limit = this.getNodeParameter('limit', i) as number; - responseData = responseData.splice(0, limit); + responseData = { success: true }; } } - if (operation === 'reopen') { - //https://developer.todoist.com/rest/v1/#get-an-active-task - const id = this.getNodeParameter('taskId', i) as string; - - responseData = await todoistApiRequest.call(this, 'POST', `/tasks/${id}/reopen`); - - responseData = { success: true }; + if (Array.isArray(responseData)) { + returnData.push.apply(returnData, responseData as IDataObject[]); + } else { + returnData.push(responseData as IDataObject); } - } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else { - returnData.push(responseData as IDataObject); + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } } diff --git a/packages/nodes-base/nodes/TravisCi/TravisCi.node.ts b/packages/nodes-base/nodes/TravisCi/TravisCi.node.ts index 7be473da6e..91a07ff38e 100644 --- a/packages/nodes-base/nodes/TravisCi/TravisCi.node.ts +++ b/packages/nodes-base/nodes/TravisCi/TravisCi.node.ts @@ -69,81 +69,89 @@ export class TravisCi implements INodeType { const operation = this.getNodeParameter('operation', 0) as string; for (let i = 0; i < length; i++) { - if (resource === 'build') { - //https://developer.travis-ci.com/resource/build#find - if (operation === 'get') { - const buildId = this.getNodeParameter('buildId', i) as string; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + try { + if (resource === 'build') { + //https://developer.travis-ci.com/resource/build#find + if (operation === 'get') { + const buildId = this.getNodeParameter('buildId', i) as string; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - if (additionalFields.include) { - qs.include = additionalFields.include as string; + if (additionalFields.include) { + qs.include = additionalFields.include as string; + } + + responseData = await travisciApiRequest.call(this, 'GET', `/build/${buildId}`, {}, qs); } + //https://developer.travis-ci.com/resource/builds#for_current_user + if (operation === 'getAll') { + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const returnAll = this.getNodeParameter('returnAll', i) as boolean; - responseData = await travisciApiRequest.call(this, 'GET', `/build/${buildId}`, {}, qs); - } - //https://developer.travis-ci.com/resource/builds#for_current_user - if (operation === 'getAll') { - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const returnAll = this.getNodeParameter('returnAll', i) as boolean; + if (additionalFields.sortBy) { + qs.sort_by = additionalFields.sortBy; + } - if (additionalFields.sortBy) { - qs.sort_by = additionalFields.sortBy; + if (additionalFields.sortBy && additionalFields.order) { + qs.sort_by = `${additionalFields.sortBy}:${additionalFields.order}`; + } + + if (additionalFields.include) { + qs.include = additionalFields.include; + } + + if (returnAll === true) { + responseData = await travisciApiRequestAllItems.call(this, 'builds', 'GET', '/builds', {}, qs); + + } else { + qs.limit = this.getNodeParameter('limit', i) as number; + responseData = await travisciApiRequest.call(this, 'GET', '/builds', {}, qs); + responseData = responseData.builds; + } } - - if (additionalFields.sortBy && additionalFields.order) { - qs.sort_by = `${additionalFields.sortBy}:${additionalFields.order}`; + //https://developer.travis-ci.com/resource/build#cancel + if (operation === 'cancel') { + const buildId = this.getNodeParameter('buildId', i) as string; + responseData = await travisciApiRequest.call(this, 'POST', `/build/${buildId}/cancel`, {}, qs); } - - if (additionalFields.include) { - qs.include = additionalFields.include; + //https://developer.travis-ci.com/resource/build#restart + if (operation === 'restart') { + const buildId = this.getNodeParameter('buildId', i) as string; + responseData = await travisciApiRequest.call(this, 'POST', `/build/${buildId}/restart`, {}, qs); } + //https://developer.travis-ci.com/resource/requests#create + if (operation === 'trigger') { + let slug = this.getNodeParameter('slug', i) as string; + const branch = this.getNodeParameter('branch', i) as string; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - if (returnAll === true) { - responseData = await travisciApiRequestAllItems.call(this, 'builds', 'GET', '/builds', {}, qs); + slug = slug.replace(new RegExp(/\//g), '%2F'); - } else { - qs.limit = this.getNodeParameter('limit', i) as number; - responseData = await travisciApiRequest.call(this, 'GET', '/builds', {}, qs); - responseData = responseData.builds; + const request: IDataObject = { + branch, + }; + + if (additionalFields.message) { + request.message = additionalFields.message as string; + } + + if (additionalFields.mergeMode) { + request.merge_mode = additionalFields.mergeMode as string; + } + + responseData = await travisciApiRequest.call(this, 'POST', `/repo/${slug}/requests`, JSON.stringify({ request })); } } - //https://developer.travis-ci.com/resource/build#cancel - if (operation === 'cancel') { - const buildId = this.getNodeParameter('buildId', i) as string; - responseData = await travisciApiRequest.call(this, 'POST', `/build/${buildId}/cancel`, {}, qs); + if (Array.isArray(responseData)) { + returnData.push.apply(returnData, responseData as IDataObject[]); + } else { + returnData.push(responseData as IDataObject); } - //https://developer.travis-ci.com/resource/build#restart - if (operation === 'restart') { - const buildId = this.getNodeParameter('buildId', i) as string; - responseData = await travisciApiRequest.call(this, 'POST', `/build/${buildId}/restart`, {}, qs); + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; } - //https://developer.travis-ci.com/resource/requests#create - if (operation === 'trigger') { - let slug = this.getNodeParameter('slug', i) as string; - const branch = this.getNodeParameter('branch', i) as string; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - - slug = slug.replace(new RegExp(/\//g), '%2F'); - - const request: IDataObject = { - branch, - }; - - if (additionalFields.message) { - request.message = additionalFields.message as string; - } - - if (additionalFields.mergeMode) { - request.merge_mode = additionalFields.mergeMode as string; - } - - responseData = await travisciApiRequest.call(this, 'POST', `/repo/${slug}/requests`, JSON.stringify({ request })); - } - } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else { - returnData.push(responseData as IDataObject); + throw error; } } return [this.helpers.returnJsonArray(returnData)]; diff --git a/packages/nodes-base/nodes/Trello/Trello.node.ts b/packages/nodes-base/nodes/Trello/Trello.node.ts index e40f8cec19..951407d9b6 100644 --- a/packages/nodes-base/nodes/Trello/Trello.node.ts +++ b/packages/nodes-base/nodes/Trello/Trello.node.ts @@ -153,605 +153,613 @@ export class Trello implements INodeType { let responseData; for (let i = 0; i < items.length; i++) { - requestMethod = 'GET'; - endpoint = ''; - body = {}; - qs = {}; + try { + requestMethod = 'GET'; + endpoint = ''; + body = {}; + qs = {}; - if (resource === 'board') { + if (resource === 'board') { - if (operation === 'create') { - // ---------------------------------- - // create - // ---------------------------------- + if (operation === 'create') { + // ---------------------------------- + // create + // ---------------------------------- - requestMethod = 'POST'; - endpoint = 'boards'; + requestMethod = 'POST'; + endpoint = 'boards'; - qs.name = this.getNodeParameter('name', i) as string; - qs.desc = this.getNodeParameter('description', i) as string; + qs.name = this.getNodeParameter('name', i) as string; + qs.desc = this.getNodeParameter('description', i) as string; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - Object.assign(qs, additionalFields); + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + Object.assign(qs, additionalFields); - } else if (operation === 'delete') { - // ---------------------------------- - // delete - // ---------------------------------- + } else if (operation === 'delete') { + // ---------------------------------- + // delete + // ---------------------------------- - requestMethod = 'DELETE'; + requestMethod = 'DELETE'; - const id = this.getNodeParameter('id', i) as string; + const id = this.getNodeParameter('id', i) as string; - endpoint = `boards/${id}`; + endpoint = `boards/${id}`; - } else if (operation === 'get') { - // ---------------------------------- - // get - // ---------------------------------- + } else if (operation === 'get') { + // ---------------------------------- + // get + // ---------------------------------- - requestMethod = 'GET'; + requestMethod = 'GET'; - const id = this.getNodeParameter('id', i) as string; + const id = this.getNodeParameter('id', i) as string; - endpoint = `boards/${id}`; + endpoint = `boards/${id}`; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - Object.assign(qs, additionalFields); + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + Object.assign(qs, additionalFields); - } else if (operation === 'update') { - // ---------------------------------- - // update - // ---------------------------------- + } else if (operation === 'update') { + // ---------------------------------- + // update + // ---------------------------------- - requestMethod = 'PUT'; + requestMethod = 'PUT'; - const id = this.getNodeParameter('id', i) as string; + const id = this.getNodeParameter('id', i) as string; - endpoint = `boards/${id}`; + endpoint = `boards/${id}`; - const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; - Object.assign(qs, updateFields); + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + Object.assign(qs, updateFields); - } else { - throw new NodeOperationError(this.getNode(), `The operation "${operation}" is not known!`); - } - - } else if (resource === 'card') { - - if (operation === 'create') { - // ---------------------------------- - // create - // ---------------------------------- - - requestMethod = 'POST'; - endpoint = 'cards'; - - qs.idList = this.getNodeParameter('listId', i) as string; - - qs.name = this.getNodeParameter('name', i) as string; - qs.desc = this.getNodeParameter('description', i) as string; - - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - Object.assign(qs, additionalFields); - - } else if (operation === 'delete') { - // ---------------------------------- - // delete - // ---------------------------------- - - requestMethod = 'DELETE'; - - const id = this.getNodeParameter('id', i) as string; - - endpoint = `cards/${id}`; - - } else if (operation === 'get') { - // ---------------------------------- - // get - // ---------------------------------- - - requestMethod = 'GET'; - - const id = this.getNodeParameter('id', i) as string; - - endpoint = `cards/${id}`; - - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - Object.assign(qs, additionalFields); - - } else if (operation === 'update') { - // ---------------------------------- - // update - // ---------------------------------- - - requestMethod = 'PUT'; - - const id = this.getNodeParameter('id', i) as string; - - endpoint = `cards/${id}`; - - const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; - Object.assign(qs, updateFields); - - } else { - throw new NodeOperationError(this.getNode(), `The operation "${operation}" is not known!`); - } - - } else if (resource === 'cardComment') { - - if (operation === 'create') { - // ---------------------------------- - // create - // ---------------------------------- - - const cardId = this.getNodeParameter('cardId', i) as string; - - qs.text = this.getNodeParameter('text', i) as string; - - requestMethod = 'POST'; - - endpoint = `cards/${cardId}/actions/comments`; - - - } else if (operation === 'delete') { - // ---------------------------------- - // delete - // ---------------------------------- - - requestMethod = 'DELETE'; - - const cardId = this.getNodeParameter('cardId', i) as string; - - const commentId = this.getNodeParameter('commentId', i) as string; - - endpoint = `/cards/${cardId}/actions/${commentId}/comments`; - - } else if (operation === 'update') { - // ---------------------------------- - // update - // ---------------------------------- - - requestMethod = 'PUT'; - - const cardId = this.getNodeParameter('cardId', i) as string; - - const commentId = this.getNodeParameter('commentId', i) as string; - - qs.text = this.getNodeParameter('text', i) as string; - - endpoint = `cards/${cardId}/actions/${commentId}/comments`; - - } else { - throw new NodeOperationError(this.getNode(), `The operation "${operation}" is not known!`); - } - - } else if (resource === 'list') { - - if (operation === 'archive') { - // ---------------------------------- - // archive - // ---------------------------------- - - requestMethod = 'PUT'; - - const id = this.getNodeParameter('id', i) as string; - qs.value = this.getNodeParameter('archive', i) as boolean; - - endpoint = `lists/${id}/closed`; - - } else if (operation === 'create') { - // ---------------------------------- - // create - // ---------------------------------- - - requestMethod = 'POST'; - endpoint = 'lists'; - - qs.idBoard = this.getNodeParameter('idBoard', i) as string; - - qs.name = this.getNodeParameter('name', i) as string; - - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - Object.assign(qs, additionalFields); - - } else if (operation === 'get') { - // ---------------------------------- - // get - // ---------------------------------- - - requestMethod = 'GET'; - - const id = this.getNodeParameter('id', i) as string; - - endpoint = `lists/${id}`; - - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - Object.assign(qs, additionalFields); - - } else if (operation === 'getAll') { - // ---------------------------------- - // getAll - // ---------------------------------- - - requestMethod = 'GET'; - - returnAll = this.getNodeParameter('returnAll', i) as boolean; - - if (returnAll === false) { - qs.limit = this.getNodeParameter('limit', i) as number; + } else { + throw new NodeOperationError(this.getNode(), `The operation "${operation}" is not known!`); } - const id = this.getNodeParameter('id', i) as string; + } else if (resource === 'card') { - endpoint = `boards/${id}/lists`; + if (operation === 'create') { + // ---------------------------------- + // create + // ---------------------------------- - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - Object.assign(qs, additionalFields); + requestMethod = 'POST'; + endpoint = 'cards'; - } else if (operation === 'getCards') { - // ---------------------------------- - // getCards - // ---------------------------------- + qs.idList = this.getNodeParameter('listId', i) as string; - requestMethod = 'GET'; + qs.name = this.getNodeParameter('name', i) as string; + qs.desc = this.getNodeParameter('description', i) as string; - returnAll = this.getNodeParameter('returnAll', i) as boolean; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + Object.assign(qs, additionalFields); - if (returnAll === false) { - qs.limit = this.getNodeParameter('limit', i) as number; + } else if (operation === 'delete') { + // ---------------------------------- + // delete + // ---------------------------------- + + requestMethod = 'DELETE'; + + const id = this.getNodeParameter('id', i) as string; + + endpoint = `cards/${id}`; + + } else if (operation === 'get') { + // ---------------------------------- + // get + // ---------------------------------- + + requestMethod = 'GET'; + + const id = this.getNodeParameter('id', i) as string; + + endpoint = `cards/${id}`; + + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + Object.assign(qs, additionalFields); + + } else if (operation === 'update') { + // ---------------------------------- + // update + // ---------------------------------- + + requestMethod = 'PUT'; + + const id = this.getNodeParameter('id', i) as string; + + endpoint = `cards/${id}`; + + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + Object.assign(qs, updateFields); + + } else { + throw new NodeOperationError(this.getNode(), `The operation "${operation}" is not known!`); } - const id = this.getNodeParameter('id', i) as string; + } else if (resource === 'cardComment') { - endpoint = `lists/${id}/cards`; + if (operation === 'create') { + // ---------------------------------- + // create + // ---------------------------------- - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - Object.assign(qs, additionalFields); + const cardId = this.getNodeParameter('cardId', i) as string; - } else if (operation === 'update') { - // ---------------------------------- - // update - // ---------------------------------- + qs.text = this.getNodeParameter('text', i) as string; - requestMethod = 'PUT'; + requestMethod = 'POST'; - const id = this.getNodeParameter('id', i) as string; + endpoint = `cards/${cardId}/actions/comments`; - endpoint = `lists/${id}`; - const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; - Object.assign(qs, updateFields); + } else if (operation === 'delete') { + // ---------------------------------- + // delete + // ---------------------------------- + requestMethod = 'DELETE'; + + const cardId = this.getNodeParameter('cardId', i) as string; + + const commentId = this.getNodeParameter('commentId', i) as string; + + endpoint = `/cards/${cardId}/actions/${commentId}/comments`; + + } else if (operation === 'update') { + // ---------------------------------- + // update + // ---------------------------------- + + requestMethod = 'PUT'; + + const cardId = this.getNodeParameter('cardId', i) as string; + + const commentId = this.getNodeParameter('commentId', i) as string; + + qs.text = this.getNodeParameter('text', i) as string; + + endpoint = `cards/${cardId}/actions/${commentId}/comments`; + + } else { + throw new NodeOperationError(this.getNode(), `The operation "${operation}" is not known!`); + } + + } else if (resource === 'list') { + + if (operation === 'archive') { + // ---------------------------------- + // archive + // ---------------------------------- + + requestMethod = 'PUT'; + + const id = this.getNodeParameter('id', i) as string; + qs.value = this.getNodeParameter('archive', i) as boolean; + + endpoint = `lists/${id}/closed`; + + } else if (operation === 'create') { + // ---------------------------------- + // create + // ---------------------------------- + + requestMethod = 'POST'; + endpoint = 'lists'; + + qs.idBoard = this.getNodeParameter('idBoard', i) as string; + + qs.name = this.getNodeParameter('name', i) as string; + + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + Object.assign(qs, additionalFields); + + } else if (operation === 'get') { + // ---------------------------------- + // get + // ---------------------------------- + + requestMethod = 'GET'; + + const id = this.getNodeParameter('id', i) as string; + + endpoint = `lists/${id}`; + + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + Object.assign(qs, additionalFields); + + } else if (operation === 'getAll') { + // ---------------------------------- + // getAll + // ---------------------------------- + + requestMethod = 'GET'; + + returnAll = this.getNodeParameter('returnAll', i) as boolean; + + if (returnAll === false) { + qs.limit = this.getNodeParameter('limit', i) as number; + } + + const id = this.getNodeParameter('id', i) as string; + + endpoint = `boards/${id}/lists`; + + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + Object.assign(qs, additionalFields); + + } else if (operation === 'getCards') { + // ---------------------------------- + // getCards + // ---------------------------------- + + requestMethod = 'GET'; + + returnAll = this.getNodeParameter('returnAll', i) as boolean; + + if (returnAll === false) { + qs.limit = this.getNodeParameter('limit', i) as number; + } + + const id = this.getNodeParameter('id', i) as string; + + endpoint = `lists/${id}/cards`; + + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + Object.assign(qs, additionalFields); + + } else if (operation === 'update') { + // ---------------------------------- + // update + // ---------------------------------- + + requestMethod = 'PUT'; + + const id = this.getNodeParameter('id', i) as string; + + endpoint = `lists/${id}`; + + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + Object.assign(qs, updateFields); + + } else { + throw new NodeOperationError(this.getNode(), `The operation "${operation}" is not known!`); + } + + } else if (resource === 'attachment') { + + if (operation === 'create') { + // ---------------------------------- + // create + // ---------------------------------- + + requestMethod = 'POST'; + + const cardId = this.getNodeParameter('cardId', i) as string; + const url = this.getNodeParameter('url', i) as string; + + Object.assign(qs, { + url, + }); + + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + Object.assign(qs, additionalFields); + + endpoint = `cards/${cardId}/attachments`; + + } else if (operation === 'delete') { + // ---------------------------------- + // delete + // ---------------------------------- + + requestMethod = 'DELETE'; + + const cardId = this.getNodeParameter('cardId', i) as string; + const id = this.getNodeParameter('id', i) as string; + + endpoint = `cards/${cardId}/attachments/${id}`; + + } else if (operation === 'get') { + // ---------------------------------- + // get + // ---------------------------------- + + requestMethod = 'GET'; + + const cardId = this.getNodeParameter('cardId', i) as string; + const id = this.getNodeParameter('id', i) as string; + + endpoint = `cards/${cardId}/attachments/${id}`; + + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + Object.assign(qs, additionalFields); + + } else if (operation === 'getAll') { + // ---------------------------------- + // getAll + // ---------------------------------- + + requestMethod = 'GET'; + + const cardId = this.getNodeParameter('cardId', i) as string; + + endpoint = `cards/${cardId}/attachments`; + + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + Object.assign(qs, additionalFields); + } else { + throw new NodeOperationError(this.getNode(), `The operation "${operation}" is not known!`); + } + + } else if (resource === 'checklist') { + + if (operation === 'create') { + // ---------------------------------- + // create + // ---------------------------------- + + requestMethod = 'POST'; + + const cardId = this.getNodeParameter('cardId', i) as string; + const name = this.getNodeParameter('name', i) as string; + + Object.assign(qs, { name }); + + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + Object.assign(qs, additionalFields); + + endpoint = `cards/${cardId}/checklists`; + + } else if (operation === 'delete') { + // ---------------------------------- + // delete + // ---------------------------------- + + requestMethod = 'DELETE'; + + const cardId = this.getNodeParameter('cardId', i) as string; + const id = this.getNodeParameter('id', i) as string; + + endpoint = `cards/${cardId}/checklists/${id}`; + + } else if (operation === 'get') { + // ---------------------------------- + // get + // ---------------------------------- + + requestMethod = 'GET'; + + const id = this.getNodeParameter('id', i) as string; + + endpoint = `checklists/${id}`; + + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + Object.assign(qs, additionalFields); + + } else if (operation === 'getAll') { + // ---------------------------------- + // getAll + // ---------------------------------- + + requestMethod = 'GET'; + + const cardId = this.getNodeParameter('cardId', i) as string; + + endpoint = `cards/${cardId}/checklists`; + + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + Object.assign(qs, additionalFields); + + } else if (operation === 'getCheckItem') { + // ---------------------------------- + // getCheckItem + // ---------------------------------- + + requestMethod = 'GET'; + + const cardId = this.getNodeParameter('cardId', i) as string; + const checkItemId = this.getNodeParameter('checkItemId', i) as string; + + endpoint = `cards/${cardId}/checkItem/${checkItemId}`; + + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + Object.assign(qs, additionalFields); + + } else if (operation === 'createCheckItem') { + // ---------------------------------- + // createCheckItem + // ---------------------------------- + + requestMethod = 'POST'; + + const checklistId = this.getNodeParameter('checklistId', i) as string; + + endpoint = `checklists/${checklistId}/checkItems`; + + const name = this.getNodeParameter('name', i) as string; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + Object.assign(qs, { name, ...additionalFields }); + + } else if (operation === 'deleteCheckItem') { + // ---------------------------------- + // deleteCheckItem + // ---------------------------------- + + requestMethod = 'DELETE'; + + const cardId = this.getNodeParameter('cardId', i) as string; + const checkItemId = this.getNodeParameter('checkItemId', i) as string; + + endpoint = `cards/${cardId}/checkItem/${checkItemId}`; + + } else if (operation === 'updateCheckItem') { + // ---------------------------------- + // updateCheckItem + // ---------------------------------- + + requestMethod = 'PUT'; + + const cardId = this.getNodeParameter('cardId', i) as string; + const checkItemId = this.getNodeParameter('checkItemId', i) as string; + + endpoint = `cards/${cardId}/checkItem/${checkItemId}`; + + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + Object.assign(qs, additionalFields); + + } else if (operation === 'completedCheckItems') { + // ---------------------------------- + // completedCheckItems + // ---------------------------------- + + requestMethod = 'GET'; + + const cardId = this.getNodeParameter('cardId', i) as string; + + endpoint = `cards/${cardId}/checkItemStates`; + + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + Object.assign(qs, additionalFields); + + } else { + throw new NodeOperationError(this.getNode(), `The operation "${operation}" is not known!`); + } + } else if (resource === 'label') { + + if (operation === 'create') { + // ---------------------------------- + // create + // ---------------------------------- + + requestMethod = 'POST'; + + const idBoard = this.getNodeParameter('boardId', i) as string; + const name = this.getNodeParameter('name', i) as string; + const color = this.getNodeParameter('color', i) as string; + + Object.assign(qs, { + idBoard, + name, + color, + }); + + endpoint = 'labels'; + + } else if (operation === 'delete') { + // ---------------------------------- + // delete + // ---------------------------------- + + requestMethod = 'DELETE'; + + const id = this.getNodeParameter('id', i) as string; + + endpoint = `labels/${id}`; + + } else if (operation === 'get') { + // ---------------------------------- + // get + // ---------------------------------- + + requestMethod = 'GET'; + + const id = this.getNodeParameter('id', i) as string; + + endpoint = `labels/${id}`; + + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + Object.assign(qs, additionalFields); + + } else if (operation === 'getAll') { + // ---------------------------------- + // getAll + // ---------------------------------- + + requestMethod = 'GET'; + + const idBoard = this.getNodeParameter('boardId', i) as string; + + endpoint = `board/${idBoard}/labels`; + + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + + Object.assign(qs, additionalFields); + } else if (operation === 'update') { + // ---------------------------------- + // update + // ---------------------------------- + + requestMethod = 'PUT'; + + const id = this.getNodeParameter('id', i) as string; + + endpoint = `labels/${id}`; + + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + Object.assign(qs, updateFields); + + } else if (operation === 'addLabel') { + // ---------------------------------- + // addLabel + // ---------------------------------- + + requestMethod = 'POST'; + + const cardId = this.getNodeParameter('cardId', i) as string; + const id = this.getNodeParameter('id', i) as string; + + qs.value = id; + + endpoint = `/cards/${cardId}/idLabels`; + + } else if (operation === 'removeLabel') { + // ---------------------------------- + // removeLabel + // ---------------------------------- + + requestMethod = 'DELETE'; + + const cardId = this.getNodeParameter('cardId', i) as string; + const id = this.getNodeParameter('id', i) as string; + + endpoint = `/cards/${cardId}/idLabels/${id}`; + + } else { + throw new NodeOperationError(this.getNode(), `The operation "${operation}" is not known!`); + } } else { - throw new NodeOperationError(this.getNode(), `The operation "${operation}" is not known!`); + throw new NodeOperationError(this.getNode(), `The resource "${resource}" is not known!`); } - } else if (resource === 'attachment') { - if (operation === 'create') { - // ---------------------------------- - // create - // ---------------------------------- + // resources listed here do not support pagination so + // paginate them 'manually' + const skipPagination = [ + 'list:getAll', + ]; - requestMethod = 'POST'; - - const cardId = this.getNodeParameter('cardId', i) as string; - const url = this.getNodeParameter('url', i) as string; - - Object.assign(qs, { - url, - }); - - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - Object.assign(qs, additionalFields); - - endpoint = `cards/${cardId}/attachments`; - - } else if (operation === 'delete') { - // ---------------------------------- - // delete - // ---------------------------------- - - requestMethod = 'DELETE'; - - const cardId = this.getNodeParameter('cardId', i) as string; - const id = this.getNodeParameter('id', i) as string; - - endpoint = `cards/${cardId}/attachments/${id}`; - - } else if (operation === 'get') { - // ---------------------------------- - // get - // ---------------------------------- - - requestMethod = 'GET'; - - const cardId = this.getNodeParameter('cardId', i) as string; - const id = this.getNodeParameter('id', i) as string; - - endpoint = `cards/${cardId}/attachments/${id}`; - - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - Object.assign(qs, additionalFields); - - } else if (operation === 'getAll') { - // ---------------------------------- - // getAll - // ---------------------------------- - - requestMethod = 'GET'; - - const cardId = this.getNodeParameter('cardId', i) as string; - - endpoint = `cards/${cardId}/attachments`; - - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - Object.assign(qs, additionalFields); + if (returnAll === true && !skipPagination.includes(`${resource}:${operation}`)) { + responseData = await apiRequestAllItems.call(this, requestMethod, endpoint, body, qs); } else { - throw new NodeOperationError(this.getNode(), `The operation "${operation}" is not known!`); + responseData = await apiRequest.call(this, requestMethod, endpoint, body, qs); + if (returnAll === false && qs.limit) { + responseData = responseData.splice(0, qs.limit); + } } - } else if (resource === 'checklist') { - - if (operation === 'create') { - // ---------------------------------- - // create - // ---------------------------------- - - requestMethod = 'POST'; - - const cardId = this.getNodeParameter('cardId', i) as string; - const name = this.getNodeParameter('name', i) as string; - - Object.assign(qs, { name }); - - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - Object.assign(qs, additionalFields); - - endpoint = `cards/${cardId}/checklists`; - - } else if (operation === 'delete') { - // ---------------------------------- - // delete - // ---------------------------------- - - requestMethod = 'DELETE'; - - const cardId = this.getNodeParameter('cardId', i) as string; - const id = this.getNodeParameter('id', i) as string; - - endpoint = `cards/${cardId}/checklists/${id}`; - - } else if (operation === 'get') { - // ---------------------------------- - // get - // ---------------------------------- - - requestMethod = 'GET'; - - const id = this.getNodeParameter('id', i) as string; - - endpoint = `checklists/${id}`; - - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - Object.assign(qs, additionalFields); - - } else if (operation === 'getAll') { - // ---------------------------------- - // getAll - // ---------------------------------- - - requestMethod = 'GET'; - - const cardId = this.getNodeParameter('cardId', i) as string; - - endpoint = `cards/${cardId}/checklists`; - - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - Object.assign(qs, additionalFields); - - } else if (operation === 'getCheckItem') { - // ---------------------------------- - // getCheckItem - // ---------------------------------- - - requestMethod = 'GET'; - - const cardId = this.getNodeParameter('cardId', i) as string; - const checkItemId = this.getNodeParameter('checkItemId', i) as string; - - endpoint = `cards/${cardId}/checkItem/${checkItemId}`; - - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - Object.assign(qs, additionalFields); - - } else if (operation === 'createCheckItem') { - // ---------------------------------- - // createCheckItem - // ---------------------------------- - - requestMethod = 'POST'; - - const checklistId = this.getNodeParameter('checklistId', i) as string; - - endpoint = `checklists/${checklistId}/checkItems`; - - const name = this.getNodeParameter('name', i) as string; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - Object.assign(qs, { name, ...additionalFields }); - - } else if (operation === 'deleteCheckItem') { - // ---------------------------------- - // deleteCheckItem - // ---------------------------------- - - requestMethod = 'DELETE'; - - const cardId = this.getNodeParameter('cardId', i) as string; - const checkItemId = this.getNodeParameter('checkItemId', i) as string; - - endpoint = `cards/${cardId}/checkItem/${checkItemId}`; - - } else if (operation === 'updateCheckItem') { - // ---------------------------------- - // updateCheckItem - // ---------------------------------- - - requestMethod = 'PUT'; - - const cardId = this.getNodeParameter('cardId', i) as string; - const checkItemId = this.getNodeParameter('checkItemId', i) as string; - - endpoint = `cards/${cardId}/checkItem/${checkItemId}`; - - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - Object.assign(qs, additionalFields); - - } else if (operation === 'completedCheckItems') { - // ---------------------------------- - // completedCheckItems - // ---------------------------------- - - requestMethod = 'GET'; - - const cardId = this.getNodeParameter('cardId', i) as string; - - endpoint = `cards/${cardId}/checkItemStates`; - - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - Object.assign(qs, additionalFields); - + if (Array.isArray(responseData)) { + returnData.push.apply(returnData, responseData as IDataObject[]); } else { - throw new NodeOperationError(this.getNode(), `The operation "${operation}" is not known!`); + returnData.push(responseData as IDataObject); } - } else if (resource === 'label') { - - if (operation === 'create') { - // ---------------------------------- - // create - // ---------------------------------- - - requestMethod = 'POST'; - - const idBoard = this.getNodeParameter('boardId', i) as string; - const name = this.getNodeParameter('name', i) as string; - const color = this.getNodeParameter('color', i) as string; - - Object.assign(qs, { - idBoard, - name, - color, - }); - - endpoint = 'labels'; - - } else if (operation === 'delete') { - // ---------------------------------- - // delete - // ---------------------------------- - - requestMethod = 'DELETE'; - - const id = this.getNodeParameter('id', i) as string; - - endpoint = `labels/${id}`; - - } else if (operation === 'get') { - // ---------------------------------- - // get - // ---------------------------------- - - requestMethod = 'GET'; - - const id = this.getNodeParameter('id', i) as string; - - endpoint = `labels/${id}`; - - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - Object.assign(qs, additionalFields); - - } else if (operation === 'getAll') { - // ---------------------------------- - // getAll - // ---------------------------------- - - requestMethod = 'GET'; - - const idBoard = this.getNodeParameter('boardId', i) as string; - - endpoint = `board/${idBoard}/labels`; - - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - - Object.assign(qs, additionalFields); - } else if (operation === 'update') { - // ---------------------------------- - // update - // ---------------------------------- - - requestMethod = 'PUT'; - - const id = this.getNodeParameter('id', i) as string; - - endpoint = `labels/${id}`; - - const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; - Object.assign(qs, updateFields); - - } else if (operation === 'addLabel') { - // ---------------------------------- - // addLabel - // ---------------------------------- - - requestMethod = 'POST'; - - const cardId = this.getNodeParameter('cardId', i) as string; - const id = this.getNodeParameter('id', i) as string; - - qs.value = id; - - endpoint = `/cards/${cardId}/idLabels`; - - } else if (operation === 'removeLabel') { - // ---------------------------------- - // removeLabel - // ---------------------------------- - - requestMethod = 'DELETE'; - - const cardId = this.getNodeParameter('cardId', i) as string; - const id = this.getNodeParameter('id', i) as string; - - endpoint = `/cards/${cardId}/idLabels/${id}`; - - } else { - throw new NodeOperationError(this.getNode(), `The operation "${operation}" is not known!`); + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; } - } else { - throw new NodeOperationError(this.getNode(), `The resource "${resource}" is not known!`); - } - - - // resources listed here do not support pagination so - // paginate them 'manually' - const skipPagination = [ - 'list:getAll', - ]; - - if (returnAll === true && !skipPagination.includes(`${resource}:${operation}`)) { - responseData = await apiRequestAllItems.call(this, requestMethod, endpoint, body, qs); - } else { - responseData = await apiRequest.call(this, requestMethod, endpoint, body, qs); - if (returnAll === false && qs.limit) { - responseData = responseData.splice(0, qs.limit); - } - } - - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else { - returnData.push(responseData as IDataObject); + throw error; } } diff --git a/packages/nodes-base/nodes/Twilio/Twilio.node.ts b/packages/nodes-base/nodes/Twilio/Twilio.node.ts index 7eeb1bff86..64deeb2af7 100644 --- a/packages/nodes-base/nodes/Twilio/Twilio.node.ts +++ b/packages/nodes-base/nodes/Twilio/Twilio.node.ts @@ -172,43 +172,51 @@ export class Twilio implements INodeType { let endpoint: string; for (let i = 0; i < items.length; i++) { - requestMethod = 'GET'; - endpoint = ''; - body = {}; - qs = {}; + try { + requestMethod = 'GET'; + endpoint = ''; + body = {}; + qs = {}; - resource = this.getNodeParameter('resource', i) as string; - operation = this.getNodeParameter('operation', i) as string; + resource = this.getNodeParameter('resource', i) as string; + operation = this.getNodeParameter('operation', i) as string; - if (resource === 'sms') { - if (operation === 'send') { - // ---------------------------------- - // sms:send - // ---------------------------------- + if (resource === 'sms') { + if (operation === 'send') { + // ---------------------------------- + // sms:send + // ---------------------------------- - requestMethod = 'POST'; - endpoint = '/Messages.json'; + requestMethod = 'POST'; + endpoint = '/Messages.json'; - body.From = this.getNodeParameter('from', i) as string; - body.To = this.getNodeParameter('to', i) as string; - body.Body = this.getNodeParameter('message', i) as string; + body.From = this.getNodeParameter('from', i) as string; + body.To = this.getNodeParameter('to', i) as string; + body.Body = this.getNodeParameter('message', i) as string; - const toWhatsapp = this.getNodeParameter('toWhatsapp', i) as boolean; + const toWhatsapp = this.getNodeParameter('toWhatsapp', i) as boolean; - if (toWhatsapp === true) { - body.From = `whatsapp:${body.From}`; - body.To = `whatsapp:${body.To}`; + if (toWhatsapp === true) { + body.From = `whatsapp:${body.From}`; + body.To = `whatsapp:${body.To}`; + } + } else { + throw new NodeOperationError(this.getNode(), `The operation "${operation}" is not known!`); } } else { - throw new NodeOperationError(this.getNode(), `The operation "${operation}" is not known!`); + throw new NodeOperationError(this.getNode(), `The resource "${resource}" is not known!`); } - } else { - throw new NodeOperationError(this.getNode(), `The resource "${resource}" is not known!`); + + const responseData = await twilioApiRequest.call(this, requestMethod, endpoint, body, qs); + + returnData.push(responseData as IDataObject); + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } - - const responseData = await twilioApiRequest.call(this, requestMethod, endpoint, body, qs); - - returnData.push(responseData as IDataObject); } return [this.helpers.returnJsonArray(returnData)]; diff --git a/packages/nodes-base/nodes/Twist/Twist.node.ts b/packages/nodes-base/nodes/Twist/Twist.node.ts index 232cb4bf1a..c749e2b577 100644 --- a/packages/nodes-base/nodes/Twist/Twist.node.ts +++ b/packages/nodes-base/nodes/Twist/Twist.node.ts @@ -176,587 +176,595 @@ export class Twist implements INodeType { 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 === 'channel') { - //https://developer.twist.com/v3/#add-channel - if (operation === 'create') { - const workspaceId = this.getNodeParameter('workspaceId', i) as string; - const name = this.getNodeParameter('name', i) as string; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const body: IDataObject = { - workspace_id: workspaceId, - name, - }; - Object.assign(body, additionalFields); + try { + if (resource === 'channel') { + //https://developer.twist.com/v3/#add-channel + if (operation === 'create') { + const workspaceId = this.getNodeParameter('workspaceId', i) as string; + const name = this.getNodeParameter('name', i) as string; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const body: IDataObject = { + workspace_id: workspaceId, + name, + }; + Object.assign(body, additionalFields); - responseData = await twistApiRequest.call(this, 'POST', '/channels/add', body); - } - //https://developer.twist.com/v3/#remove-channel - if (operation === 'delete') { - qs.id = this.getNodeParameter('channelId', i) as string; - - responseData = await twistApiRequest.call(this, 'POST', '/channels/remove', {}, qs); - } - //https://developer.twist.com/v3/#get-channel - if (operation === 'get') { - qs.id = this.getNodeParameter('channelId', i) as string; - - responseData = await twistApiRequest.call(this, 'GET', '/channels/getone', {}, qs); - } - //https://developer.twist.com/v3/#get-all-channels - if (operation === 'getAll') { - const workspaceId = this.getNodeParameter('workspaceId', i) as string; - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - const filters = this.getNodeParameter('filters', i) as IDataObject; - qs.workspace_id = workspaceId; - Object.assign(qs, filters); - - responseData = await twistApiRequest.call(this, 'GET', '/channels/get', {}, qs); - - if (!returnAll) { - const limit = this.getNodeParameter('limit', i) as number; - responseData = responseData.splice(0, limit); + responseData = await twistApiRequest.call(this, 'POST', '/channels/add', body); } - } - //https://developer.twist.com/v3/#update-channel - if (operation === 'update') { - const channelId = this.getNodeParameter('channelId', i) as string; - const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; - const body: IDataObject = { - id: channelId, - }; - Object.assign(body, updateFields); + //https://developer.twist.com/v3/#remove-channel + if (operation === 'delete') { + qs.id = this.getNodeParameter('channelId', i) as string; - responseData = await twistApiRequest.call(this, 'POST', '/channels/update', body); - } - //https://developer.twist.com/v3/#archive-channel - if (operation === 'archive') { - qs.id = this.getNodeParameter('channelId', i) as string; + responseData = await twistApiRequest.call(this, 'POST', '/channels/remove', {}, qs); + } + //https://developer.twist.com/v3/#get-channel + if (operation === 'get') { + qs.id = this.getNodeParameter('channelId', i) as string; - responseData = await twistApiRequest.call(this, 'POST', '/channels/archive', {}, qs); - } - //https://developer.twist.com/v3/#unarchive-channel - if (operation === 'unarchive') { - qs.id = this.getNodeParameter('channelId', i) as string; + responseData = await twistApiRequest.call(this, 'GET', '/channels/getone', {}, qs); + } + //https://developer.twist.com/v3/#get-all-channels + if (operation === 'getAll') { + const workspaceId = this.getNodeParameter('workspaceId', i) as string; + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + const filters = this.getNodeParameter('filters', i) as IDataObject; + qs.workspace_id = workspaceId; + Object.assign(qs, filters); - responseData = await twistApiRequest.call(this, 'POST', '/channels/unarchive', {}, qs); - } - } - if (resource === 'comment') { - //https://developer.twist.com/v3/#add-comment - if (operation === 'create') { - const threadId = this.getNodeParameter('threadId', i) as string; - const content = this.getNodeParameter('content', i) as string; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const body: IDataObject = { - thread_id: threadId, - content, - }; - Object.assign(body, additionalFields); + responseData = await twistApiRequest.call(this, 'GET', '/channels/get', {}, qs); - if (body.actionsUi) { - const actions = (body.actionsUi as IDataObject).actionValues as IDataObject[]; - - if (actions) { - body.actions = actions; - delete body.actionsUi; + if (!returnAll) { + const limit = this.getNodeParameter('limit', i) as number; + responseData = responseData.splice(0, limit); } } + //https://developer.twist.com/v3/#update-channel + if (operation === 'update') { + const channelId = this.getNodeParameter('channelId', i) as string; + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + const body: IDataObject = { + id: channelId, + }; + Object.assign(body, updateFields); - if (body.binaryProperties) { - const binaryProperties = (body.binaryProperties as string).split(',') as string[]; + responseData = await twistApiRequest.call(this, 'POST', '/channels/update', body); + } + //https://developer.twist.com/v3/#archive-channel + if (operation === 'archive') { + qs.id = this.getNodeParameter('channelId', i) as string; - const attachments: IDataObject[] = []; + responseData = await twistApiRequest.call(this, 'POST', '/channels/archive', {}, qs); + } + //https://developer.twist.com/v3/#unarchive-channel + if (operation === 'unarchive') { + qs.id = this.getNodeParameter('channelId', i) as string; - for (const binaryProperty of binaryProperties) { + responseData = await twistApiRequest.call(this, 'POST', '/channels/unarchive', {}, qs); + } + } + if (resource === 'comment') { + //https://developer.twist.com/v3/#add-comment + if (operation === 'create') { + const threadId = this.getNodeParameter('threadId', i) as string; + const content = this.getNodeParameter('content', i) as string; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const body: IDataObject = { + thread_id: threadId, + content, + }; + Object.assign(body, additionalFields); - const item = items[i].binary as IBinaryKeyData; + if (body.actionsUi) { + const actions = (body.actionsUi as IDataObject).actionValues as IDataObject[]; - const binaryData = item[binaryProperty] as IBinaryData; + if (actions) { + body.actions = actions; + delete body.actionsUi; + } + } - if (binaryData === undefined) { - throw new Error(`No binary data property "${binaryProperty}" does not exists on item!`); + if (body.binaryProperties) { + const binaryProperties = (body.binaryProperties as string).split(',') as string[]; + + const attachments: IDataObject[] = []; + + for (const binaryProperty of binaryProperties) { + + const item = items[i].binary as IBinaryKeyData; + + const binaryData = item[binaryProperty] as IBinaryData; + + if (binaryData === undefined) { + throw new Error(`No binary data property "${binaryProperty}" does not exists on item!`); + } + + attachments.push(await twistApiRequest.call( + this, + 'POST', + '/attachments/upload', + {}, + {}, + { + formData: { + file_name: { + value: Buffer.from(binaryData.data, BINARY_ENCODING), + options: { + filename: binaryData.fileName, + }, + }, + attachment_id: uuid(), + }, + }, + )); } - attachments.push(await twistApiRequest.call( - this, - 'POST', - '/attachments/upload', - {}, - {}, - { - formData: { - file_name: { - value: Buffer.from(binaryData.data, BINARY_ENCODING), - options: { - filename: binaryData.fileName, + body.attachments = attachments; + } + + if (body.direct_mentions) { + const directMentions: string[] = []; + for (const directMention of body.direct_mentions as number[]) { + directMentions.push(`[name](twist-mention://${directMention})`); + } + body.content = `${directMentions.join(' ')} ${body.content}`; + } + + responseData = await twistApiRequest.call(this, 'POST', '/comments/add', body); + } + //https://developer.twist.com/v3/#remove-comment + if (operation === 'delete') { + qs.id = this.getNodeParameter('commentId', i) as string; + + responseData = await twistApiRequest.call(this, 'POST', '/comments/remove', {}, qs); + } + //https://developer.twist.com/v3/#get-comment + if (operation === 'get') { + qs.id = this.getNodeParameter('commentId', i) as string; + + responseData = await twistApiRequest.call(this, 'GET', '/comments/getone', {}, qs); + responseData = responseData?.comment; + } + //https://developer.twist.com/v3/#get-all-comments + if (operation === 'getAll') { + const threadId = this.getNodeParameter('threadId', i) as string; + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + const filters = this.getNodeParameter('filters', i) as IDataObject; + qs.thread_id = threadId; + + Object.assign(qs, filters); + if (!returnAll) { + qs.limit = this.getNodeParameter('limit', i) as number; + } + if (qs.older_than_ts) { + qs.older_than_ts = moment(qs.older_than_ts as string).unix(); + } + if (qs.newer_than_ts) { + qs.newer_than_ts = moment(qs.newer_than_ts as string).unix(); + } + + responseData = await twistApiRequest.call(this, 'GET', '/comments/get', {}, qs); + if (qs.as_ids) { + responseData = (responseData as number[]).map(id => ({ ID: id })); + } + } + //https://developer.twist.com/v3/#update-comment + if (operation === 'update') { + const commentId = this.getNodeParameter('commentId', i) as string; + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + const body: IDataObject = { + id: commentId, + }; + Object.assign(body, updateFields); + + if (body.actionsUi) { + const actions = (body.actionsUi as IDataObject).actionValues as IDataObject[]; + + if (actions) { + body.actions = actions; + delete body.actionsUi; + } + } + + if (body.binaryProperties) { + const binaryProperties = (body.binaryProperties as string).split(',') as string[]; + + const attachments: IDataObject[] = []; + + for (const binaryProperty of binaryProperties) { + + const item = items[i].binary as IBinaryKeyData; + + const binaryData = item[binaryProperty] as IBinaryData; + + if (binaryData === undefined) { + throw new Error(`No binary data property "${binaryProperty}" does not exists on item!`); + } + + attachments.push(await twistApiRequest.call( + this, + 'POST', + '/attachments/upload', + {}, + {}, + { + formData: { + file_name: { + value: Buffer.from(binaryData.data, BINARY_ENCODING), + options: { + filename: binaryData.fileName, + }, }, + attachment_id: uuid(), }, - attachment_id: uuid(), }, - }, - )); - } - - body.attachments = attachments; - } - - if (body.direct_mentions) { - const directMentions: string[] = []; - for (const directMention of body.direct_mentions as number[]) { - directMentions.push(`[name](twist-mention://${directMention})`); - } - body.content = `${directMentions.join(' ')} ${body.content}`; - } - - responseData = await twistApiRequest.call(this, 'POST', '/comments/add', body); - } - //https://developer.twist.com/v3/#remove-comment - if (operation === 'delete') { - qs.id = this.getNodeParameter('commentId', i) as string; - - responseData = await twistApiRequest.call(this, 'POST', '/comments/remove', {}, qs); - } - //https://developer.twist.com/v3/#get-comment - if (operation === 'get') { - qs.id = this.getNodeParameter('commentId', i) as string; - - responseData = await twistApiRequest.call(this, 'GET', '/comments/getone', {}, qs); - responseData = responseData?.comment; - } - //https://developer.twist.com/v3/#get-all-comments - if (operation === 'getAll') { - const threadId = this.getNodeParameter('threadId', i) as string; - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - const filters = this.getNodeParameter('filters', i) as IDataObject; - qs.thread_id = threadId; - - Object.assign(qs, filters); - if (!returnAll) { - qs.limit = this.getNodeParameter('limit', i) as number; - } - if (qs.older_than_ts) { - qs.older_than_ts = moment(qs.older_than_ts as string).unix(); - } - if (qs.newer_than_ts) { - qs.newer_than_ts = moment(qs.newer_than_ts as string).unix(); - } - - responseData = await twistApiRequest.call(this, 'GET', '/comments/get', {}, qs); - if (qs.as_ids) { - responseData = (responseData as number[]).map(id => ({ ID: id })); - } - } - //https://developer.twist.com/v3/#update-comment - if (operation === 'update') { - const commentId = this.getNodeParameter('commentId', i) as string; - const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; - const body: IDataObject = { - id: commentId, - }; - Object.assign(body, updateFields); - - if (body.actionsUi) { - const actions = (body.actionsUi as IDataObject).actionValues as IDataObject[]; - - if (actions) { - body.actions = actions; - delete body.actionsUi; - } - } - - if (body.binaryProperties) { - const binaryProperties = (body.binaryProperties as string).split(',') as string[]; - - const attachments: IDataObject[] = []; - - for (const binaryProperty of binaryProperties) { - - const item = items[i].binary as IBinaryKeyData; - - const binaryData = item[binaryProperty] as IBinaryData; - - if (binaryData === undefined) { - throw new Error(`No binary data property "${binaryProperty}" does not exists on item!`); + )); } - attachments.push(await twistApiRequest.call( - this, - 'POST', - '/attachments/upload', - {}, - {}, - { - formData: { - file_name: { - value: Buffer.from(binaryData.data, BINARY_ENCODING), - options: { - filename: binaryData.fileName, - }, - }, - attachment_id: uuid(), - }, - }, - )); + body.attachments = attachments; } - body.attachments = attachments; - } - - if (body.direct_mentions) { - const directMentions: string[] = []; - for (const directMention of body.direct_mentions as number[]) { - directMentions.push(`[name](twist-mention://${directMention})`); + if (body.direct_mentions) { + const directMentions: string[] = []; + for (const directMention of body.direct_mentions as number[]) { + directMentions.push(`[name](twist-mention://${directMention})`); + } + body.content = `${directMentions.join(' ')} ${body.content}`; } - body.content = `${directMentions.join(' ')} ${body.content}`; - } - responseData = await twistApiRequest.call(this, 'POST', '/comments/update', body); + responseData = await twistApiRequest.call(this, 'POST', '/comments/update', body); + } } - } - if (resource === 'messageConversation') { - //https://developer.twist.com/v3/#add-message-to-conversation - if (operation === 'create') { - const workspaceId = this.getNodeParameter('workspaceId', i) as string; - const conversationId = this.getNodeParameter('conversationId', i) as string; - const content = this.getNodeParameter('content', i) as string; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const body: IDataObject = { - conversation_id: conversationId, - workspace_id: workspaceId, - content, - }; - Object.assign(body, additionalFields); + if (resource === 'messageConversation') { + //https://developer.twist.com/v3/#add-message-to-conversation + if (operation === 'create') { + const workspaceId = this.getNodeParameter('workspaceId', i) as string; + const conversationId = this.getNodeParameter('conversationId', i) as string; + const content = this.getNodeParameter('content', i) as string; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const body: IDataObject = { + conversation_id: conversationId, + workspace_id: workspaceId, + content, + }; + Object.assign(body, additionalFields); - if (body.actionsUi) { - const actions = (body.actionsUi as IDataObject).actionValues as IDataObject[]; + if (body.actionsUi) { + const actions = (body.actionsUi as IDataObject).actionValues as IDataObject[]; - if (actions) { - body.actions = actions; - delete body.actionsUi; + if (actions) { + body.actions = actions; + delete body.actionsUi; + } } - } - if (body.binaryProperties) { - const binaryProperties = (body.binaryProperties as string).split(',') as string[]; + if (body.binaryProperties) { + const binaryProperties = (body.binaryProperties as string).split(',') as string[]; - const attachments: IDataObject[] = []; + const attachments: IDataObject[] = []; - for (const binaryProperty of binaryProperties) { + for (const binaryProperty of binaryProperties) { - const item = items[i].binary as IBinaryKeyData; + const item = items[i].binary as IBinaryKeyData; - const binaryData = item[binaryProperty] as IBinaryData; + const binaryData = item[binaryProperty] as IBinaryData; - if (binaryData === undefined) { - throw new NodeOperationError(this.getNode(), `No binary data property "${binaryProperty}" does not exists on item!`); + if (binaryData === undefined) { + throw new NodeOperationError(this.getNode(), `No binary data property "${binaryProperty}" does not exists on item!`); + } + + attachments.push(await twistApiRequest.call( + this, + 'POST', + '/attachments/upload', + {}, + {}, + { + formData: { + file_name: { + value: Buffer.from(binaryData.data, BINARY_ENCODING), + options: { + filename: binaryData.fileName, + }, + }, + attachment_id: uuid(), + }, + }, + )); } - attachments.push(await twistApiRequest.call( - this, - 'POST', - '/attachments/upload', - {}, - {}, - { - formData: { - file_name: { - value: Buffer.from(binaryData.data, BINARY_ENCODING), - options: { - filename: binaryData.fileName, + body.attachments = attachments; + } + + if (body.direct_mentions) { + const directMentions: string[] = []; + for (const directMention of body.direct_mentions as number[]) { + directMentions.push(`[name](twist-mention://${directMention})`); + } + body.content = `${directMentions.join(' ')} ${body.content}`; + } + + // if (body.direct_group_mentions) { + // const directGroupMentions: string[] = []; + // for (const directGroupMention of body.direct_group_mentions as number[]) { + // directGroupMentions.push(`[Group name](twist-group-mention://${directGroupMention})`); + // } + // body.content = `${directGroupMentions.join(' ')} ${body.content}`; + // } + + responseData = await twistApiRequest.call(this, 'POST', '/conversation_messages/add', body); + } + //https://developer.twist.com/v3/#get-message + if (operation === 'get') { + qs.id = this.getNodeParameter('id', i) as string; + + responseData = await twistApiRequest.call(this, 'GET', '/conversation_messages/getone', {}, qs); + } + //https://developer.twist.com/v3/#get-all-messages + if (operation === 'getAll') { + const conversationId = this.getNodeParameter('conversationId', i) as string; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + qs.conversation_id = conversationId; + Object.assign(qs, additionalFields); + + responseData = await twistApiRequest.call(this, 'GET', '/conversation_messages/get', {}, qs); + } + //https://developer.twist.com/v3/#remove-message-from-conversation + if (operation === 'delete') { + qs.id = this.getNodeParameter('id', i) as string; + + responseData = await twistApiRequest.call(this, 'POST', '/conversation_messages/remove', {}, qs); + } + //https://developer.twist.com/v3/#update-message-in-conversation + if (operation === 'update') { + const id = this.getNodeParameter('id', i) as string; + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + const body: IDataObject = { + id, + }; + Object.assign(body, updateFields); + + if (body.actionsUi) { + const actions = (body.actionsUi as IDataObject).actionValues as IDataObject[]; + + if (actions) { + body.actions = actions; + delete body.actionsUi; + } + } + + if (body.binaryProperties) { + const binaryProperties = (body.binaryProperties as string).split(',') as string[]; + + const attachments: IDataObject[] = []; + + for (const binaryProperty of binaryProperties) { + + const item = items[i].binary as IBinaryKeyData; + + const binaryData = item[binaryProperty] as IBinaryData; + + if (binaryData === undefined) { + throw new Error(`No binary data property "${binaryProperty}" does not exists on item!`); + } + + attachments.push(await twistApiRequest.call( + this, + 'POST', + '/attachments/upload', + {}, + {}, + { + formData: { + file_name: { + value: Buffer.from(binaryData.data, BINARY_ENCODING), + options: { + filename: binaryData.fileName, + }, }, + attachment_id: uuid(), }, - attachment_id: uuid(), }, - }, - )); - } - - body.attachments = attachments; - } - - if (body.direct_mentions) { - const directMentions: string[] = []; - for (const directMention of body.direct_mentions as number[]) { - directMentions.push(`[name](twist-mention://${directMention})`); - } - body.content = `${directMentions.join(' ')} ${body.content}`; - } - - // if (body.direct_group_mentions) { - // const directGroupMentions: string[] = []; - // for (const directGroupMention of body.direct_group_mentions as number[]) { - // directGroupMentions.push(`[Group name](twist-group-mention://${directGroupMention})`); - // } - // body.content = `${directGroupMentions.join(' ')} ${body.content}`; - // } - - responseData = await twistApiRequest.call(this, 'POST', '/conversation_messages/add', body); - } - //https://developer.twist.com/v3/#get-message - if (operation === 'get') { - qs.id = this.getNodeParameter('id', i) as string; - - responseData = await twistApiRequest.call(this, 'GET', '/conversation_messages/getone', {}, qs); - } - //https://developer.twist.com/v3/#get-all-messages - if (operation === 'getAll') { - const conversationId = this.getNodeParameter('conversationId', i) as string; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - qs.conversation_id = conversationId; - Object.assign(qs, additionalFields); - - responseData = await twistApiRequest.call(this, 'GET', '/conversation_messages/get', {}, qs); - } - //https://developer.twist.com/v3/#remove-message-from-conversation - if (operation === 'delete') { - qs.id = this.getNodeParameter('id', i) as string; - - responseData = await twistApiRequest.call(this, 'POST', '/conversation_messages/remove', {}, qs); - } - //https://developer.twist.com/v3/#update-message-in-conversation - if (operation === 'update') { - const id = this.getNodeParameter('id', i) as string; - const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; - const body: IDataObject = { - id, - }; - Object.assign(body, updateFields); - - if (body.actionsUi) { - const actions = (body.actionsUi as IDataObject).actionValues as IDataObject[]; - - if (actions) { - body.actions = actions; - delete body.actionsUi; - } - } - - if (body.binaryProperties) { - const binaryProperties = (body.binaryProperties as string).split(',') as string[]; - - const attachments: IDataObject[] = []; - - for (const binaryProperty of binaryProperties) { - - const item = items[i].binary as IBinaryKeyData; - - const binaryData = item[binaryProperty] as IBinaryData; - - if (binaryData === undefined) { - throw new Error(`No binary data property "${binaryProperty}" does not exists on item!`); + )); } - attachments.push(await twistApiRequest.call( - this, - 'POST', - '/attachments/upload', - {}, - {}, - { - formData: { - file_name: { - value: Buffer.from(binaryData.data, BINARY_ENCODING), - options: { - filename: binaryData.fileName, - }, - }, - attachment_id: uuid(), - }, - }, - )); + body.attachments = attachments; } - body.attachments = attachments; - } - - if (body.direct_mentions) { - const directMentions: string[] = []; - for (const directMention of body.direct_mentions as number[]) { - directMentions.push(`[name](twist-mention://${directMention})`); + if (body.direct_mentions) { + const directMentions: string[] = []; + for (const directMention of body.direct_mentions as number[]) { + directMentions.push(`[name](twist-mention://${directMention})`); + } + body.content = `${directMentions.join(' ')} ${body.content}`; } - body.content = `${directMentions.join(' ')} ${body.content}`; - } - responseData = await twistApiRequest.call(this, 'POST', '/conversation_messages/update', body); + responseData = await twistApiRequest.call(this, 'POST', '/conversation_messages/update', body); + } } - } - if (resource === 'thread') { - //https://developer.twist.com/v3/#add-thread - if (operation === 'create') { - const channelId = this.getNodeParameter('channelId', i) as string; - const title = this.getNodeParameter('title', i) as string; - const content = this.getNodeParameter('content', i) as string; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const body: IDataObject = { - channel_id: channelId, - content, - title, - }; - Object.assign(body, additionalFields); + if (resource === 'thread') { + //https://developer.twist.com/v3/#add-thread + if (operation === 'create') { + const channelId = this.getNodeParameter('channelId', i) as string; + const title = this.getNodeParameter('title', i) as string; + const content = this.getNodeParameter('content', i) as string; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const body: IDataObject = { + channel_id: channelId, + content, + title, + }; + Object.assign(body, additionalFields); - if (body.actionsUi) { - const actions = (body.actionsUi as IDataObject).actionValues as IDataObject[]; + if (body.actionsUi) { + const actions = (body.actionsUi as IDataObject).actionValues as IDataObject[]; - if (actions) { - body.actions = actions; - delete body.actionsUi; + if (actions) { + body.actions = actions; + delete body.actionsUi; + } } - } - if (body.binaryProperties) { - const binaryProperties = (body.binaryProperties as string).split(',') as string[]; + if (body.binaryProperties) { + const binaryProperties = (body.binaryProperties as string).split(',') as string[]; - const attachments: IDataObject[] = []; + const attachments: IDataObject[] = []; - for (const binaryProperty of binaryProperties) { + for (const binaryProperty of binaryProperties) { - const item = items[i].binary as IBinaryKeyData; + const item = items[i].binary as IBinaryKeyData; - const binaryData = item[binaryProperty] as IBinaryData; + const binaryData = item[binaryProperty] as IBinaryData; - if (binaryData === undefined) { - throw new Error(`No binary data property "${binaryProperty}" does not exists on item!`); + if (binaryData === undefined) { + throw new Error(`No binary data property "${binaryProperty}" does not exists on item!`); + } + + attachments.push(await twistApiRequest.call( + this, + 'POST', + '/attachments/upload', + {}, + {}, + { + formData: { + file_name: { + value: Buffer.from(binaryData.data, BINARY_ENCODING), + options: { + filename: binaryData.fileName, + }, + }, + attachment_id: uuid(), + }, + }, + )); } - attachments.push(await twistApiRequest.call( - this, - 'POST', - '/attachments/upload', - {}, - {}, - { - formData: { - file_name: { - value: Buffer.from(binaryData.data, BINARY_ENCODING), - options: { - filename: binaryData.fileName, + body.attachments = attachments; + } + + if (body.direct_mentions) { + const directMentions: string[] = []; + for (const directMention of body.direct_mentions as number[]) { + directMentions.push(`[name](twist-mention://${directMention})`); + } + body.content = `${directMentions.join(' ')} ${body.content}`; + } + + responseData = await twistApiRequest.call(this, 'POST', '/threads/add', body); + } + //https://developer.twist.com/v3/#remove-thread + if (operation === 'delete') { + qs.id = this.getNodeParameter('threadId', i) as string; + + responseData = await twistApiRequest.call(this, 'POST', '/threads/remove', {}, qs); + } + //https://developer.twist.com/v3/#get-thread + if (operation === 'get') { + qs.id = this.getNodeParameter('threadId', i) as string; + + responseData = await twistApiRequest.call(this, 'GET', '/threads/getone', {}, qs); + } + //https://developer.twist.com/v3/#get-all-threads + if (operation === 'getAll') { + const channelId = this.getNodeParameter('channelId', i) as string; + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + const filters = this.getNodeParameter('filters', i) as IDataObject; + qs.channel_id = channelId; + + Object.assign(qs, filters); + if (!returnAll) { + qs.limit = this.getNodeParameter('limit', i) as number; + } + if (qs.older_than_ts) { + qs.older_than_ts = moment(qs.older_than_ts as string).unix(); + } + if (qs.newer_than_ts) { + qs.newer_than_ts = moment(qs.newer_than_ts as string).unix(); + } + + responseData = await twistApiRequest.call(this, 'GET', '/threads/get', {}, qs); + if (qs.as_ids) { + responseData = (responseData as number[]).map(id => ({ ID: id })); + } + } + //https://developer.twist.com/v3/#update-thread + if (operation === 'update') { + const threadId = this.getNodeParameter('threadId', i) as string; + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + const body: IDataObject = { + id: threadId, + }; + Object.assign(body, updateFields); + + if (body.actionsUi) { + const actions = (body.actionsUi as IDataObject).actionValues as IDataObject[]; + + if (actions) { + body.actions = actions; + delete body.actionsUi; + } + } + + if (body.binaryProperties) { + const binaryProperties = (body.binaryProperties as string).split(',') as string[]; + + const attachments: IDataObject[] = []; + + for (const binaryProperty of binaryProperties) { + + const item = items[i].binary as IBinaryKeyData; + + const binaryData = item[binaryProperty] as IBinaryData; + + if (binaryData === undefined) { + throw new Error(`No binary data property "${binaryProperty}" does not exists on item!`); + } + + attachments.push(await twistApiRequest.call( + this, + 'POST', + '/attachments/upload', + {}, + {}, + { + formData: { + file_name: { + value: Buffer.from(binaryData.data, BINARY_ENCODING), + options: { + filename: binaryData.fileName, + }, }, + attachment_id: uuid(), }, - attachment_id: uuid(), }, - }, - )); - } - - body.attachments = attachments; - } - - if (body.direct_mentions) { - const directMentions: string[] = []; - for (const directMention of body.direct_mentions as number[]) { - directMentions.push(`[name](twist-mention://${directMention})`); - } - body.content = `${directMentions.join(' ')} ${body.content}`; - } - - responseData = await twistApiRequest.call(this, 'POST', '/threads/add', body); - } - //https://developer.twist.com/v3/#remove-thread - if (operation === 'delete') { - qs.id = this.getNodeParameter('threadId', i) as string; - - responseData = await twistApiRequest.call(this, 'POST', '/threads/remove', {}, qs); - } - //https://developer.twist.com/v3/#get-thread - if (operation === 'get') { - qs.id = this.getNodeParameter('threadId', i) as string; - - responseData = await twistApiRequest.call(this, 'GET', '/threads/getone', {}, qs); - } - //https://developer.twist.com/v3/#get-all-threads - if (operation === 'getAll') { - const channelId = this.getNodeParameter('channelId', i) as string; - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - const filters = this.getNodeParameter('filters', i) as IDataObject; - qs.channel_id = channelId; - - Object.assign(qs, filters); - if (!returnAll) { - qs.limit = this.getNodeParameter('limit', i) as number; - } - if (qs.older_than_ts) { - qs.older_than_ts = moment(qs.older_than_ts as string).unix(); - } - if (qs.newer_than_ts) { - qs.newer_than_ts = moment(qs.newer_than_ts as string).unix(); - } - - responseData = await twistApiRequest.call(this, 'GET', '/threads/get', {}, qs); - if (qs.as_ids) { - responseData = (responseData as number[]).map(id => ({ ID: id })); - } - } - //https://developer.twist.com/v3/#update-thread - if (operation === 'update') { - const threadId = this.getNodeParameter('threadId', i) as string; - const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; - const body: IDataObject = { - id: threadId, - }; - Object.assign(body, updateFields); - - if (body.actionsUi) { - const actions = (body.actionsUi as IDataObject).actionValues as IDataObject[]; - - if (actions) { - body.actions = actions; - delete body.actionsUi; - } - } - - if (body.binaryProperties) { - const binaryProperties = (body.binaryProperties as string).split(',') as string[]; - - const attachments: IDataObject[] = []; - - for (const binaryProperty of binaryProperties) { - - const item = items[i].binary as IBinaryKeyData; - - const binaryData = item[binaryProperty] as IBinaryData; - - if (binaryData === undefined) { - throw new Error(`No binary data property "${binaryProperty}" does not exists on item!`); + )); } - attachments.push(await twistApiRequest.call( - this, - 'POST', - '/attachments/upload', - {}, - {}, - { - formData: { - file_name: { - value: Buffer.from(binaryData.data, BINARY_ENCODING), - options: { - filename: binaryData.fileName, - }, - }, - attachment_id: uuid(), - }, - }, - )); + body.attachments = attachments; } - body.attachments = attachments; - } - - if (body.direct_mentions) { - const directMentions: string[] = []; - for (const directMention of body.direct_mentions as number[]) { - directMentions.push(`[name](twist-mention://${directMention})`); + if (body.direct_mentions) { + const directMentions: string[] = []; + for (const directMention of body.direct_mentions as number[]) { + directMentions.push(`[name](twist-mention://${directMention})`); + } + body.content = `${directMentions.join(' ')} ${body.content}`; } - body.content = `${directMentions.join(' ')} ${body.content}`; - } - responseData = await twistApiRequest.call(this, 'POST', '/threads/update', body); + responseData = await twistApiRequest.call(this, 'POST', '/threads/update', body); + } } - } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else { - returnData.push(responseData as IDataObject); + if (Array.isArray(responseData)) { + returnData.push.apply(returnData, responseData as IDataObject[]); + } else { + returnData.push(responseData as IDataObject); + } + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } } return [this.helpers.returnJsonArray(returnData)]; diff --git a/packages/nodes-base/nodes/Twitter/Twitter.node.ts b/packages/nodes-base/nodes/Twitter/Twitter.node.ts index 3ade4eca82..7d8aab996e 100644 --- a/packages/nodes-base/nodes/Twitter/Twitter.node.ts +++ b/packages/nodes-base/nodes/Twitter/Twitter.node.ts @@ -110,173 +110,181 @@ export class Twitter implements INodeType { 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 === 'directMessage') { - //https://developer.twitter.com/en/docs/twitter-api/v1/direct-messages/sending-and-receiving/api-reference/new-event - if (operation === 'create') { - const userId = this.getNodeParameter('userId', i) as string; - const text = this.getNodeParameter('text', i) as string; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const body: IDataObject = { - type: 'message_create', - message_create: { - target: { - recipient_id: userId, + try { + if (resource === 'directMessage') { + //https://developer.twitter.com/en/docs/twitter-api/v1/direct-messages/sending-and-receiving/api-reference/new-event + if (operation === 'create') { + const userId = this.getNodeParameter('userId', i) as string; + const text = this.getNodeParameter('text', i) as string; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const body: IDataObject = { + type: 'message_create', + message_create: { + target: { + recipient_id: userId, + }, + message_data: { + text, + attachment: {}, + }, }, - message_data: { - text, - attachment: {}, - }, - }, - }; + }; - if (additionalFields.attachment) { - const attachment = additionalFields.attachment as string; + if (additionalFields.attachment) { + const attachment = additionalFields.attachment as string; - const attachmentProperties: string[] = attachment.split(',').map((propertyName) => { - return propertyName.trim(); - }); + const attachmentProperties: string[] = attachment.split(',').map((propertyName) => { + return propertyName.trim(); + }); - const medias = await uploadAttachments.call(this, attachmentProperties, items, i); - //@ts-ignore - body.message_create.message_data.attachment = { type: 'media', media: { id: medias[0].media_id_string } }; - } else { - //@ts-ignore - delete body.message_create.message_data.attachment; + const medias = await uploadAttachments.call(this, attachmentProperties, items, i); + //@ts-ignore + body.message_create.message_data.attachment = { type: 'media', media: { id: medias[0].media_id_string } }; + } else { + //@ts-ignore + delete body.message_create.message_data.attachment; + } + + responseData = await twitterApiRequest.call(this, 'POST', '/direct_messages/events/new.json', { event: body }); + + responseData = responseData.event; } - - responseData = await twitterApiRequest.call(this, 'POST', '/direct_messages/events/new.json', { event: body }); - - responseData = responseData.event; } - } - if (resource === 'tweet') { - // https://developer.twitter.com/en/docs/tweets/post-and-engage/api-reference/post-statuses-update - if (operation === 'create') { - const text = this.getNodeParameter('text', i) as string; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const body: ITweet = { - status: text, - }; + if (resource === 'tweet') { + // https://developer.twitter.com/en/docs/tweets/post-and-engage/api-reference/post-statuses-update + if (operation === 'create') { + const text = this.getNodeParameter('text', i) as string; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const body: ITweet = { + status: text, + }; - if (additionalFields.inReplyToStatusId) { - body.in_reply_to_status_id = additionalFields.inReplyToStatusId as string; - body.auto_populate_reply_metadata = true; + if (additionalFields.inReplyToStatusId) { + body.in_reply_to_status_id = additionalFields.inReplyToStatusId as string; + body.auto_populate_reply_metadata = true; + } + + if (additionalFields.attachments) { + + const attachments = additionalFields.attachments as string; + + const attachmentProperties: string[] = attachments.split(',').map((propertyName) => { + return propertyName.trim(); + }); + + const medias = await uploadAttachments.call(this, attachmentProperties, items, i); + + body.media_ids = (medias as IDataObject[]).map((media: IDataObject) => media.media_id_string).join(','); + } + + if (additionalFields.possiblySensitive) { + body.possibly_sensitive = additionalFields.possiblySensitive as boolean; + } + + if (additionalFields.displayCoordinates) { + body.display_coordinates = additionalFields.displayCoordinates as boolean; + } + + if (additionalFields.locationFieldsUi) { + const locationUi = additionalFields.locationFieldsUi as IDataObject; + if (locationUi.locationFieldsValues) { + const values = locationUi.locationFieldsValues as IDataObject; + body.lat = parseFloat(values.latitude as string); + body.long = parseFloat(values.longitude as string); + } + } + + responseData = await twitterApiRequest.call(this, 'POST', '/statuses/update.json', {}, body as unknown as IDataObject); } + // https://developer.twitter.com/en/docs/twitter-api/v1/tweets/post-and-engage/api-reference/post-statuses-destroy-id + if (operation === 'delete') { + const tweetId = this.getNodeParameter('tweetId', i) as string; - if (additionalFields.attachments) { - - const attachments = additionalFields.attachments as string; - - const attachmentProperties: string[] = attachments.split(',').map((propertyName) => { - return propertyName.trim(); - }); - - const medias = await uploadAttachments.call(this, attachmentProperties, items, i); - - body.media_ids = (medias as IDataObject[]).map((media: IDataObject) => media.media_id_string).join(','); + responseData = await twitterApiRequest.call(this, 'POST', `/statuses/destroy/${tweetId}.json`, {}, {}); } + // https://developer.twitter.com/en/docs/tweets/search/api-reference/get-search-tweets + if (operation === 'search') { + const q = this.getNodeParameter('searchText', i) as string; + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const qs: IDataObject = { + q, + }; - if (additionalFields.possiblySensitive) { - body.possibly_sensitive = additionalFields.possiblySensitive as boolean; - } + if (additionalFields.includeEntities) { + qs.include_entities = additionalFields.includeEntities as boolean; + } - if (additionalFields.displayCoordinates) { - body.display_coordinates = additionalFields.displayCoordinates as boolean; - } + if (additionalFields.resultType) { + qs.response_type = additionalFields.resultType as string; + } - if (additionalFields.locationFieldsUi) { - const locationUi = additionalFields.locationFieldsUi as IDataObject; - if (locationUi.locationFieldsValues) { - const values = locationUi.locationFieldsValues as IDataObject; - body.lat = parseFloat(values.latitude as string); - body.long = parseFloat(values.longitude as string); + if (additionalFields.until) { + qs.until = additionalFields.until as string; + } + + if (additionalFields.lang) { + qs.lang = additionalFields.lang as string; + } + + if (additionalFields.locationFieldsUi) { + const locationUi = additionalFields.locationFieldsUi as IDataObject; + if (locationUi.locationFieldsValues) { + const values = locationUi.locationFieldsValues as IDataObject; + qs.geocode = `${values.latitude as string},${values.longitude as string},${values.distance}${values.radius}`; + } + } + + if (returnAll) { + responseData = await twitterApiRequestAllItems.call(this, 'statuses', 'GET', '/search/tweets.json', {}, qs); + } else { + qs.count = this.getNodeParameter('limit', 0) as number; + responseData = await twitterApiRequest.call(this, 'GET', '/search/tweets.json', {}, qs); + responseData = responseData.statuses; } } + //https://developer.twitter.com/en/docs/twitter-api/v1/tweets/post-and-engage/api-reference/post-favorites-create + if (operation === 'like') { + const tweetId = this.getNodeParameter('tweetId', i) as string; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - responseData = await twitterApiRequest.call(this, 'POST', '/statuses/update.json', {}, body as unknown as IDataObject); - } - // https://developer.twitter.com/en/docs/twitter-api/v1/tweets/post-and-engage/api-reference/post-statuses-destroy-id - if (operation === 'delete') { - const tweetId = this.getNodeParameter('tweetId', i) as string; + const qs: IDataObject = { + id: tweetId, + }; - responseData = await twitterApiRequest.call(this, 'POST', `/statuses/destroy/${tweetId}.json`, {}, {}); - } - // https://developer.twitter.com/en/docs/tweets/search/api-reference/get-search-tweets - if (operation === 'search') { - const q = this.getNodeParameter('searchText', i) as string; - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const qs: IDataObject = { - q, - }; - - if (additionalFields.includeEntities) { - qs.include_entities = additionalFields.includeEntities as boolean; - } - - if (additionalFields.resultType) { - qs.response_type = additionalFields.resultType as string; - } - - if (additionalFields.until) { - qs.until = additionalFields.until as string; - } - - if (additionalFields.lang) { - qs.lang = additionalFields.lang as string; - } - - if (additionalFields.locationFieldsUi) { - const locationUi = additionalFields.locationFieldsUi as IDataObject; - if (locationUi.locationFieldsValues) { - const values = locationUi.locationFieldsValues as IDataObject; - qs.geocode = `${values.latitude as string},${values.longitude as string},${values.distance}${values.radius}`; + if (additionalFields.includeEntities) { + qs.include_entities = additionalFields.includeEntities as boolean; } - } - if (returnAll) { - responseData = await twitterApiRequestAllItems.call(this, 'statuses', 'GET', '/search/tweets.json', {}, qs); - } else { - qs.count = this.getNodeParameter('limit', 0) as number; - responseData = await twitterApiRequest.call(this, 'GET', '/search/tweets.json', {}, qs); - responseData = responseData.statuses; + responseData = await twitterApiRequest.call(this, 'POST', '/favorites/create.json', {}, qs); + } + //https://developer.twitter.com/en/docs/twitter-api/v1/tweets/post-and-engage/api-reference/post-statuses-retweet-id + if (operation === 'retweet') { + const tweetId = this.getNodeParameter('tweetId', i) as string; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + + const qs: IDataObject = { + id: tweetId, + }; + + if (additionalFields.trimUser) { + qs.trim_user = additionalFields.trimUser as boolean; + } + + responseData = await twitterApiRequest.call(this, 'POST', `/statuses/retweet/${tweetId}.json`, {}, qs); } } - //https://developer.twitter.com/en/docs/twitter-api/v1/tweets/post-and-engage/api-reference/post-favorites-create - if (operation === 'like') { - const tweetId = this.getNodeParameter('tweetId', i) as string; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - - const qs: IDataObject = { - id: tweetId, - }; - - if (additionalFields.includeEntities) { - qs.include_entities = additionalFields.includeEntities as boolean; - } - - responseData = await twitterApiRequest.call(this, 'POST', '/favorites/create.json', {}, qs); + if (Array.isArray(responseData)) { + returnData.push.apply(returnData, responseData as IDataObject[]); + } else if (responseData !== undefined) { + returnData.push(responseData as IDataObject); } - //https://developer.twitter.com/en/docs/twitter-api/v1/tweets/post-and-engage/api-reference/post-statuses-retweet-id - if (operation === 'retweet') { - const tweetId = this.getNodeParameter('tweetId', i) as string; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - - const qs: IDataObject = { - id: tweetId, - }; - - if (additionalFields.trimUser) { - qs.trim_user = additionalFields.trimUser as boolean; - } - - responseData = await twitterApiRequest.call(this, 'POST', `/statuses/retweet/${tweetId}.json`, {}, qs); + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; } - } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else if (responseData !== undefined) { - returnData.push(responseData as IDataObject); + throw error; } } return [this.helpers.returnJsonArray(returnData)]; diff --git a/packages/nodes-base/nodes/UProc/UProc.node.ts b/packages/nodes-base/nodes/UProc/UProc.node.ts index 8721f9b166..33428d4e51 100644 --- a/packages/nodes-base/nodes/UProc/UProc.node.ts +++ b/packages/nodes-base/nodes/UProc/UProc.node.ts @@ -107,34 +107,42 @@ export class UProc implements INodeType { const requestPromises = []; for (let i = 0; i < length; i++) { - const toolKey = tool.replace(/([A-Z]+)/g, '-$1').toLowerCase(); - const body: LooseObject = { - processor: toolKey, - params: {}, - }; + try { + const toolKey = tool.replace(/([A-Z]+)/g, '-$1').toLowerCase(); + const body: LooseObject = { + processor: toolKey, + params: {}, + }; - fields.forEach((field) => { - if (field && field.length) { - const data = this.getNodeParameter(field, i) as string; - body.params[field] = data + ''; + fields.forEach((field) => { + if (field && field.length) { + const data = this.getNodeParameter(field, i) as string; + body.params[field] = data + ''; + } + }); + + if (dataWebhook && dataWebhook.length) { + body.callback = {}; } - }); - if (dataWebhook && dataWebhook.length) { - body.callback = {}; - } + if (dataWebhook && dataWebhook.length) { + body.callback.data = dataWebhook; + } - if (dataWebhook && dataWebhook.length) { - body.callback.data = dataWebhook; - } + //Change to multiple requests + responseData = await uprocApiRequest.call(this, 'POST', body); - //Change to multiple requests - responseData = await uprocApiRequest.call(this, 'POST', body); - - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else { - returnData.push(responseData as IDataObject); + if (Array.isArray(responseData)) { + returnData.push.apply(returnData, responseData as IDataObject[]); + } else { + returnData.push(responseData as IDataObject); + } + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } } return [this.helpers.returnJsonArray(returnData)]; diff --git a/packages/nodes-base/nodes/Uplead/Uplead.node.ts b/packages/nodes-base/nodes/Uplead/Uplead.node.ts index bd280ad35f..821d818931 100644 --- a/packages/nodes-base/nodes/Uplead/Uplead.node.ts +++ b/packages/nodes-base/nodes/Uplead/Uplead.node.ts @@ -76,46 +76,54 @@ export class Uplead implements INodeType { 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 === 'person') { - if (operation === 'enrich') { - const email = this.getNodeParameter('email', i) as string; - const firstname = this.getNodeParameter('firstname', i) as string; - const lastname = this.getNodeParameter('lastname', i) as string; - const domain = this.getNodeParameter('domain', i) as string; - if (email) { - qs.email = email; + try { + if (resource === 'person') { + if (operation === 'enrich') { + const email = this.getNodeParameter('email', i) as string; + const firstname = this.getNodeParameter('firstname', i) as string; + const lastname = this.getNodeParameter('lastname', i) as string; + const domain = this.getNodeParameter('domain', i) as string; + if (email) { + qs.email = email; + } + if (firstname) { + qs.first_name = firstname; + } + if (lastname) { + qs.last_name = lastname; + } + if (domain) { + qs.domain = domain; + } + responseData = await upleadApiRequest.call(this, 'GET', '/person-search', {}, qs); } - if (firstname) { - qs.first_name = firstname; - } - if (lastname) { - qs.last_name = lastname; - } - if (domain) { - qs.domain = domain; - } - responseData = await upleadApiRequest.call(this, 'GET', '/person-search', {}, qs); } - } - if (resource === 'company') { - if (operation === 'enrich') { - const domain = this.getNodeParameter('domain', i) as string; - const company = this.getNodeParameter('company', i) as string; - if (domain) { - qs.domain = domain; + if (resource === 'company') { + if (operation === 'enrich') { + const domain = this.getNodeParameter('domain', i) as string; + const company = this.getNodeParameter('company', i) as string; + if (domain) { + qs.domain = domain; + } + if (company) { + qs.company = company; + } + responseData = await upleadApiRequest.call(this, 'GET', '/company-search', {}, qs); } - if (company) { - qs.company = company; + } + if (Array.isArray(responseData.data)) { + returnData.push.apply(returnData, responseData.data as IDataObject[]); + } else { + if (responseData.data !== null) { + returnData.push(responseData.data as IDataObject); } - responseData = await upleadApiRequest.call(this, 'GET', '/company-search', {}, qs); } - } - if (Array.isArray(responseData.data)) { - returnData.push.apply(returnData, responseData.data as IDataObject[]); - } else { - if (responseData.data !== null) { - returnData.push(responseData.data as IDataObject); + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; } + throw error; } } return [this.helpers.returnJsonArray(returnData)]; diff --git a/packages/nodes-base/nodes/Vero/Vero.node.ts b/packages/nodes-base/nodes/Vero/Vero.node.ts index aba898064d..d9335c90d0 100644 --- a/packages/nodes-base/nodes/Vero/Vero.node.ts +++ b/packages/nodes-base/nodes/Vero/Vero.node.ts @@ -76,157 +76,165 @@ export class Vero implements INodeType { const length = items.length as unknown as number; 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; - //https://developers.getvero.com/?bash#users - if (resource === 'user') { - //https://developers.getvero.com/?bash#users-identify - if (operation === 'create') { - const id = this.getNodeParameter('id', i) as string; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const jsonActive = this.getNodeParameter('jsonParameters', i) as boolean; - const body = { - id, - }; - if (additionalFields.email) { - // @ts-ignore - body.email = additionalFields.email as string; - } - if (!jsonActive) { - const dataAttributesValues = (this.getNodeParameter('dataAttributesUi', i) as IDataObject).dataAttributesValues as IDataObject[]; - if (dataAttributesValues) { - const dataAttributes = {}; - for (let i = 0; i < dataAttributesValues.length; i++) { + try { + const resource = this.getNodeParameter('resource', 0) as string; + const operation = this.getNodeParameter('operation', 0) as string; + //https://developers.getvero.com/?bash#users + if (resource === 'user') { + //https://developers.getvero.com/?bash#users-identify + if (operation === 'create') { + const id = this.getNodeParameter('id', i) as string; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const jsonActive = this.getNodeParameter('jsonParameters', i) as boolean; + const body = { + id, + }; + if (additionalFields.email) { + // @ts-ignore + body.email = additionalFields.email as string; + } + if (!jsonActive) { + const dataAttributesValues = (this.getNodeParameter('dataAttributesUi', i) as IDataObject).dataAttributesValues as IDataObject[]; + if (dataAttributesValues) { + const dataAttributes = {}; + for (let i = 0; i < dataAttributesValues.length; i++) { + // @ts-ignore + dataAttributes[dataAttributesValues[i].key] = dataAttributesValues[i].value; + // @ts-ignore + body.data = dataAttributes; + } + } + } else { + const dataAttributesJson = validateJSON(this.getNodeParameter('dataAttributesJson', i) as string); + if (dataAttributesJson) { // @ts-ignore - dataAttributes[dataAttributesValues[i].key] = dataAttributesValues[i].value; - // @ts-ignore - body.data = dataAttributes; + body.data = dataAttributesJson; } } - } else { - const dataAttributesJson = validateJSON(this.getNodeParameter('dataAttributesJson', i) as string); - if (dataAttributesJson) { - // @ts-ignore - body.data = dataAttributesJson; + try { + responseData = await veroApiRequest.call(this, 'POST', '/users/track', body); + } catch (error) { + throw new NodeApiError(this.getNode(), error); } } - try { - responseData = await veroApiRequest.call(this, 'POST', '/users/track', body); - } catch (error) { - throw new NodeApiError(this.getNode(), error); + //https://developers.getvero.com/?bash#users-alias + if (operation === 'alias') { + const id = this.getNodeParameter('id', i) as string; + const newId = this.getNodeParameter('newId', i) as string; + const body = { + id, + new_id: newId, + }; + try { + responseData = await veroApiRequest.call(this, 'PUT', '/users/reidentify', body); + } catch (error) { + throw new NodeApiError(this.getNode(), error); + } + } + //https://developers.getvero.com/?bash#users-unsubscribe + //https://developers.getvero.com/?bash#users-resubscribe + //https://developers.getvero.com/?bash#users-delete + if (operation === 'unsubscribe' || + operation === 'resubscribe' || + operation === 'delete') { + const id = this.getNodeParameter('id', i) as string; + const body = { + id, + }; + try { + responseData = await veroApiRequest.call(this, 'POST', `/users/${operation}`, body); + } catch (error) { + throw new NodeApiError(this.getNode(), error); + } + } + //https://developers.getvero.com/?bash#tags-add + //https://developers.getvero.com/?bash#tags-remove + if (operation === 'addTags' || + operation === 'removeTags') { + const id = this.getNodeParameter('id', i) as string; + const tags = (this.getNodeParameter('tags', i) as string).split(',') as string[]; + const body = { + id, + }; + if (operation === 'addTags') { + // @ts-ignore + body.add = JSON.stringify(tags); + } + if (operation === 'removeTags') { + // @ts-ignore + body.remove = JSON.stringify(tags); + } + try { + responseData = await veroApiRequest.call(this, 'PUT', '/users/tags/edit', body); + } catch (error) { + throw new NodeApiError(this.getNode(), error); + } } } - //https://developers.getvero.com/?bash#users-alias - if (operation === 'alias') { - const id = this.getNodeParameter('id', i) as string; - const newId = this.getNodeParameter('newId', i) as string; - const body = { - id, - new_id: newId, - }; - try { - responseData = await veroApiRequest.call(this, 'PUT', '/users/reidentify', body); - } catch (error) { - throw new NodeApiError(this.getNode(), error); - } - } - //https://developers.getvero.com/?bash#users-unsubscribe - //https://developers.getvero.com/?bash#users-resubscribe - //https://developers.getvero.com/?bash#users-delete - if (operation === 'unsubscribe' || - operation === 'resubscribe' || - operation === 'delete') { - const id = this.getNodeParameter('id', i) as string; - const body = { - id, - }; - try { - responseData = await veroApiRequest.call(this, 'POST', `/users/${operation}`, body); - } catch (error) { - throw new NodeApiError(this.getNode(), error); - } - } - //https://developers.getvero.com/?bash#tags-add - //https://developers.getvero.com/?bash#tags-remove - if (operation === 'addTags' || - operation === 'removeTags') { - const id = this.getNodeParameter('id', i) as string; - const tags = (this.getNodeParameter('tags', i) as string).split(',') as string[]; - const body = { - id, - }; - if (operation === 'addTags') { - // @ts-ignore - body.add = JSON.stringify(tags); - } - if (operation === 'removeTags') { - // @ts-ignore - body.remove = JSON.stringify(tags); - } - try { - responseData = await veroApiRequest.call(this, 'PUT', '/users/tags/edit', body); - } catch (error) { - throw new NodeApiError(this.getNode(), error); - } - } - } - //https://developers.getvero.com/?bash#events - if (resource === 'event') { - //https://developers.getvero.com/?bash#events-track - if (operation === 'track') { - const id = this.getNodeParameter('id', i) as string; - const email = this.getNodeParameter('email', i) as string; - const eventName = this.getNodeParameter('eventName', i) as string; - const jsonActive = this.getNodeParameter('jsonParameters', i) as boolean; - const body = { - identity: { id, email }, - event_name: eventName, - email, - }; - if (!jsonActive) { - const dataAttributesValues = (this.getNodeParameter('dataAttributesUi', i) as IDataObject).dataAttributesValues as IDataObject[]; - if (dataAttributesValues) { - const dataAttributes = {}; - for (let i = 0; i < dataAttributesValues.length; i++) { + //https://developers.getvero.com/?bash#events + if (resource === 'event') { + //https://developers.getvero.com/?bash#events-track + if (operation === 'track') { + const id = this.getNodeParameter('id', i) as string; + const email = this.getNodeParameter('email', i) as string; + const eventName = this.getNodeParameter('eventName', i) as string; + const jsonActive = this.getNodeParameter('jsonParameters', i) as boolean; + const body = { + identity: { id, email }, + event_name: eventName, + email, + }; + if (!jsonActive) { + const dataAttributesValues = (this.getNodeParameter('dataAttributesUi', i) as IDataObject).dataAttributesValues as IDataObject[]; + if (dataAttributesValues) { + const dataAttributes = {}; + for (let i = 0; i < dataAttributesValues.length; i++) { + // @ts-ignore + dataAttributes[dataAttributesValues[i].key] = dataAttributesValues[i].value; + // @ts-ignore + body.data = JSON.stringify(dataAttributes); + } + } + const extraAttributesValues = (this.getNodeParameter('extraAttributesUi', i) as IDataObject).extraAttributesValues as IDataObject[]; + if (extraAttributesValues) { + const extraAttributes = {}; + for (let i = 0; i < extraAttributesValues.length; i++) { + // @ts-ignore + extraAttributes[extraAttributesValues[i].key] = extraAttributesValues[i].value; + // @ts-ignore + body.extras = JSON.stringify(extraAttributes); + } + } + } else { + const dataAttributesJson = validateJSON(this.getNodeParameter('dataAttributesJson', i) as string); + if (dataAttributesJson) { // @ts-ignore - dataAttributes[dataAttributesValues[i].key] = dataAttributesValues[i].value; + body.data = JSON.stringify(dataAttributesJson); + } + const extraAttributesJson = validateJSON(this.getNodeParameter('extraAttributesJson', i) as string); + if (extraAttributesJson) { // @ts-ignore - body.data = JSON.stringify(dataAttributes); + body.extras = JSON.stringify(extraAttributesJson); } } - const extraAttributesValues = (this.getNodeParameter('extraAttributesUi', i) as IDataObject).extraAttributesValues as IDataObject[]; - if (extraAttributesValues) { - const extraAttributes = {}; - for (let i = 0; i < extraAttributesValues.length; i++) { - // @ts-ignore - extraAttributes[extraAttributesValues[i].key] = extraAttributesValues[i].value; - // @ts-ignore - body.extras = JSON.stringify(extraAttributes); - } + try { + responseData = await veroApiRequest.call(this, 'POST', '/events/track', body); + } catch (error) { + throw new NodeApiError(this.getNode(), error); } - } else { - const dataAttributesJson = validateJSON(this.getNodeParameter('dataAttributesJson', i) as string); - if (dataAttributesJson) { - // @ts-ignore - body.data = JSON.stringify(dataAttributesJson); - } - const extraAttributesJson = validateJSON(this.getNodeParameter('extraAttributesJson', i) as string); - if (extraAttributesJson) { - // @ts-ignore - body.extras = JSON.stringify(extraAttributesJson); - } - } - try { - responseData = await veroApiRequest.call(this, 'POST', '/events/track', body); - } catch (error) { - throw new NodeApiError(this.getNode(), error); } } - } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else { - returnData.push(responseData as IDataObject); + if (Array.isArray(responseData)) { + returnData.push.apply(returnData, responseData as IDataObject[]); + } else { + returnData.push(responseData as IDataObject); + } + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } } return [this.helpers.returnJsonArray(returnData)]; diff --git a/packages/nodes-base/nodes/Vonage/Vonage.node.ts b/packages/nodes-base/nodes/Vonage/Vonage.node.ts index d93f52812a..0bf87c23a8 100644 --- a/packages/nodes-base/nodes/Vonage/Vonage.node.ts +++ b/packages/nodes-base/nodes/Vonage/Vonage.node.ts @@ -425,84 +425,91 @@ export class Vonage implements INodeType { const resource = this.getNodeParameter('resource', 0) as string; const operation = this.getNodeParameter('operation', 0) as string; for (let i = 0; i < length; i++) { + try { + if (resource === 'sms') { - if (resource === 'sms') { + if (operation === 'send') { - if (operation === 'send') { + const from = this.getNodeParameter('from', i) as string; - const from = this.getNodeParameter('from', i) as string; + const to = this.getNodeParameter('to', i) as string; - const to = this.getNodeParameter('to', i) as string; + const type = this.getNodeParameter('type', i, 'text') as string; - const type = this.getNodeParameter('type', i, 'text') as string; + const body: IDataObject = { + from, + to, + type, + }; - const body: IDataObject = { - from, - to, - type, - }; + if (type === 'text' || type === 'unicode') { + const message = this.getNodeParameter('message', i) as string; - if (type === 'text' || type === 'unicode') { - const message = this.getNodeParameter('message', i) as string; + body.text = message; + } - body.text = message; + if (type === 'binary') { + const data = this.getNodeParameter('body', i) as string; + + const udh = this.getNodeParameter('udh', i) as string; + + body.udh = udh; + + body.body = data; + } + + if (type === 'wappush') { + const title = this.getNodeParameter('title', i) as string; + + const url = this.getNodeParameter('url', i) as string; + + const validity = this.getNodeParameter('validity', i) as number; + + body.title = title; + + body.url = url; + + body.validity = validity * 60000; + } + + if (type === 'vcard') { + const vcard = this.getNodeParameter('vcard', i) as string; + + body.vcard = vcard; + } + + if (type === 'vcal') { + const vcal = this.getNodeParameter('vcal', i) as string; + + body.vcal = vcal; + } + + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + + Object.assign(body, additionalFields); + + if (body.ttl) { + // transform minutes to milliseconds + body.ttl = (body.ttl as number) * 60000; + } + + responseData = await vonageApiRequest.call(this, 'POST', '/sms/json', body); + + responseData = responseData.messages; } - - if (type === 'binary') { - const data = this.getNodeParameter('body', i) as string; - - const udh = this.getNodeParameter('udh', i) as string; - - body.udh = udh; - - body.body = data; - } - - if (type === 'wappush') { - const title = this.getNodeParameter('title', i) as string; - - const url = this.getNodeParameter('url', i) as string; - - const validity = this.getNodeParameter('validity', i) as number; - - body.title = title; - - body.url = url; - - body.validity = validity * 60000; - } - - if (type === 'vcard') { - const vcard = this.getNodeParameter('vcard', i) as string; - - body.vcard = vcard; - } - - if (type === 'vcal') { - const vcal = this.getNodeParameter('vcal', i) as string; - - body.vcal = vcal; - } - - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - - Object.assign(body, additionalFields); - - if (body.ttl) { - // transform minutes to milliseconds - body.ttl = (body.ttl as number) * 60000; - } - - responseData = await vonageApiRequest.call(this, 'POST', '/sms/json', body); - - responseData = responseData.messages; } + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; + } + if (Array.isArray(responseData)) { + returnData.push.apply(returnData, responseData as IDataObject[]); + } else if (responseData !== undefined) { + returnData.push(responseData as IDataObject); } - } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else if (responseData !== undefined) { - returnData.push(responseData as IDataObject); } return [this.helpers.returnJsonArray(returnData)]; } diff --git a/packages/nodes-base/nodes/Webflow/Webflow.node.ts b/packages/nodes-base/nodes/Webflow/Webflow.node.ts index 8b71950d3f..42483520e8 100644 --- a/packages/nodes-base/nodes/Webflow/Webflow.node.ts +++ b/packages/nodes-base/nodes/Webflow/Webflow.node.ts @@ -147,114 +147,122 @@ export class Webflow implements INodeType { for (let i = 0; i < items.length; i++) { - if (resource === 'item') { + try { + if (resource === 'item') { - // ********************************************************************* - // item - // ********************************************************************* + // ********************************************************************* + // item + // ********************************************************************* - // https://developers.webflow.com/#item-model + // https://developers.webflow.com/#item-model - if (operation === 'create') { + if (operation === 'create') { - // ---------------------------------- - // item: create - // ---------------------------------- + // ---------------------------------- + // item: create + // ---------------------------------- - // https://developers.webflow.com/#create-new-collection-item + // https://developers.webflow.com/#create-new-collection-item - const collectionId = this.getNodeParameter('collectionId', i) as string; + const collectionId = this.getNodeParameter('collectionId', i) as string; - const properties = this.getNodeParameter('fieldsUi.fieldValues', i, []) as IDataObject[]; + const properties = this.getNodeParameter('fieldsUi.fieldValues', i, []) as IDataObject[]; - const live = this.getNodeParameter('live', i) as boolean; + const live = this.getNodeParameter('live', i) as boolean; - const fields = {} as IDataObject; + const fields = {} as IDataObject; - properties.forEach(data => (fields[data.fieldId as string] = data.fieldValue)); + properties.forEach(data => (fields[data.fieldId as string] = data.fieldValue)); - const body: IDataObject = { - fields, - }; + const body: IDataObject = { + fields, + }; - responseData = await webflowApiRequest.call(this, 'POST', `/collections/${collectionId}/items`, body, { live }); + responseData = await webflowApiRequest.call(this, 'POST', `/collections/${collectionId}/items`, body, { live }); - } else if (operation === 'delete') { + } else if (operation === 'delete') { - // ---------------------------------- - // item: delete - // ---------------------------------- + // ---------------------------------- + // item: delete + // ---------------------------------- - // https://developers.webflow.com/#remove-collection-item + // https://developers.webflow.com/#remove-collection-item - const collectionId = this.getNodeParameter('collectionId', i) as string; - const itemId = this.getNodeParameter('itemId', i) as string; - responseData = await webflowApiRequest.call(this, 'DELETE', `/collections/${collectionId}/items/${itemId}`); + const collectionId = this.getNodeParameter('collectionId', i) as string; + const itemId = this.getNodeParameter('itemId', i) as string; + responseData = await webflowApiRequest.call(this, 'DELETE', `/collections/${collectionId}/items/${itemId}`); - } else if (operation === 'get') { + } else if (operation === 'get') { - // ---------------------------------- - // item: get - // ---------------------------------- + // ---------------------------------- + // item: get + // ---------------------------------- - // https://developers.webflow.com/#get-single-item + // https://developers.webflow.com/#get-single-item - const collectionId = this.getNodeParameter('collectionId', i) as string; - const itemId = this.getNodeParameter('itemId', i) as string; - responseData = await webflowApiRequest.call(this, 'GET', `/collections/${collectionId}/items/${itemId}`); - responseData = responseData.items; - - } else if (operation === 'getAll') { - - // ---------------------------------- - // item: getAll - // ---------------------------------- - - // https://developers.webflow.com/#get-all-items-for-a-collection - - const returnAll = this.getNodeParameter('returnAll', 0) as boolean; - const collectionId = this.getNodeParameter('collectionId', i) as string; - const qs: IDataObject = {}; - - if (returnAll === true) { - responseData = await webflowApiRequestAllItems.call(this, 'GET', `/collections/${collectionId}/items`, {}, qs); - } else { - qs.limit = this.getNodeParameter('limit', 0) as number; - responseData = await webflowApiRequest.call(this, 'GET', `/collections/${collectionId}/items`, {}, qs); + const collectionId = this.getNodeParameter('collectionId', i) as string; + const itemId = this.getNodeParameter('itemId', i) as string; + responseData = await webflowApiRequest.call(this, 'GET', `/collections/${collectionId}/items/${itemId}`); responseData = responseData.items; + + } else if (operation === 'getAll') { + + // ---------------------------------- + // item: getAll + // ---------------------------------- + + // https://developers.webflow.com/#get-all-items-for-a-collection + + const returnAll = this.getNodeParameter('returnAll', 0) as boolean; + const collectionId = this.getNodeParameter('collectionId', i) as string; + const qs: IDataObject = {}; + + if (returnAll === true) { + responseData = await webflowApiRequestAllItems.call(this, 'GET', `/collections/${collectionId}/items`, {}, qs); + } else { + qs.limit = this.getNodeParameter('limit', 0) as number; + responseData = await webflowApiRequest.call(this, 'GET', `/collections/${collectionId}/items`, {}, qs); + responseData = responseData.items; + } + + } else if (operation === 'update') { + + // ---------------------------------- + // item: update + // ---------------------------------- + + // https://developers.webflow.com/#update-collection-item + + const collectionId = this.getNodeParameter('collectionId', i) as string; + + const itemId = this.getNodeParameter('itemId', i) as string; + + const properties = this.getNodeParameter('fieldsUi.fieldValues', i, []) as IDataObject[]; + + const live = this.getNodeParameter('live', i) as boolean; + + const fields = {} as IDataObject; + + properties.forEach(data => (fields[data.fieldId as string] = data.fieldValue)); + + const body: IDataObject = { + fields, + }; + + responseData = await webflowApiRequest.call(this, 'PUT', `/collections/${collectionId}/items/${itemId}`, body, { live }); } - - } else if (operation === 'update') { - - // ---------------------------------- - // item: update - // ---------------------------------- - - // https://developers.webflow.com/#update-collection-item - - const collectionId = this.getNodeParameter('collectionId', i) as string; - - const itemId = this.getNodeParameter('itemId', i) as string; - - const properties = this.getNodeParameter('fieldsUi.fieldValues', i, []) as IDataObject[]; - - const live = this.getNodeParameter('live', i) as boolean; - - const fields = {} as IDataObject; - - properties.forEach(data => (fields[data.fieldId as string] = data.fieldValue)); - - const body: IDataObject = { - fields, - }; - - responseData = await webflowApiRequest.call(this, 'PUT', `/collections/${collectionId}/items/${itemId}`, body, { live }); } - } - Array.isArray(responseData) - ? returnData.push(...responseData) - : returnData.push(responseData); + Array.isArray(responseData) + ? returnData.push(...responseData) + : returnData.push(responseData); + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; + } } return [this.helpers.returnJsonArray(returnData)]; diff --git a/packages/nodes-base/nodes/Wekan/Wekan.node.ts b/packages/nodes-base/nodes/Wekan/Wekan.node.ts index ced73ee665..016ee4ebb3 100644 --- a/packages/nodes-base/nodes/Wekan/Wekan.node.ts +++ b/packages/nodes-base/nodes/Wekan/Wekan.node.ts @@ -249,437 +249,445 @@ export class Wekan implements INodeType { let endpoint: string; for (let i = 0; i < items.length; i++) { - requestMethod = 'GET'; - endpoint = ''; - body = {}; - qs = {}; + try { + requestMethod = 'GET'; + endpoint = ''; + body = {}; + qs = {}; - if (resource === 'board') { + if (resource === 'board') { - if (operation === 'create') { - // ---------------------------------- - // create - // ---------------------------------- + if (operation === 'create') { + // ---------------------------------- + // create + // ---------------------------------- - requestMethod = 'POST'; - endpoint = 'boards'; + requestMethod = 'POST'; + endpoint = 'boards'; - body.title = this.getNodeParameter('title', i) as string; - body.owner = this.getNodeParameter('owner', i) as string; + body.title = this.getNodeParameter('title', i) as string; + body.owner = this.getNodeParameter('owner', i) as string; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - Object.assign(body, additionalFields); + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + Object.assign(body, additionalFields); - } else if (operation === 'delete') { - // ---------------------------------- - // delete - // ---------------------------------- + } else if (operation === 'delete') { + // ---------------------------------- + // delete + // ---------------------------------- - requestMethod = 'DELETE'; + requestMethod = 'DELETE'; - const boardId = this.getNodeParameter('boardId', i) as string; + const boardId = this.getNodeParameter('boardId', i) as string; - endpoint = `boards/${boardId}`; + endpoint = `boards/${boardId}`; - } else if (operation === 'get') { - // ---------------------------------- - // get - // ---------------------------------- + } else if (operation === 'get') { + // ---------------------------------- + // get + // ---------------------------------- - requestMethod = 'GET'; + requestMethod = 'GET'; - const boardId = this.getNodeParameter('boardId', i) as string; + const boardId = this.getNodeParameter('boardId', i) as string; - endpoint = `boards/${boardId}`; + endpoint = `boards/${boardId}`; - } else if (operation === 'getAll') { - // ---------------------------------- - // getAll - // ---------------------------------- + } else if (operation === 'getAll') { + // ---------------------------------- + // getAll + // ---------------------------------- - requestMethod = 'GET'; + requestMethod = 'GET'; - const userId = this.getNodeParameter('IdUser', i) as string; + const userId = this.getNodeParameter('IdUser', i) as string; - returnAll = this.getNodeParameter('returnAll', i) as boolean; + returnAll = this.getNodeParameter('returnAll', i) as boolean; - endpoint = `users/${userId}/boards`; + endpoint = `users/${userId}/boards`; - } else { - throw new NodeOperationError(this.getNode(), `The operation "${operation}" is not known!`); - } + } else { + throw new NodeOperationError(this.getNode(), `The operation "${operation}" is not known!`); + } - } else if (resource === 'card') { + } else if (resource === 'card') { - if (operation === 'create') { - // ---------------------------------- - // create - // ---------------------------------- + if (operation === 'create') { + // ---------------------------------- + // create + // ---------------------------------- - requestMethod = 'POST'; + requestMethod = 'POST'; - const boardId = this.getNodeParameter('boardId', i) as string; - const listId = this.getNodeParameter('listId', i) as string; - - endpoint = `boards/${boardId}/lists/${listId}/cards`; - - body.title = this.getNodeParameter('title', i) as string; - body.swimlaneId = this.getNodeParameter('swimlaneId', i) as string; - body.authorId = this.getNodeParameter('authorId', i) as string; - - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - Object.assign(body, additionalFields); - - } else if (operation === 'delete') { - // ---------------------------------- - // delete - // ---------------------------------- - - requestMethod = 'DELETE'; - - const boardId = this.getNodeParameter('boardId', i) as string; - const listId = this.getNodeParameter('listId', i) as string; - const cardId = this.getNodeParameter('cardId', i) as string; - - endpoint = `boards/${boardId}/lists/${listId}/cards/${cardId}`; - - } else if (operation === 'get') { - // ---------------------------------- - // get - // ---------------------------------- - - requestMethod = 'GET'; - - const boardId = this.getNodeParameter('boardId', i) as string; - const listId = this.getNodeParameter('listId', i) as string; - const cardId = this.getNodeParameter('cardId', i) as string; - - endpoint = `boards/${boardId}/lists/${listId}/cards/${cardId}`; - - } else if (operation === 'getAll') { - // ---------------------------------- - // getAll - // ---------------------------------- - - requestMethod = 'GET'; - - const boardId = this.getNodeParameter('boardId', i) as string; - const fromObject = this.getNodeParameter('fromObject', i) as string; - returnAll = this.getNodeParameter('returnAll', i) as boolean; - - if (fromObject === 'list') { + const boardId = this.getNodeParameter('boardId', i) as string; const listId = this.getNodeParameter('listId', i) as string; endpoint = `boards/${boardId}/lists/${listId}/cards`; + + body.title = this.getNodeParameter('title', i) as string; + body.swimlaneId = this.getNodeParameter('swimlaneId', i) as string; + body.authorId = this.getNodeParameter('authorId', i) as string; + + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + Object.assign(body, additionalFields); + + } else if (operation === 'delete') { + // ---------------------------------- + // delete + // ---------------------------------- + + requestMethod = 'DELETE'; + + const boardId = this.getNodeParameter('boardId', i) as string; + const listId = this.getNodeParameter('listId', i) as string; + const cardId = this.getNodeParameter('cardId', i) as string; + + endpoint = `boards/${boardId}/lists/${listId}/cards/${cardId}`; + + } else if (operation === 'get') { + // ---------------------------------- + // get + // ---------------------------------- + + requestMethod = 'GET'; + + const boardId = this.getNodeParameter('boardId', i) as string; + const listId = this.getNodeParameter('listId', i) as string; + const cardId = this.getNodeParameter('cardId', i) as string; + + endpoint = `boards/${boardId}/lists/${listId}/cards/${cardId}`; + + } else if (operation === 'getAll') { + // ---------------------------------- + // getAll + // ---------------------------------- + + requestMethod = 'GET'; + + const boardId = this.getNodeParameter('boardId', i) as string; + const fromObject = this.getNodeParameter('fromObject', i) as string; + returnAll = this.getNodeParameter('returnAll', i) as boolean; + + if (fromObject === 'list') { + const listId = this.getNodeParameter('listId', i) as string; + + endpoint = `boards/${boardId}/lists/${listId}/cards`; + } + + if (fromObject === 'swimlane') { + const swimlaneId = this.getNodeParameter('swimlaneId', i) as string; + + endpoint = `boards/${boardId}/swimlanes/${swimlaneId}/cards`; + } + + } else if (operation === 'update') { + // ---------------------------------- + // update + // ---------------------------------- + + requestMethod = 'PUT'; + + const boardId = this.getNodeParameter('boardId', i) as string; + const listId = this.getNodeParameter('listId', i) as string; + const cardId = this.getNodeParameter('cardId', i) as string; + + endpoint = `boards/${boardId}/lists/${listId}/cards/${cardId}`; + + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + Object.assign(body, updateFields); + + } else { + throw new NodeOperationError(this.getNode(), `The operation "${operation}" is not known!`); } - if (fromObject === 'swimlane') { - const swimlaneId = this.getNodeParameter('swimlaneId', i) as string; + } else if (resource === 'cardComment') { - endpoint = `boards/${boardId}/swimlanes/${swimlaneId}/cards`; + if (operation === 'create') { + // ---------------------------------- + // create + // ---------------------------------- + + requestMethod = 'POST'; + + const boardId = this.getNodeParameter('boardId', i) as string; + const cardId = this.getNodeParameter('cardId', i) as string; + + endpoint = `boards/${boardId}/cards/${cardId}/comments`; + + body.authorId = this.getNodeParameter('authorId', i) as string; + body.comment = this.getNodeParameter('comment', i) as string; + + } else if (operation === 'delete') { + // ---------------------------------- + // delete + // ---------------------------------- + + requestMethod = 'DELETE'; + + const boardId = this.getNodeParameter('boardId', i) as string; + const cardId = this.getNodeParameter('cardId', i) as string; + const commentId = this.getNodeParameter('commentId', i) as string; + + endpoint = `boards/${boardId}/cards/${cardId}/comments/${commentId}`; + + } else if (operation === 'get') { + // ---------------------------------- + // get + // ---------------------------------- + + requestMethod = 'GET'; + + const boardId = this.getNodeParameter('boardId', i) as string; + const cardId = this.getNodeParameter('cardId', i) as string; + const commentId = this.getNodeParameter('commentId', i) as string; + + endpoint = `boards/${boardId}/cards/${cardId}/comments/${commentId}`; + + } else if (operation === 'getAll') { + // ---------------------------------- + // getAll + // ---------------------------------- + + requestMethod = 'GET'; + + const boardId = this.getNodeParameter('boardId', i) as string; + const cardId = this.getNodeParameter('cardId', i) as string; + + endpoint = `boards/${boardId}/cards/${cardId}/comments`; + + } else { + throw new NodeOperationError(this.getNode(), `The operation "${operation}" is not known!`); } - } else if (operation === 'update') { - // ---------------------------------- - // update - // ---------------------------------- + } else if (resource === 'list') { - requestMethod = 'PUT'; + if (operation === 'create') { + // ---------------------------------- + // create + // ---------------------------------- - const boardId = this.getNodeParameter('boardId', i) as string; - const listId = this.getNodeParameter('listId', i) as string; - const cardId = this.getNodeParameter('cardId', i) as string; + requestMethod = 'POST'; - endpoint = `boards/${boardId}/lists/${listId}/cards/${cardId}`; + const boardId = this.getNodeParameter('boardId', i) as string; - const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; - Object.assign(body, updateFields); + endpoint = `boards/${boardId}/lists`; + body.title = this.getNodeParameter('title', i) as string; + + } else if (operation === 'delete') { + // ---------------------------------- + // delete + // ---------------------------------- + + requestMethod = 'DELETE'; + + const boardId = this.getNodeParameter('boardId', i) as string; + const listId = this.getNodeParameter('listId', i) as string; + + endpoint = `boards/${boardId}/lists/${listId}`; + + } else if (operation === 'get') { + // ---------------------------------- + // get + // ---------------------------------- + + requestMethod = 'GET'; + + const boardId = this.getNodeParameter('boardId', i) as string; + const listId = this.getNodeParameter('listId', i) as string; + + endpoint = `boards/${boardId}/lists/${listId}`; + + } else if (operation === 'getAll') { + // ---------------------------------- + // getAll + // ---------------------------------- + + requestMethod = 'GET'; + + const boardId = this.getNodeParameter('boardId', i) as string; + returnAll = this.getNodeParameter('returnAll', i) as boolean; + + endpoint = `boards/${boardId}/lists`; + + } else { + throw new NodeOperationError(this.getNode(), `The operation "${operation}" is not known!`); + } + + } else if (resource === 'checklist') { + + if (operation === 'create') { + // ---------------------------------- + // create + // ---------------------------------- + + requestMethod = 'POST'; + + const boardId = this.getNodeParameter('boardId', i) as string; + const cardId = this.getNodeParameter('cardId', i) as string; + + endpoint = `boards/${boardId}/cards/${cardId}/checklists`; + + body.title = this.getNodeParameter('title', i) as string; + + body.items = this.getNodeParameter('items', i) as string[]; + + } else if (operation === 'delete') { + // ---------------------------------- + // delete + // ---------------------------------- + + requestMethod = 'DELETE'; + + const boardId = this.getNodeParameter('boardId', i) as string; + const cardId = this.getNodeParameter('cardId', i) as string; + const checklistId = this.getNodeParameter('checklistId', i) as string; + + endpoint = `boards/${boardId}/cards/${cardId}/checklists/${checklistId}`; + + } else if (operation === 'get') { + // ---------------------------------- + // get + // ---------------------------------- + + requestMethod = 'GET'; + + const boardId = this.getNodeParameter('boardId', i) as string; + const cardId = this.getNodeParameter('cardId', i) as string; + const checklistId = this.getNodeParameter('checklistId', i) as string; + + endpoint = `boards/${boardId}/cards/${cardId}/checklists/${checklistId}`; + + } else if (operation === 'getAll') { + // ---------------------------------- + // getAll + // ---------------------------------- + + requestMethod = 'GET'; + + const boardId = this.getNodeParameter('boardId', i) as string; + const cardId = this.getNodeParameter('cardId', i) as string; + returnAll = this.getNodeParameter('returnAll', i) as boolean; + + + endpoint = `boards/${boardId}/cards/${cardId}/checklists`; + + } else if (operation === 'getCheckItem') { + // ---------------------------------- + // getCheckItem + // ---------------------------------- + + requestMethod = 'GET'; + + const boardId = this.getNodeParameter('boardId', i) as string; + const cardId = this.getNodeParameter('cardId', i) as string; + const checklistId = this.getNodeParameter('checklistId', i) as string; + const itemId = this.getNodeParameter('itemId', i) as string; + + endpoint = `boards/${boardId}/cards/${cardId}/checklists/${checklistId}/items/${itemId}`; + + } else if (operation === 'deleteCheckItem') { + // ---------------------------------- + // deleteCheckItem + // ---------------------------------- + + requestMethod = 'DELETE'; + + const boardId = this.getNodeParameter('boardId', i) as string; + const cardId = this.getNodeParameter('cardId', i) as string; + const checklistId = this.getNodeParameter('checklistId', i) as string; + const itemId = this.getNodeParameter('itemId', i) as string; + + endpoint = `boards/${boardId}/cards/${cardId}/checklists/${checklistId}/items/${itemId}`; + + } else if (operation === 'updateCheckItem') { + // ---------------------------------- + // updateCheckItem + // ---------------------------------- + + requestMethod = 'PUT'; + + const boardId = this.getNodeParameter('boardId', i) as string; + const cardId = this.getNodeParameter('cardId', i) as string; + const checklistId = this.getNodeParameter('checklistId', i) as string; + const itemId = this.getNodeParameter('itemId', i) as string; + + endpoint = `boards/${boardId}/cards/${cardId}/checklists/${checklistId}/items/${itemId}`; + + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + Object.assign(body, updateFields); + + + + } else { + throw new NodeOperationError(this.getNode(), `The operation "${operation}" is not known!`); + } + } else if (resource === 'checklistItem') { + + if (operation === 'get') { + // ---------------------------------- + // get + // ---------------------------------- + + requestMethod = 'GET'; + + const boardId = this.getNodeParameter('boardId', i) as string; + const cardId = this.getNodeParameter('cardId', i) as string; + const checklistId = this.getNodeParameter('checklistId', i) as string; + const itemId = this.getNodeParameter('checklistItemId', i) as string; + + endpoint = `boards/${boardId}/cards/${cardId}/checklists/${checklistId}/items/${itemId}`; + + } else if (operation === 'delete') { + // ---------------------------------- + // delete + // ---------------------------------- + + requestMethod = 'DELETE'; + + const boardId = this.getNodeParameter('boardId', i) as string; + const cardId = this.getNodeParameter('cardId', i) as string; + const checklistId = this.getNodeParameter('checklistId', i) as string; + const itemId = this.getNodeParameter('checklistItemId', i) as string; + + endpoint = `boards/${boardId}/cards/${cardId}/checklists/${checklistId}/items/${itemId}`; + + } else if (operation === 'update') { + // ---------------------------------- + // update + // ---------------------------------- + + requestMethod = 'PUT'; + + const boardId = this.getNodeParameter('boardId', i) as string; + const cardId = this.getNodeParameter('cardId', i) as string; + const checklistId = this.getNodeParameter('checklistId', i) as string; + const itemId = this.getNodeParameter('checklistItemId', i) as string; + + endpoint = `boards/${boardId}/cards/${cardId}/checklists/${checklistId}/items/${itemId}`; + + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + Object.assign(body, updateFields); + } + } + let responseData = await apiRequest.call(this, requestMethod, endpoint, body, qs); + + if (returnAll === false) { + limit = this.getNodeParameter('limit', i) as number; + responseData = responseData.splice(0, limit); + } + + if (Array.isArray(responseData)) { + returnData.push.apply(returnData, responseData as IDataObject[]); } else { - throw new NodeOperationError(this.getNode(), `The operation "${operation}" is not known!`); + returnData.push(responseData as IDataObject); } - - } else if (resource === 'cardComment') { - - if (operation === 'create') { - // ---------------------------------- - // create - // ---------------------------------- - - requestMethod = 'POST'; - - const boardId = this.getNodeParameter('boardId', i) as string; - const cardId = this.getNodeParameter('cardId', i) as string; - - endpoint = `boards/${boardId}/cards/${cardId}/comments`; - - body.authorId = this.getNodeParameter('authorId', i) as string; - body.comment = this.getNodeParameter('comment', i) as string; - - } else if (operation === 'delete') { - // ---------------------------------- - // delete - // ---------------------------------- - - requestMethod = 'DELETE'; - - const boardId = this.getNodeParameter('boardId', i) as string; - const cardId = this.getNodeParameter('cardId', i) as string; - const commentId = this.getNodeParameter('commentId', i) as string; - - endpoint = `boards/${boardId}/cards/${cardId}/comments/${commentId}`; - - } else if (operation === 'get') { - // ---------------------------------- - // get - // ---------------------------------- - - requestMethod = 'GET'; - - const boardId = this.getNodeParameter('boardId', i) as string; - const cardId = this.getNodeParameter('cardId', i) as string; - const commentId = this.getNodeParameter('commentId', i) as string; - - endpoint = `boards/${boardId}/cards/${cardId}/comments/${commentId}`; - - } else if (operation === 'getAll') { - // ---------------------------------- - // getAll - // ---------------------------------- - - requestMethod = 'GET'; - - const boardId = this.getNodeParameter('boardId', i) as string; - const cardId = this.getNodeParameter('cardId', i) as string; - - endpoint = `boards/${boardId}/cards/${cardId}/comments`; - - } else { - throw new NodeOperationError(this.getNode(), `The operation "${operation}" is not known!`); + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; } - - } else if (resource === 'list') { - - if (operation === 'create') { - // ---------------------------------- - // create - // ---------------------------------- - - requestMethod = 'POST'; - - const boardId = this.getNodeParameter('boardId', i) as string; - - endpoint = `boards/${boardId}/lists`; - - body.title = this.getNodeParameter('title', i) as string; - - } else if (operation === 'delete') { - // ---------------------------------- - // delete - // ---------------------------------- - - requestMethod = 'DELETE'; - - const boardId = this.getNodeParameter('boardId', i) as string; - const listId = this.getNodeParameter('listId', i) as string; - - endpoint = `boards/${boardId}/lists/${listId}`; - - } else if (operation === 'get') { - // ---------------------------------- - // get - // ---------------------------------- - - requestMethod = 'GET'; - - const boardId = this.getNodeParameter('boardId', i) as string; - const listId = this.getNodeParameter('listId', i) as string; - - endpoint = `boards/${boardId}/lists/${listId}`; - - } else if (operation === 'getAll') { - // ---------------------------------- - // getAll - // ---------------------------------- - - requestMethod = 'GET'; - - const boardId = this.getNodeParameter('boardId', i) as string; - returnAll = this.getNodeParameter('returnAll', i) as boolean; - - endpoint = `boards/${boardId}/lists`; - - } else { - throw new NodeOperationError(this.getNode(), `The operation "${operation}" is not known!`); - } - - } else if (resource === 'checklist') { - - if (operation === 'create') { - // ---------------------------------- - // create - // ---------------------------------- - - requestMethod = 'POST'; - - const boardId = this.getNodeParameter('boardId', i) as string; - const cardId = this.getNodeParameter('cardId', i) as string; - - endpoint = `boards/${boardId}/cards/${cardId}/checklists`; - - body.title = this.getNodeParameter('title', i) as string; - - body.items = this.getNodeParameter('items', i) as string[]; - - } else if (operation === 'delete') { - // ---------------------------------- - // delete - // ---------------------------------- - - requestMethod = 'DELETE'; - - const boardId = this.getNodeParameter('boardId', i) as string; - const cardId = this.getNodeParameter('cardId', i) as string; - const checklistId = this.getNodeParameter('checklistId', i) as string; - - endpoint = `boards/${boardId}/cards/${cardId}/checklists/${checklistId}`; - - } else if (operation === 'get') { - // ---------------------------------- - // get - // ---------------------------------- - - requestMethod = 'GET'; - - const boardId = this.getNodeParameter('boardId', i) as string; - const cardId = this.getNodeParameter('cardId', i) as string; - const checklistId = this.getNodeParameter('checklistId', i) as string; - - endpoint = `boards/${boardId}/cards/${cardId}/checklists/${checklistId}`; - - } else if (operation === 'getAll') { - // ---------------------------------- - // getAll - // ---------------------------------- - - requestMethod = 'GET'; - - const boardId = this.getNodeParameter('boardId', i) as string; - const cardId = this.getNodeParameter('cardId', i) as string; - returnAll = this.getNodeParameter('returnAll', i) as boolean; - - - endpoint = `boards/${boardId}/cards/${cardId}/checklists`; - - } else if (operation === 'getCheckItem') { - // ---------------------------------- - // getCheckItem - // ---------------------------------- - - requestMethod = 'GET'; - - const boardId = this.getNodeParameter('boardId', i) as string; - const cardId = this.getNodeParameter('cardId', i) as string; - const checklistId = this.getNodeParameter('checklistId', i) as string; - const itemId = this.getNodeParameter('itemId', i) as string; - - endpoint = `boards/${boardId}/cards/${cardId}/checklists/${checklistId}/items/${itemId}`; - - } else if (operation === 'deleteCheckItem') { - // ---------------------------------- - // deleteCheckItem - // ---------------------------------- - - requestMethod = 'DELETE'; - - const boardId = this.getNodeParameter('boardId', i) as string; - const cardId = this.getNodeParameter('cardId', i) as string; - const checklistId = this.getNodeParameter('checklistId', i) as string; - const itemId = this.getNodeParameter('itemId', i) as string; - - endpoint = `boards/${boardId}/cards/${cardId}/checklists/${checklistId}/items/${itemId}`; - - } else if (operation === 'updateCheckItem') { - // ---------------------------------- - // updateCheckItem - // ---------------------------------- - - requestMethod = 'PUT'; - - const boardId = this.getNodeParameter('boardId', i) as string; - const cardId = this.getNodeParameter('cardId', i) as string; - const checklistId = this.getNodeParameter('checklistId', i) as string; - const itemId = this.getNodeParameter('itemId', i) as string; - - endpoint = `boards/${boardId}/cards/${cardId}/checklists/${checklistId}/items/${itemId}`; - - const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; - Object.assign(body, updateFields); - - - - } else { - throw new NodeOperationError(this.getNode(), `The operation "${operation}" is not known!`); - } - } else if (resource === 'checklistItem') { - - if (operation === 'get') { - // ---------------------------------- - // get - // ---------------------------------- - - requestMethod = 'GET'; - - const boardId = this.getNodeParameter('boardId', i) as string; - const cardId = this.getNodeParameter('cardId', i) as string; - const checklistId = this.getNodeParameter('checklistId', i) as string; - const itemId = this.getNodeParameter('checklistItemId', i) as string; - - endpoint = `boards/${boardId}/cards/${cardId}/checklists/${checklistId}/items/${itemId}`; - - } else if (operation === 'delete') { - // ---------------------------------- - // delete - // ---------------------------------- - - requestMethod = 'DELETE'; - - const boardId = this.getNodeParameter('boardId', i) as string; - const cardId = this.getNodeParameter('cardId', i) as string; - const checklistId = this.getNodeParameter('checklistId', i) as string; - const itemId = this.getNodeParameter('checklistItemId', i) as string; - - endpoint = `boards/${boardId}/cards/${cardId}/checklists/${checklistId}/items/${itemId}`; - - } else if (operation === 'update') { - // ---------------------------------- - // update - // ---------------------------------- - - requestMethod = 'PUT'; - - const boardId = this.getNodeParameter('boardId', i) as string; - const cardId = this.getNodeParameter('cardId', i) as string; - const checklistId = this.getNodeParameter('checklistId', i) as string; - const itemId = this.getNodeParameter('checklistItemId', i) as string; - - endpoint = `boards/${boardId}/cards/${cardId}/checklists/${checklistId}/items/${itemId}`; - - const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; - Object.assign(body, updateFields); - } - } - let responseData = await apiRequest.call(this, requestMethod, endpoint, body, qs); - - if (returnAll === false) { - limit = this.getNodeParameter('limit', i) as number; - responseData = responseData.splice(0, limit); - } - - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else { - returnData.push(responseData as IDataObject); + throw error; } } diff --git a/packages/nodes-base/nodes/Wordpress/Wordpress.node.ts b/packages/nodes-base/nodes/Wordpress/Wordpress.node.ts index 36f845325b..ca27583927 100644 --- a/packages/nodes-base/nodes/Wordpress/Wordpress.node.ts +++ b/packages/nodes-base/nodes/Wordpress/Wordpress.node.ts @@ -139,278 +139,286 @@ export class Wordpress implements INodeType { const operation = this.getNodeParameter('operation', 0) as string; for (let i = 0; i < length; i++) { - if (resource === 'post') { - //https://developer.wordpress.org/rest-api/reference/posts/#create-a-post - if (operation === 'create') { - const title = this.getNodeParameter('title', i) as string; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const body: IPost = { - title, - }; - if (additionalFields.authorId) { - body.author = additionalFields.authorId as number; + try { + if (resource === 'post') { + //https://developer.wordpress.org/rest-api/reference/posts/#create-a-post + if (operation === 'create') { + const title = this.getNodeParameter('title', i) as string; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const body: IPost = { + title, + }; + if (additionalFields.authorId) { + body.author = additionalFields.authorId as number; + } + if (additionalFields.content) { + body.content = additionalFields.content as string; + } + if (additionalFields.slug) { + body.slug = additionalFields.slug as string; + } + if (additionalFields.password) { + body.password = additionalFields.password as string; + } + if (additionalFields.status) { + body.status = additionalFields.status as string; + } + if (additionalFields.commentStatus) { + body.comment_status = additionalFields.commentStatus as string; + } + if (additionalFields.pingStatus) { + body.ping_status = additionalFields.pingStatus as string; + } + if (additionalFields.sticky) { + body.sticky = additionalFields.sticky as boolean; + } + if (additionalFields.categories) { + body.categories = additionalFields.categories as number[]; + } + if (additionalFields.tags) { + body.tags = additionalFields.tags as number[]; + } + if (additionalFields.format) { + body.format = additionalFields.format as string; + } + responseData = await wordpressApiRequest.call(this, 'POST', '/posts', body); } - if (additionalFields.content) { - body.content = additionalFields.content as string; + //https://developer.wordpress.org/rest-api/reference/posts/#update-a-post + if (operation === 'update') { + const postId = this.getNodeParameter('postId', i) as string; + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + const body: IPost = { + id: parseInt(postId, 10), + }; + if (updateFields.authorId) { + body.author = updateFields.authorId as number; + } + if (updateFields.title) { + body.title = updateFields.title as string; + } + if (updateFields.content) { + body.content = updateFields.content as string; + } + if (updateFields.slug) { + body.slug = updateFields.slug as string; + } + if (updateFields.password) { + body.password = updateFields.password as string; + } + if (updateFields.status) { + body.status = updateFields.status as string; + } + if (updateFields.commentStatus) { + body.comment_status = updateFields.commentStatus as string; + } + if (updateFields.pingStatus) { + body.ping_status = updateFields.pingStatus as string; + } + if (updateFields.sticky) { + body.sticky = updateFields.sticky as boolean; + } + if (updateFields.categories) { + body.categories = updateFields.categories as number[]; + } + if (updateFields.tags) { + body.tags = updateFields.tags as number[]; + } + if (updateFields.format) { + body.format = updateFields.format as string; + } + responseData = await wordpressApiRequest.call(this, 'POST', `/posts/${postId}`, body); } - if (additionalFields.slug) { - body.slug = additionalFields.slug as string; + //https://developer.wordpress.org/rest-api/reference/posts/#retrieve-a-post + if (operation === 'get') { + const postId = this.getNodeParameter('postId', i) as string; + const options = this.getNodeParameter('options', i) as IDataObject; + if (options.password) { + qs.password = options.password as string; + } + if (options.context) { + qs.context = options.context as string; + } + responseData = await wordpressApiRequest.call(this, 'GET', `/posts/${postId}`, {}, qs); } - if (additionalFields.password) { - body.password = additionalFields.password as string; + //https://developer.wordpress.org/rest-api/reference/posts/#list-posts + if (operation === 'getAll') { + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + const options = this.getNodeParameter('options', i) as IDataObject; + if (options.context) { + qs.context = options.context as string; + } + if (options.orderBy) { + qs.orderby = options.orderBy as string; + } + if (options.order) { + qs.order = options.order as string; + } + if (options.search) { + qs.search = options.search as string; + } + if (options.after) { + qs.after = options.after as string; + } + if (options.author) { + qs.author = options.author as number[]; + } + if (options.categories) { + qs.categories = options.categories as number[]; + } + if (options.excludedCategories) { + qs.categories_exclude = options.excludedCategories as number[]; + } + if (options.tags) { + qs.tags = options.tags as number[]; + } + if (options.excludedTags) { + qs.tags_exclude = options.excludedTags as number[]; + } + if (options.sticky) { + qs.sticky = options.sticky as boolean; + } + if (returnAll === true) { + responseData = await wordpressApiRequestAllItems.call(this, 'GET', '/posts', {}, qs); + } else { + qs.per_page = this.getNodeParameter('limit', i) as number; + responseData = await wordpressApiRequest.call(this, 'GET', '/posts', {}, qs); + } } - if (additionalFields.status) { - body.status = additionalFields.status as string; - } - if (additionalFields.commentStatus) { - body.comment_status = additionalFields.commentStatus as string; - } - if (additionalFields.pingStatus) { - body.ping_status = additionalFields.pingStatus as string; - } - if (additionalFields.sticky) { - body.sticky = additionalFields.sticky as boolean; - } - if (additionalFields.categories) { - body.categories = additionalFields.categories as number[]; - } - if (additionalFields.tags) { - body.tags = additionalFields.tags as number[]; - } - if (additionalFields.format) { - body.format = additionalFields.format as string; - } - responseData = await wordpressApiRequest.call(this, 'POST', '/posts', body); - } - //https://developer.wordpress.org/rest-api/reference/posts/#update-a-post - if (operation === 'update') { - const postId = this.getNodeParameter('postId', i) as string; - const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; - const body: IPost = { - id: parseInt(postId, 10), - }; - if (updateFields.authorId) { - body.author = updateFields.authorId as number; - } - if (updateFields.title) { - body.title = updateFields.title as string; - } - if (updateFields.content) { - body.content = updateFields.content as string; - } - if (updateFields.slug) { - body.slug = updateFields.slug as string; - } - if (updateFields.password) { - body.password = updateFields.password as string; - } - if (updateFields.status) { - body.status = updateFields.status as string; - } - if (updateFields.commentStatus) { - body.comment_status = updateFields.commentStatus as string; - } - if (updateFields.pingStatus) { - body.ping_status = updateFields.pingStatus as string; - } - if (updateFields.sticky) { - body.sticky = updateFields.sticky as boolean; - } - if (updateFields.categories) { - body.categories = updateFields.categories as number[]; - } - if (updateFields.tags) { - body.tags = updateFields.tags as number[]; - } - if (updateFields.format) { - body.format = updateFields.format as string; - } - responseData = await wordpressApiRequest.call(this, 'POST', `/posts/${postId}`, body); - } - //https://developer.wordpress.org/rest-api/reference/posts/#retrieve-a-post - if (operation === 'get') { - const postId = this.getNodeParameter('postId', i) as string; - const options = this.getNodeParameter('options', i) as IDataObject; - if (options.password) { - qs.password = options.password as string; - } - if (options.context) { - qs.context = options.context as string; - } - responseData = await wordpressApiRequest.call(this, 'GET', `/posts/${postId}`, {}, qs); - } - //https://developer.wordpress.org/rest-api/reference/posts/#list-posts - if (operation === 'getAll') { - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - const options = this.getNodeParameter('options', i) as IDataObject; - if (options.context) { - qs.context = options.context as string; - } - if (options.orderBy) { - qs.orderby = options.orderBy as string; - } - if (options.order) { - qs.order = options.order as string; - } - if (options.search) { - qs.search = options.search as string; - } - if (options.after) { - qs.after = options.after as string; - } - if (options.author) { - qs.author = options.author as number[]; - } - if (options.categories) { - qs.categories = options.categories as number[]; - } - if (options.excludedCategories) { - qs.categories_exclude = options.excludedCategories as number[]; - } - if (options.tags) { - qs.tags = options.tags as number[]; - } - if (options.excludedTags) { - qs.tags_exclude = options.excludedTags as number[]; - } - if (options.sticky) { - qs.sticky = options.sticky as boolean; - } - if (returnAll === true) { - responseData = await wordpressApiRequestAllItems.call(this, 'GET', '/posts', {}, qs); - } else { - qs.per_page = this.getNodeParameter('limit', i) as number; - responseData = await wordpressApiRequest.call(this, 'GET', '/posts', {}, qs); + //https://developer.wordpress.org/rest-api/reference/posts/#delete-a-post + if (operation === 'delete') { + const postId = this.getNodeParameter('postId', i) as string; + const options = this.getNodeParameter('options', i) as IDataObject; + if (options.force) { + qs.force = options.force as boolean; + } + responseData = await wordpressApiRequest.call(this, 'DELETE', `/posts/${postId}`, {}, qs); } } - //https://developer.wordpress.org/rest-api/reference/posts/#delete-a-post - if (operation === 'delete') { - const postId = this.getNodeParameter('postId', i) as string; - const options = this.getNodeParameter('options', i) as IDataObject; - if (options.force) { - qs.force = options.force as boolean; + if (resource === 'user') { + //https://developer.wordpress.org/rest-api/reference/users/#create-a-user + if (operation === 'create') { + const name = this.getNodeParameter('name', i) as string; + const username = this.getNodeParameter('username', i) as string; + const firstName = this.getNodeParameter('firstName', i) as string; + const lastName = this.getNodeParameter('lastName', i) as string; + const email = this.getNodeParameter('email', i) as string; + const password = this.getNodeParameter('password', i) as string; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const body: IUser = { + name, + username, + first_name: firstName, + last_name: lastName, + email, + password, + }; + if (additionalFields.url) { + body.url = additionalFields.url as string; + } + if (additionalFields.description) { + body.description = additionalFields.description as string; + } + if (additionalFields.nickname) { + body.nickname = additionalFields.nickname as string; + } + if (additionalFields.slug) { + body.slug = additionalFields.slug as string; + } + responseData = await wordpressApiRequest.call(this, 'POST', '/users', body); } - responseData = await wordpressApiRequest.call(this, 'DELETE', `/posts/${postId}`, {}, qs); - } - } - if (resource === 'user') { - //https://developer.wordpress.org/rest-api/reference/users/#create-a-user - if (operation === 'create') { - const name = this.getNodeParameter('name', i) as string; - const username = this.getNodeParameter('username', i) as string; - const firstName = this.getNodeParameter('firstName', i) as string; - const lastName = this.getNodeParameter('lastName', i) as string; - const email = this.getNodeParameter('email', i) as string; - const password = this.getNodeParameter('password', i) as string; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const body: IUser = { - name, - username, - first_name: firstName, - last_name: lastName, - email, - password, - }; - if (additionalFields.url) { - body.url = additionalFields.url as string; + //https://developer.wordpress.org/rest-api/reference/users/#update-a-user + if (operation === 'update') { + const userId = this.getNodeParameter('userId', i) as number; + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + const body: IUser = { + id: userId, + }; + if (updateFields.name) { + body.name = updateFields.name as string; + } + if (updateFields.firstName) { + body.first_name = updateFields.firstName as string; + } + if (updateFields.lastName) { + body.last_name = updateFields.lastName as string; + } + if (updateFields.email) { + body.email = updateFields.email as string; + } + if (updateFields.password) { + body.password = updateFields.password as string; + } + if (updateFields.username) { + body.username = updateFields.username as string; + } + if (updateFields.url) { + body.url = updateFields.url as string; + } + if (updateFields.description) { + body.description = updateFields.description as string; + } + if (updateFields.nickname) { + body.nickname = updateFields.nickname as string; + } + if (updateFields.slug) { + body.slug = updateFields.slug as string; + } + responseData = await wordpressApiRequest.call(this, 'POST', `/users/${userId}`, body); } - if (additionalFields.description) { - body.description = additionalFields.description as string; + //https://developer.wordpress.org/rest-api/reference/users/#retrieve-a-user + if (operation === 'get') { + const userId = this.getNodeParameter('userId', i) as string; + const options = this.getNodeParameter('options', i) as IDataObject; + if (options.context) { + qs.context = options.context as string; + } + responseData = await wordpressApiRequest.call(this, 'GET', `/users/${userId}`, {}, qs); } - if (additionalFields.nickname) { - body.nickname = additionalFields.nickname as string; + //https://developer.wordpress.org/rest-api/reference/users/#list-users + if (operation === 'getAll') { + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + const options = this.getNodeParameter('options', i) as IDataObject; + if (options.context) { + qs.context = options.context as string; + } + if (options.orderBy) { + qs.orderby = options.orderBy as string; + } + if (options.order) { + qs.order = options.order as string; + } + if (options.search) { + qs.search = options.search as string; + } + if (options.who) { + qs.who = options.who as string; + } + if (returnAll === true) { + responseData = await wordpressApiRequestAllItems.call(this, 'GET', '/users', {}, qs); + } else { + qs.per_page = this.getNodeParameter('limit', i) as number; + responseData = await wordpressApiRequest.call(this, 'GET', '/users', {}, qs); + } } - if (additionalFields.slug) { - body.slug = additionalFields.slug as string; - } - responseData = await wordpressApiRequest.call(this, 'POST', '/users', body); - } - //https://developer.wordpress.org/rest-api/reference/users/#update-a-user - if (operation === 'update') { - const userId = this.getNodeParameter('userId', i) as number; - const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; - const body: IUser = { - id: userId, - }; - if (updateFields.name) { - body.name = updateFields.name as string; - } - if (updateFields.firstName) { - body.first_name = updateFields.firstName as string; - } - if (updateFields.lastName) { - body.last_name = updateFields.lastName as string; - } - if (updateFields.email) { - body.email = updateFields.email as string; - } - if (updateFields.password) { - body.password = updateFields.password as string; - } - if (updateFields.username) { - body.username = updateFields.username as string; - } - if (updateFields.url) { - body.url = updateFields.url as string; - } - if (updateFields.description) { - body.description = updateFields.description as string; - } - if (updateFields.nickname) { - body.nickname = updateFields.nickname as string; - } - if (updateFields.slug) { - body.slug = updateFields.slug as string; - } - responseData = await wordpressApiRequest.call(this, 'POST', `/users/${userId}`, body); - } - //https://developer.wordpress.org/rest-api/reference/users/#retrieve-a-user - if (operation === 'get') { - const userId = this.getNodeParameter('userId', i) as string; - const options = this.getNodeParameter('options', i) as IDataObject; - if (options.context) { - qs.context = options.context as string; - } - responseData = await wordpressApiRequest.call(this, 'GET', `/users/${userId}`, {}, qs); - } - //https://developer.wordpress.org/rest-api/reference/users/#list-users - if (operation === 'getAll') { - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - const options = this.getNodeParameter('options', i) as IDataObject; - if (options.context) { - qs.context = options.context as string; - } - if (options.orderBy) { - qs.orderby = options.orderBy as string; - } - if (options.order) { - qs.order = options.order as string; - } - if (options.search) { - qs.search = options.search as string; - } - if (options.who) { - qs.who = options.who as string; - } - if (returnAll === true) { - responseData = await wordpressApiRequestAllItems.call(this, 'GET', '/users', {}, qs); - } else { - qs.per_page = this.getNodeParameter('limit', i) as number; - responseData = await wordpressApiRequest.call(this, 'GET', '/users', {}, qs); + //https://developer.wordpress.org/rest-api/reference/users/#delete-a-user + if (operation === 'delete') { + const reassign = this.getNodeParameter('reassign', i) as string; + qs.reassign = reassign; + qs.force = true; + responseData = await wordpressApiRequest.call(this, 'DELETE', `/users/me`, {}, qs); } } - //https://developer.wordpress.org/rest-api/reference/users/#delete-a-user - if (operation === 'delete') { - const reassign = this.getNodeParameter('reassign', i) as string; - qs.reassign = reassign; - qs.force = true; - responseData = await wordpressApiRequest.call(this, 'DELETE', `/users/me`, {}, qs); + if (Array.isArray(responseData)) { + returnData.push.apply(returnData, responseData as IDataObject[]); + } else { + returnData.push(responseData as IDataObject); } - } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else { - returnData.push(responseData as IDataObject); + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } } return [this.helpers.returnJsonArray(returnData)]; diff --git a/packages/nodes-base/nodes/WriteBinaryFile.node.ts b/packages/nodes-base/nodes/WriteBinaryFile.node.ts index 5796110119..db1b6371ed 100644 --- a/packages/nodes-base/nodes/WriteBinaryFile.node.ts +++ b/packages/nodes-base/nodes/WriteBinaryFile.node.ts @@ -61,42 +61,50 @@ export class WriteBinaryFile implements INodeType { let item: INodeExecutionData; for (let itemIndex = 0; itemIndex < length; itemIndex++) { + try { + const dataPropertyName = this.getNodeParameter('dataPropertyName', itemIndex) as string; - const dataPropertyName = this.getNodeParameter('dataPropertyName', itemIndex) as string; + const fileName = this.getNodeParameter('fileName', itemIndex) as string; - const fileName = this.getNodeParameter('fileName', itemIndex) as string; + item = items[itemIndex]; - item = items[itemIndex]; + if (item.binary === undefined) { + throw new NodeOperationError(this.getNode(), 'No binary data set. So file can not be written!'); + } - if (item.binary === undefined) { - throw new NodeOperationError(this.getNode(), 'No binary data set. So file can not be written!'); + if (item.binary[dataPropertyName] === undefined) { + throw new NodeOperationError(this.getNode(), `The binary property "${dataPropertyName}" does not exist. So no file can be written!`); + } + + // Write the file to disk + await fsWriteFile(fileName, Buffer.from(item.binary[dataPropertyName].data, BINARY_ENCODING), 'binary'); + + const newItem: INodeExecutionData = { + json: {}, + }; + Object.assign(newItem.json, item.json); + + if (item.binary !== undefined) { + // Create a shallow copy of the binary data so that the old + // data references which do not get changed still stay behind + // but the incoming data does not get changed. + newItem.binary = {}; + Object.assign(newItem.binary, item.binary); + } + + // Add the file name to data + + (newItem.json as IDataObject).fileName = fileName; + + returnData.push(newItem); + + } catch (error) { + if (this.continueOnFail()) { + returnData.push({json:{ error: error.message }}); + continue; + } + throw error; } - - if (item.binary[dataPropertyName] === undefined) { - throw new NodeOperationError(this.getNode(), `The binary property "${dataPropertyName}" does not exist. So no file can be written!`); - } - - // Write the file to disk - await fsWriteFile(fileName, Buffer.from(item.binary[dataPropertyName].data, BINARY_ENCODING), 'binary'); - - const newItem: INodeExecutionData = { - json: {}, - }; - Object.assign(newItem.json, item.json); - - if (item.binary !== undefined) { - // Create a shallow copy of the binary data so that the old - // data references which do not get changed still stay behind - // but the incoming data does not get changed. - newItem.binary = {}; - Object.assign(newItem.binary, item.binary); - } - - // Add the file name to data - - (newItem.json as IDataObject).fileName = fileName; - - returnData.push(newItem); } return this.prepareOutputData(returnData); } diff --git a/packages/nodes-base/nodes/Xero/Xero.node.ts b/packages/nodes-base/nodes/Xero/Xero.node.ts index 1f23e3620e..25ed4ca1ec 100644 --- a/packages/nodes-base/nodes/Xero/Xero.node.ts +++ b/packages/nodes-base/nodes/Xero/Xero.node.ts @@ -210,112 +210,24 @@ export class Xero implements INodeType { 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; - //https://developer.xero.com/documentation/api/invoices - if (resource === 'invoice') { - if (operation === 'create') { - const organizationId = this.getNodeParameter('organizationId', i) as string; - const type = this.getNodeParameter('type', i) as string; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const contactId = this.getNodeParameter('contactId', i) as string; - const lineItemsValues = ((this.getNodeParameter('lineItemsUi', i) as IDataObject).lineItemsValues as IDataObject[]); + try { + const resource = this.getNodeParameter('resource', 0) as string; + const operation = this.getNodeParameter('operation', 0) as string; + //https://developer.xero.com/documentation/api/invoices + if (resource === 'invoice') { + if (operation === 'create') { + const organizationId = this.getNodeParameter('organizationId', i) as string; + const type = this.getNodeParameter('type', i) as string; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const contactId = this.getNodeParameter('contactId', i) as string; + const lineItemsValues = ((this.getNodeParameter('lineItemsUi', i) as IDataObject).lineItemsValues as IDataObject[]); - const body: IInvoice = { - organizationId, - Type: type, - Contact: { ContactID: contactId }, - }; + const body: IInvoice = { + organizationId, + Type: type, + Contact: { ContactID: contactId }, + }; - if (lineItemsValues) { - const lineItems: ILineItem[] = []; - for (const lineItemValue of lineItemsValues) { - const lineItem: ILineItem = { - Tracking: [], - }; - lineItem.AccountCode = lineItemValue.accountCode as string; - lineItem.Description = lineItemValue.description as string; - lineItem.DiscountRate = lineItemValue.discountRate as string; - lineItem.ItemCode = lineItemValue.itemCode as string; - lineItem.LineAmount = lineItemValue.lineAmount as string; - lineItem.Quantity = (lineItemValue.quantity as number).toString(); - lineItem.TaxAmount = lineItemValue.taxAmount as string; - lineItem.TaxType = lineItemValue.taxType as string; - lineItem.UnitAmount = lineItemValue.unitAmount as string; - // if (lineItemValue.trackingUi) { - // //@ts-ignore - // const { trackingValues } = lineItemValue.trackingUi as IDataObject[]; - // if (trackingValues) { - // for (const trackingValue of trackingValues) { - // const tracking: IDataObject = {}; - // tracking.Name = trackingValue.name as string; - // tracking.Option = trackingValue.option as string; - // lineItem.Tracking!.push(tracking); - // } - // } - // } - lineItems.push(lineItem); - } - body.LineItems = lineItems; - } - - if (additionalFields.brandingThemeId) { - body.BrandingThemeID = additionalFields.brandingThemeId as string; - } - if (additionalFields.currency) { - body.CurrencyCode = additionalFields.currency as string; - } - if (additionalFields.currencyRate) { - body.CurrencyRate = additionalFields.currencyRate as string; - } - if (additionalFields.date) { - body.Date = additionalFields.date as string; - } - if (additionalFields.dueDate) { - body.DueDate = additionalFields.dueDate as string; - } - if (additionalFields.dueDate) { - body.DueDate = additionalFields.dueDate as string; - } - if (additionalFields.expectedPaymentDate) { - body.ExpectedPaymentDate = additionalFields.expectedPaymentDate as string; - } - if (additionalFields.invoiceNumber) { - body.InvoiceNumber = additionalFields.invoiceNumber as string; - } - if (additionalFields.lineAmountType) { - body.LineAmountType = additionalFields.lineAmountType as string; - } - if (additionalFields.plannedPaymentDate) { - body.PlannedPaymentDate = additionalFields.plannedPaymentDate as string; - } - if (additionalFields.reference) { - body.Reference = additionalFields.reference as string; - } - if (additionalFields.sendToContact) { - body.SentToContact = additionalFields.sendToContact as boolean; - } - if (additionalFields.status) { - body.Status = additionalFields.status as string; - } - if (additionalFields.url) { - body.Url = additionalFields.url as string; - } - - responseData = await xeroApiRequest.call(this, 'POST', '/Invoices', body); - responseData = responseData.Invoices; - } - if (operation === 'update') { - const invoiceId = this.getNodeParameter('invoiceId', i) as string; - const organizationId = this.getNodeParameter('organizationId', i) as string; - const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; - - const body: IInvoice = { - organizationId, - }; - - if (updateFields.lineItemsUi) { - const lineItemsValues = (updateFields.lineItemsUi as IDataObject).lineItemsValues as IDataObject[]; if (lineItemsValues) { const lineItems: ILineItem[] = []; for (const lineItemValue of lineItemsValues) { @@ -347,333 +259,429 @@ export class Xero implements INodeType { } body.LineItems = lineItems; } - } - if (updateFields.type) { - body.Type = updateFields.type as string; - } - if (updateFields.Contact) { - body.Contact = { ContactID: updateFields.contactId as string }; - } - if (updateFields.brandingThemeId) { - body.BrandingThemeID = updateFields.brandingThemeId as string; - } - if (updateFields.currency) { - body.CurrencyCode = updateFields.currency as string; - } - if (updateFields.currencyRate) { - body.CurrencyRate = updateFields.currencyRate as string; - } - if (updateFields.date) { - body.Date = updateFields.date as string; - } - if (updateFields.dueDate) { - body.DueDate = updateFields.dueDate as string; - } - if (updateFields.dueDate) { - body.DueDate = updateFields.dueDate as string; - } - if (updateFields.expectedPaymentDate) { - body.ExpectedPaymentDate = updateFields.expectedPaymentDate as string; - } - if (updateFields.invoiceNumber) { - body.InvoiceNumber = updateFields.invoiceNumber as string; - } - if (updateFields.lineAmountType) { - body.LineAmountType = updateFields.lineAmountType as string; - } - if (updateFields.plannedPaymentDate) { - body.PlannedPaymentDate = updateFields.plannedPaymentDate as string; - } - if (updateFields.reference) { - body.Reference = updateFields.reference as string; - } - if (updateFields.sendToContact) { - body.SentToContact = updateFields.sendToContact as boolean; - } - if (updateFields.status) { - body.Status = updateFields.status as string; - } - if (updateFields.url) { - body.Url = updateFields.url as string; - } + if (additionalFields.brandingThemeId) { + body.BrandingThemeID = additionalFields.brandingThemeId as string; + } + if (additionalFields.currency) { + body.CurrencyCode = additionalFields.currency as string; + } + if (additionalFields.currencyRate) { + body.CurrencyRate = additionalFields.currencyRate as string; + } + if (additionalFields.date) { + body.Date = additionalFields.date as string; + } + if (additionalFields.dueDate) { + body.DueDate = additionalFields.dueDate as string; + } + if (additionalFields.dueDate) { + body.DueDate = additionalFields.dueDate as string; + } + if (additionalFields.expectedPaymentDate) { + body.ExpectedPaymentDate = additionalFields.expectedPaymentDate as string; + } + if (additionalFields.invoiceNumber) { + body.InvoiceNumber = additionalFields.invoiceNumber as string; + } + if (additionalFields.lineAmountType) { + body.LineAmountType = additionalFields.lineAmountType as string; + } + if (additionalFields.plannedPaymentDate) { + body.PlannedPaymentDate = additionalFields.plannedPaymentDate as string; + } + if (additionalFields.reference) { + body.Reference = additionalFields.reference as string; + } + if (additionalFields.sendToContact) { + body.SentToContact = additionalFields.sendToContact as boolean; + } + if (additionalFields.status) { + body.Status = additionalFields.status as string; + } + if (additionalFields.url) { + body.Url = additionalFields.url as string; + } - responseData = await xeroApiRequest.call(this, 'POST', `/Invoices/${invoiceId}`, body); - responseData = responseData.Invoices; - } - if (operation === 'get') { - const organizationId = this.getNodeParameter('organizationId', i) as string; - const invoiceId = this.getNodeParameter('invoiceId', i) as string; - responseData = await xeroApiRequest.call(this, 'GET', `/Invoices/${invoiceId}`, { organizationId }); - responseData = responseData.Invoices; - } - if (operation === 'getAll') { - const organizationId = this.getNodeParameter('organizationId', i) as string; - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - const options = this.getNodeParameter('options', i) as IDataObject; - if (options.statuses) { - qs.statuses = (options.statuses as string[]).join(','); - } - if (options.orderBy) { - qs.order = `${options.orderBy} ${(options.sortOrder === undefined) ? 'DESC' : options.sortOrder}`; - } - if (options.where) { - qs.where = options.where; - } - if (options.createdByMyApp) { - qs.createdByMyApp = options.createdByMyApp as boolean; - } - if (returnAll) { - responseData = await xeroApiRequestAllItems.call(this, 'Invoices', 'GET', '/Invoices', { organizationId }, qs); - } else { - const limit = this.getNodeParameter('limit', i) as number; - responseData = await xeroApiRequest.call(this, 'GET', `/Invoices`, { organizationId }, qs); + responseData = await xeroApiRequest.call(this, 'POST', '/Invoices', body); responseData = responseData.Invoices; - responseData = responseData.splice(0, limit); + } + if (operation === 'update') { + const invoiceId = this.getNodeParameter('invoiceId', i) as string; + const organizationId = this.getNodeParameter('organizationId', i) as string; + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + + const body: IInvoice = { + organizationId, + }; + + if (updateFields.lineItemsUi) { + const lineItemsValues = (updateFields.lineItemsUi as IDataObject).lineItemsValues as IDataObject[]; + if (lineItemsValues) { + const lineItems: ILineItem[] = []; + for (const lineItemValue of lineItemsValues) { + const lineItem: ILineItem = { + Tracking: [], + }; + lineItem.AccountCode = lineItemValue.accountCode as string; + lineItem.Description = lineItemValue.description as string; + lineItem.DiscountRate = lineItemValue.discountRate as string; + lineItem.ItemCode = lineItemValue.itemCode as string; + lineItem.LineAmount = lineItemValue.lineAmount as string; + lineItem.Quantity = (lineItemValue.quantity as number).toString(); + lineItem.TaxAmount = lineItemValue.taxAmount as string; + lineItem.TaxType = lineItemValue.taxType as string; + lineItem.UnitAmount = lineItemValue.unitAmount as string; + // if (lineItemValue.trackingUi) { + // //@ts-ignore + // const { trackingValues } = lineItemValue.trackingUi as IDataObject[]; + // if (trackingValues) { + // for (const trackingValue of trackingValues) { + // const tracking: IDataObject = {}; + // tracking.Name = trackingValue.name as string; + // tracking.Option = trackingValue.option as string; + // lineItem.Tracking!.push(tracking); + // } + // } + // } + lineItems.push(lineItem); + } + body.LineItems = lineItems; + } + } + + if (updateFields.type) { + body.Type = updateFields.type as string; + } + if (updateFields.Contact) { + body.Contact = { ContactID: updateFields.contactId as string }; + } + if (updateFields.brandingThemeId) { + body.BrandingThemeID = updateFields.brandingThemeId as string; + } + if (updateFields.currency) { + body.CurrencyCode = updateFields.currency as string; + } + if (updateFields.currencyRate) { + body.CurrencyRate = updateFields.currencyRate as string; + } + if (updateFields.date) { + body.Date = updateFields.date as string; + } + if (updateFields.dueDate) { + body.DueDate = updateFields.dueDate as string; + } + if (updateFields.dueDate) { + body.DueDate = updateFields.dueDate as string; + } + if (updateFields.expectedPaymentDate) { + body.ExpectedPaymentDate = updateFields.expectedPaymentDate as string; + } + if (updateFields.invoiceNumber) { + body.InvoiceNumber = updateFields.invoiceNumber as string; + } + if (updateFields.lineAmountType) { + body.LineAmountType = updateFields.lineAmountType as string; + } + if (updateFields.plannedPaymentDate) { + body.PlannedPaymentDate = updateFields.plannedPaymentDate as string; + } + if (updateFields.reference) { + body.Reference = updateFields.reference as string; + } + if (updateFields.sendToContact) { + body.SentToContact = updateFields.sendToContact as boolean; + } + if (updateFields.status) { + body.Status = updateFields.status as string; + } + if (updateFields.url) { + body.Url = updateFields.url as string; + } + + responseData = await xeroApiRequest.call(this, 'POST', `/Invoices/${invoiceId}`, body); + responseData = responseData.Invoices; + } + if (operation === 'get') { + const organizationId = this.getNodeParameter('organizationId', i) as string; + const invoiceId = this.getNodeParameter('invoiceId', i) as string; + responseData = await xeroApiRequest.call(this, 'GET', `/Invoices/${invoiceId}`, { organizationId }); + responseData = responseData.Invoices; + } + if (operation === 'getAll') { + const organizationId = this.getNodeParameter('organizationId', i) as string; + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + const options = this.getNodeParameter('options', i) as IDataObject; + if (options.statuses) { + qs.statuses = (options.statuses as string[]).join(','); + } + if (options.orderBy) { + qs.order = `${options.orderBy} ${(options.sortOrder === undefined) ? 'DESC' : options.sortOrder}`; + } + if (options.where) { + qs.where = options.where; + } + if (options.createdByMyApp) { + qs.createdByMyApp = options.createdByMyApp as boolean; + } + if (returnAll) { + responseData = await xeroApiRequestAllItems.call(this, 'Invoices', 'GET', '/Invoices', { organizationId }, qs); + } else { + const limit = this.getNodeParameter('limit', i) as number; + responseData = await xeroApiRequest.call(this, 'GET', `/Invoices`, { organizationId }, qs); + responseData = responseData.Invoices; + responseData = responseData.splice(0, limit); + } } } - } - if (resource === 'contact') { - if (operation === 'create') { - const organizationId = this.getNodeParameter('organizationId', i) as string; - const name = this.getNodeParameter('name', i) as string; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - // const addressesUi = additionalFields.addressesUi as IDataObject; - // const phonesUi = additionalFields.phonesUi as IDataObject; + if (resource === 'contact') { + if (operation === 'create') { + const organizationId = this.getNodeParameter('organizationId', i) as string; + const name = this.getNodeParameter('name', i) as string; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + // const addressesUi = additionalFields.addressesUi as IDataObject; + // const phonesUi = additionalFields.phonesUi as IDataObject; - const body: IContact = { - Name: name, - }; + const body: IContact = { + Name: name, + }; - if (additionalFields.accountNumber) { - body.AccountNumber = additionalFields.accountNumber as string; - } + if (additionalFields.accountNumber) { + body.AccountNumber = additionalFields.accountNumber as string; + } - if (additionalFields.bankAccountDetails) { - body.BankAccountDetails = additionalFields.bankAccountDetails as string; - } + if (additionalFields.bankAccountDetails) { + body.BankAccountDetails = additionalFields.bankAccountDetails as string; + } - if (additionalFields.contactNumber) { - body.ContactNumber = additionalFields.contactNumber as string; - } + if (additionalFields.contactNumber) { + body.ContactNumber = additionalFields.contactNumber as string; + } - if (additionalFields.contactStatus) { - body.ContactStatus = additionalFields.contactStatus as string; - } + if (additionalFields.contactStatus) { + body.ContactStatus = additionalFields.contactStatus as string; + } - if (additionalFields.defaultCurrency) { - body.DefaultCurrency = additionalFields.defaultCurrency as string; - } + if (additionalFields.defaultCurrency) { + body.DefaultCurrency = additionalFields.defaultCurrency as string; + } - if (additionalFields.emailAddress) { - body.EmailAddress = additionalFields.emailAddress as string; - } + if (additionalFields.emailAddress) { + body.EmailAddress = additionalFields.emailAddress as string; + } - if (additionalFields.firstName) { - body.FirstName = additionalFields.firstName as string; - } + if (additionalFields.firstName) { + body.FirstName = additionalFields.firstName as string; + } - if (additionalFields.lastName) { - body.LastName = additionalFields.lastName as string; - } + if (additionalFields.lastName) { + body.LastName = additionalFields.lastName as string; + } - if (additionalFields.purchasesDefaultAccountCode) { - body.PurchasesDefaultAccountCode = additionalFields.purchasesDefaultAccountCode as string; - } + if (additionalFields.purchasesDefaultAccountCode) { + body.PurchasesDefaultAccountCode = additionalFields.purchasesDefaultAccountCode as string; + } - if (additionalFields.salesDefaultAccountCode) { - body.SalesDefaultAccountCode = additionalFields.salesDefaultAccountCode as string; - } + if (additionalFields.salesDefaultAccountCode) { + body.SalesDefaultAccountCode = additionalFields.salesDefaultAccountCode as string; + } - if (additionalFields.skypeUserName) { - body.SkypeUserName = additionalFields.skypeUserName as string; - } + if (additionalFields.skypeUserName) { + body.SkypeUserName = additionalFields.skypeUserName as string; + } - if (additionalFields.taxNumber) { - body.taxNumber = additionalFields.taxNumber as string; - } + if (additionalFields.taxNumber) { + body.taxNumber = additionalFields.taxNumber as string; + } - if (additionalFields.xeroNetworkKey) { - body.xeroNetworkKey = additionalFields.xeroNetworkKey as string; - } + if (additionalFields.xeroNetworkKey) { + body.xeroNetworkKey = additionalFields.xeroNetworkKey as string; + } - // if (phonesUi) { - // const phoneValues = phonesUi?.phonesValues as IDataObject[]; - // if (phoneValues) { - // const phones: IPhone[] = []; - // for (const phoneValue of phoneValues) { - // const phone: IPhone = {}; - // phone.Type = phoneValue.type as string; - // phone.PhoneNumber = phoneValue.PhoneNumber as string; - // phone.PhoneAreaCode = phoneValue.phoneAreaCode as string; - // phone.PhoneCountryCode = phoneValue.phoneCountryCode as string; - // phones.push(phone); - // } - // body.Phones = phones; - // } - // } + // if (phonesUi) { + // const phoneValues = phonesUi?.phonesValues as IDataObject[]; + // if (phoneValues) { + // const phones: IPhone[] = []; + // for (const phoneValue of phoneValues) { + // const phone: IPhone = {}; + // phone.Type = phoneValue.type as string; + // phone.PhoneNumber = phoneValue.PhoneNumber as string; + // phone.PhoneAreaCode = phoneValue.phoneAreaCode as string; + // phone.PhoneCountryCode = phoneValue.phoneCountryCode as string; + // phones.push(phone); + // } + // body.Phones = phones; + // } + // } - // if (addressesUi) { - // const addressValues = addressesUi?.addressesValues as IDataObject[]; - // if (addressValues) { - // const addresses: IAddress[] = []; - // for (const addressValue of addressValues) { - // const address: IAddress = {}; - // address.Type = addressValue.type as string; - // address.AddressLine1 = addressValue.line1 as string; - // address.AddressLine2 = addressValue.line2 as string; - // address.City = addressValue.city as string; - // address.Region = addressValue.region as string; - // address.PostalCode = addressValue.postalCode as string; - // address.Country = addressValue.country as string; - // address.AttentionTo = addressValue.attentionTo as string; - // addresses.push(address); - // } - // body.Addresses = addresses; - // } - // } + // if (addressesUi) { + // const addressValues = addressesUi?.addressesValues as IDataObject[]; + // if (addressValues) { + // const addresses: IAddress[] = []; + // for (const addressValue of addressValues) { + // const address: IAddress = {}; + // address.Type = addressValue.type as string; + // address.AddressLine1 = addressValue.line1 as string; + // address.AddressLine2 = addressValue.line2 as string; + // address.City = addressValue.city as string; + // address.Region = addressValue.region as string; + // address.PostalCode = addressValue.postalCode as string; + // address.Country = addressValue.country as string; + // address.AttentionTo = addressValue.attentionTo as string; + // addresses.push(address); + // } + // body.Addresses = addresses; + // } + // } - responseData = await xeroApiRequest.call(this, 'POST', '/Contacts', { organizationId, Contacts: [body] }); - responseData = responseData.Contacts; - } - if (operation === 'get') { - const organizationId = this.getNodeParameter('organizationId', i) as string; - const contactId = this.getNodeParameter('contactId', i) as string; - responseData = await xeroApiRequest.call(this, 'GET', `/Contacts/${contactId}`, { organizationId }); - responseData = responseData.Contacts; - } - if (operation === 'getAll') { - const organizationId = this.getNodeParameter('organizationId', i) as string; - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - const options = this.getNodeParameter('options', i) as IDataObject; - if (options.includeArchived) { - qs.includeArchived = options.includeArchived as boolean; - } - if (options.orderBy) { - qs.order = `${options.orderBy} ${(options.sortOrder === undefined) ? 'DESC' : options.sortOrder}`; - } - if (options.where) { - qs.where = options.where; - } - if (returnAll) { - responseData = await xeroApiRequestAllItems.call(this, 'Contacts', 'GET', '/Contacts', { organizationId }, qs); - } else { - const limit = this.getNodeParameter('limit', i) as number; - responseData = await xeroApiRequest.call(this, 'GET', `/Contacts`, { organizationId }, qs); + responseData = await xeroApiRequest.call(this, 'POST', '/Contacts', { organizationId, Contacts: [body] }); responseData = responseData.Contacts; - responseData = responseData.splice(0, limit); } + if (operation === 'get') { + const organizationId = this.getNodeParameter('organizationId', i) as string; + const contactId = this.getNodeParameter('contactId', i) as string; + responseData = await xeroApiRequest.call(this, 'GET', `/Contacts/${contactId}`, { organizationId }); + responseData = responseData.Contacts; + } + if (operation === 'getAll') { + const organizationId = this.getNodeParameter('organizationId', i) as string; + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + const options = this.getNodeParameter('options', i) as IDataObject; + if (options.includeArchived) { + qs.includeArchived = options.includeArchived as boolean; + } + if (options.orderBy) { + qs.order = `${options.orderBy} ${(options.sortOrder === undefined) ? 'DESC' : options.sortOrder}`; + } + if (options.where) { + qs.where = options.where; + } + if (returnAll) { + responseData = await xeroApiRequestAllItems.call(this, 'Contacts', 'GET', '/Contacts', { organizationId }, qs); + } else { + const limit = this.getNodeParameter('limit', i) as number; + responseData = await xeroApiRequest.call(this, 'GET', `/Contacts`, { organizationId }, qs); + responseData = responseData.Contacts; + responseData = responseData.splice(0, limit); + } + } + if (operation === 'update') { + const organizationId = this.getNodeParameter('organizationId', i) as string; + const contactId = this.getNodeParameter('contactId', i) as string; + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + // const addressesUi = updateFields.addressesUi as IDataObject; + // const phonesUi = updateFields.phonesUi as IDataObject; + + const body: IContact = {}; + + if (updateFields.accountNumber) { + body.AccountNumber = updateFields.accountNumber as string; + } + + if (updateFields.name) { + body.Name = updateFields.name as string; + } + + if (updateFields.bankAccountDetails) { + body.BankAccountDetails = updateFields.bankAccountDetails as string; + } + + if (updateFields.contactNumber) { + body.ContactNumber = updateFields.contactNumber as string; + } + + if (updateFields.contactStatus) { + body.ContactStatus = updateFields.contactStatus as string; + } + + if (updateFields.defaultCurrency) { + body.DefaultCurrency = updateFields.defaultCurrency as string; + } + + if (updateFields.emailAddress) { + body.EmailAddress = updateFields.emailAddress as string; + } + + if (updateFields.firstName) { + body.FirstName = updateFields.firstName as string; + } + + if (updateFields.lastName) { + body.LastName = updateFields.lastName as string; + } + + if (updateFields.purchasesDefaultAccountCode) { + body.PurchasesDefaultAccountCode = updateFields.purchasesDefaultAccountCode as string; + } + + if (updateFields.salesDefaultAccountCode) { + body.SalesDefaultAccountCode = updateFields.salesDefaultAccountCode as string; + } + + if (updateFields.skypeUserName) { + body.SkypeUserName = updateFields.skypeUserName as string; + } + + if (updateFields.taxNumber) { + body.taxNumber = updateFields.taxNumber as string; + } + + if (updateFields.xeroNetworkKey) { + body.xeroNetworkKey = updateFields.xeroNetworkKey as string; + } + + // if (phonesUi) { + // const phoneValues = phonesUi?.phonesValues as IDataObject[]; + // if (phoneValues) { + // const phones: IPhone[] = []; + // for (const phoneValue of phoneValues) { + // const phone: IPhone = {}; + // phone.Type = phoneValue.type as string; + // phone.PhoneNumber = phoneValue.PhoneNumber as string; + // phone.PhoneAreaCode = phoneValue.phoneAreaCode as string; + // phone.PhoneCountryCode = phoneValue.phoneCountryCode as string; + // phones.push(phone); + // } + // body.Phones = phones; + // } + // } + + // if (addressesUi) { + // const addressValues = addressesUi?.addressesValues as IDataObject[]; + // if (addressValues) { + // const addresses: IAddress[] = []; + // for (const addressValue of addressValues) { + // const address: IAddress = {}; + // address.Type = addressValue.type as string; + // address.AddressLine1 = addressValue.line1 as string; + // address.AddressLine2 = addressValue.line2 as string; + // address.City = addressValue.city as string; + // address.Region = addressValue.region as string; + // address.PostalCode = addressValue.postalCode as string; + // address.Country = addressValue.country as string; + // address.AttentionTo = addressValue.attentionTo as string; + // addresses.push(address); + // } + // body.Addresses = addresses; + // } + // } + + responseData = await xeroApiRequest.call(this, 'POST', `/Contacts/${contactId}`, { organizationId, Contacts: [body] }); + responseData = responseData.Contacts; + } } - if (operation === 'update') { - const organizationId = this.getNodeParameter('organizationId', i) as string; - const contactId = this.getNodeParameter('contactId', i) as string; - const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; - // const addressesUi = updateFields.addressesUi as IDataObject; - // const phonesUi = updateFields.phonesUi as IDataObject; - - const body: IContact = {}; - - if (updateFields.accountNumber) { - body.AccountNumber = updateFields.accountNumber as string; - } - - if (updateFields.name) { - body.Name = updateFields.name as string; - } - - if (updateFields.bankAccountDetails) { - body.BankAccountDetails = updateFields.bankAccountDetails as string; - } - - if (updateFields.contactNumber) { - body.ContactNumber = updateFields.contactNumber as string; - } - - if (updateFields.contactStatus) { - body.ContactStatus = updateFields.contactStatus as string; - } - - if (updateFields.defaultCurrency) { - body.DefaultCurrency = updateFields.defaultCurrency as string; - } - - if (updateFields.emailAddress) { - body.EmailAddress = updateFields.emailAddress as string; - } - - if (updateFields.firstName) { - body.FirstName = updateFields.firstName as string; - } - - if (updateFields.lastName) { - body.LastName = updateFields.lastName as string; - } - - if (updateFields.purchasesDefaultAccountCode) { - body.PurchasesDefaultAccountCode = updateFields.purchasesDefaultAccountCode as string; - } - - if (updateFields.salesDefaultAccountCode) { - body.SalesDefaultAccountCode = updateFields.salesDefaultAccountCode as string; - } - - if (updateFields.skypeUserName) { - body.SkypeUserName = updateFields.skypeUserName as string; - } - - if (updateFields.taxNumber) { - body.taxNumber = updateFields.taxNumber as string; - } - - if (updateFields.xeroNetworkKey) { - body.xeroNetworkKey = updateFields.xeroNetworkKey as string; - } - - // if (phonesUi) { - // const phoneValues = phonesUi?.phonesValues as IDataObject[]; - // if (phoneValues) { - // const phones: IPhone[] = []; - // for (const phoneValue of phoneValues) { - // const phone: IPhone = {}; - // phone.Type = phoneValue.type as string; - // phone.PhoneNumber = phoneValue.PhoneNumber as string; - // phone.PhoneAreaCode = phoneValue.phoneAreaCode as string; - // phone.PhoneCountryCode = phoneValue.phoneCountryCode as string; - // phones.push(phone); - // } - // body.Phones = phones; - // } - // } - - // if (addressesUi) { - // const addressValues = addressesUi?.addressesValues as IDataObject[]; - // if (addressValues) { - // const addresses: IAddress[] = []; - // for (const addressValue of addressValues) { - // const address: IAddress = {}; - // address.Type = addressValue.type as string; - // address.AddressLine1 = addressValue.line1 as string; - // address.AddressLine2 = addressValue.line2 as string; - // address.City = addressValue.city as string; - // address.Region = addressValue.region as string; - // address.PostalCode = addressValue.postalCode as string; - // address.Country = addressValue.country as string; - // address.AttentionTo = addressValue.attentionTo as string; - // addresses.push(address); - // } - // body.Addresses = addresses; - // } - // } - - responseData = await xeroApiRequest.call(this, 'POST', `/Contacts/${contactId}`, { organizationId, Contacts: [body] }); - responseData = responseData.Contacts; + if (Array.isArray(responseData)) { + returnData.push.apply(returnData, responseData as IDataObject[]); + } else { + returnData.push(responseData as IDataObject); } - } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else { - returnData.push(responseData as IDataObject); + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } } return [this.helpers.returnJsonArray(returnData)]; diff --git a/packages/nodes-base/nodes/Xml.node.ts b/packages/nodes-base/nodes/Xml.node.ts index 58717c2cc9..2b42926c81 100644 --- a/packages/nodes-base/nodes/Xml.node.ts +++ b/packages/nodes-base/nodes/Xml.node.ts @@ -235,33 +235,42 @@ export class Xml implements INodeType { let item: INodeExecutionData; for (let itemIndex = 0; itemIndex < items.length; itemIndex++) { - item = items[itemIndex]; + try { - if (mode === 'xmlToJson') { - const parserOptions = Object.assign({ - mergeAttrs: true, - explicitArray: false, - }, options); + item = items[itemIndex]; - const parser = new Parser(parserOptions); + if (mode === 'xmlToJson') { + const parserOptions = Object.assign({ + mergeAttrs: true, + explicitArray: false, + }, options); - if (item.json[dataPropertyName] === undefined) { - throw new NodeOperationError(this.getNode(), `No json property "${dataPropertyName}" does not exists on item!`); + const parser = new Parser(parserOptions); + + if (item.json[dataPropertyName] === undefined) { + throw new NodeOperationError(this.getNode(), `No json property "${dataPropertyName}" does not exists on item!`); + } + + // @ts-ignore + const json = await parser.parseStringPromise(item.json[dataPropertyName]); + items[itemIndex] = { json }; + } else if (mode === 'jsonToxml') { + const builder = new Builder(options); + + items[itemIndex] = { + json: { + [dataPropertyName]: builder.buildObject(items[itemIndex].json), + }, + }; + } else { + throw new NodeOperationError(this.getNode(), `The operation "${mode}" is not known!`); } - - // @ts-ignore - const json = await parser.parseStringPromise(item.json[dataPropertyName]); - items[itemIndex] = { json }; - } else if (mode === 'jsonToxml') { - const builder = new Builder(options); - - items[itemIndex] = { - json: { - [dataPropertyName]: builder.buildObject(items[itemIndex].json), - }, - }; - } else { - throw new NodeOperationError(this.getNode(), `The operation "${mode}" is not known!`); + } catch (error) { + if (this.continueOnFail()) { + items[itemIndex] = ({json:{ error: error.message }}); + continue; + } + throw error; } } diff --git a/packages/nodes-base/nodes/Yourls/Yourls.node.ts b/packages/nodes-base/nodes/Yourls/Yourls.node.ts index 0ddf94c7a1..1ca0b41a01 100644 --- a/packages/nodes-base/nodes/Yourls/Yourls.node.ts +++ b/packages/nodes-base/nodes/Yourls/Yourls.node.ts @@ -67,35 +67,43 @@ export class Yourls implements INodeType { 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 === 'url') { - if (operation === 'shorten') { - const url = this.getNodeParameter('url', i) as string; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - qs.url = url; - qs.action = 'shorturl'; - Object.assign(qs, additionalFields); - responseData = await yourlsApiRequest.call(this, 'GET', {}, qs); - } + try { + if (resource === 'url') { + if (operation === 'shorten') { + const url = this.getNodeParameter('url', i) as string; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + qs.url = url; + qs.action = 'shorturl'; + Object.assign(qs, additionalFields); + responseData = await yourlsApiRequest.call(this, 'GET', {}, qs); + } - if (operation === 'expand') { - const shortUrl = this.getNodeParameter('shortUrl', i) as string; - qs.shorturl = shortUrl; - qs.action = 'expand'; - responseData = await yourlsApiRequest.call(this, 'GET', {}, qs); - } + if (operation === 'expand') { + const shortUrl = this.getNodeParameter('shortUrl', i) as string; + qs.shorturl = shortUrl; + qs.action = 'expand'; + responseData = await yourlsApiRequest.call(this, 'GET', {}, qs); + } - if (operation === 'stats') { - const shortUrl = this.getNodeParameter('shortUrl', i) as string; - qs.shorturl = shortUrl; - qs.action = 'url-stats'; - responseData = await yourlsApiRequest.call(this, 'GET', {}, qs); - responseData = responseData.link; + if (operation === 'stats') { + const shortUrl = this.getNodeParameter('shortUrl', i) as string; + qs.shorturl = shortUrl; + qs.action = 'url-stats'; + responseData = await yourlsApiRequest.call(this, 'GET', {}, qs); + responseData = responseData.link; + } } - } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else { - returnData.push(responseData as IDataObject); + if (Array.isArray(responseData)) { + returnData.push.apply(returnData, responseData as IDataObject[]); + } else { + returnData.push(responseData as IDataObject); + } + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } } return [this.helpers.returnJsonArray(returnData)]; diff --git a/packages/nodes-base/nodes/Zendesk/Zendesk.node.ts b/packages/nodes-base/nodes/Zendesk/Zendesk.node.ts index f77b8cc9d8..8340876bf3 100644 --- a/packages/nodes-base/nodes/Zendesk/Zendesk.node.ts +++ b/packages/nodes-base/nodes/Zendesk/Zendesk.node.ts @@ -233,279 +233,287 @@ export class Zendesk implements INodeType { 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; - //https://developer.zendesk.com/rest_api/docs/support/introduction - if (resource === 'ticket') { - //https://developer.zendesk.com/rest_api/docs/support/tickets - if (operation === 'create') { - const description = this.getNodeParameter('description', i) as string; - const jsonParameters = this.getNodeParameter('jsonParameters', i) as boolean; - const comment: IComment = { - body: description, - }; - const body: ITicket = { - comment, - }; - if (jsonParameters) { - const additionalFieldsJson = this.getNodeParameter('additionalFieldsJson', i) as string; + try { + const resource = this.getNodeParameter('resource', 0) as string; + const operation = this.getNodeParameter('operation', 0) as string; + //https://developer.zendesk.com/rest_api/docs/support/introduction + if (resource === 'ticket') { + //https://developer.zendesk.com/rest_api/docs/support/tickets + if (operation === 'create') { + const description = this.getNodeParameter('description', i) as string; + const jsonParameters = this.getNodeParameter('jsonParameters', i) as boolean; + const comment: IComment = { + body: description, + }; + const body: ITicket = { + comment, + }; + if (jsonParameters) { + const additionalFieldsJson = this.getNodeParameter('additionalFieldsJson', i) as string; - if (additionalFieldsJson !== '' ) { + if (additionalFieldsJson !== '' ) { - if (validateJSON(additionalFieldsJson) !== undefined) { + if (validateJSON(additionalFieldsJson) !== undefined) { - Object.assign(body, JSON.parse(additionalFieldsJson)); + Object.assign(body, JSON.parse(additionalFieldsJson)); - } else { - throw new NodeOperationError(this.getNode(), 'Additional fields must be a valid JSON'); + } else { + throw new NodeOperationError(this.getNode(), 'Additional fields must be a valid JSON'); + } + } + + } else { + + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + + if (additionalFields.type) { + body.type = additionalFields.type as string; + } + if (additionalFields.externalId) { + body.external_id = additionalFields.externalId as string; + } + if (additionalFields.subject) { + body.subject = additionalFields.subject as string; + } + if (additionalFields.status) { + body.status = additionalFields.status as string; + } + if (additionalFields.recipient) { + body.recipient = additionalFields.recipient as string; + } + if (additionalFields.group) { + body.group = additionalFields.group as string; + } + if (additionalFields.tags) { + body.tags = additionalFields.tags as string[]; + } + if (additionalFields.customFieldsUi) { + body.custom_fields = (additionalFields.customFieldsUi as IDataObject).customFieldsValues as IDataObject[]; } } + responseData = await zendeskApiRequest.call(this, 'POST', '/tickets', { ticket: body }); + responseData = responseData.ticket; + } + //https://developer.zendesk.com/rest_api/docs/support/tickets#update-ticket + if (operation === 'update') { + const ticketId = this.getNodeParameter('id', i) as string; + const jsonParameters = this.getNodeParameter('jsonParameters', i) as boolean; + const body: ITicket = {}; - } else { + if (jsonParameters) { + const updateFieldsJson = this.getNodeParameter('updateFieldsJson', i) as string; + if (updateFieldsJson !== '' ) { + + if (validateJSON(updateFieldsJson) !== undefined) { + + Object.assign(body, JSON.parse(updateFieldsJson)); + + } else { + throw new NodeOperationError(this.getNode(), 'Additional fields must be a valid JSON'); + } + } + + } else { + + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + + if (updateFields.type) { + body.type = updateFields.type as string; + } + if (updateFields.externalId) { + body.external_id = updateFields.externalId as string; + } + if (updateFields.subject) { + body.subject = updateFields.subject as string; + } + if (updateFields.status) { + body.status = updateFields.status as string; + } + if (updateFields.recipient) { + body.recipient = updateFields.recipient as string; + } + if (updateFields.group) { + body.group = updateFields.group as string; + } + if (updateFields.tags) { + body.tags = updateFields.tags as string[]; + } + if (updateFields.customFieldsUi) { + body.custom_fields = (updateFields.customFieldsUi as IDataObject).customFieldsValues as IDataObject[]; + } + } + responseData = await zendeskApiRequest.call(this, 'PUT', `/tickets/${ticketId}`, { ticket: body }); + responseData = responseData.ticket; + } + //https://developer.zendesk.com/rest_api/docs/support/tickets#show-ticket + if (operation === 'get') { + const ticketId = this.getNodeParameter('id', i) as string; + responseData = await zendeskApiRequest.call(this, 'GET', `/tickets/${ticketId}`, {}); + responseData = responseData.ticket; + } + //https://developer.zendesk.com/rest_api/docs/support/search#list-search-results + if (operation === 'getAll') { + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + const options = this.getNodeParameter('options', i) as IDataObject; + qs.query = 'type:ticket'; + if (options.status) { + qs.query += ` status:${options.status}`; + } + if (options.sortBy) { + qs.sort_by = options.sortBy; + } + if (options.sortOrder) { + qs.sort_order = options.sortOrder; + } + if (returnAll) { + responseData = await zendeskApiRequestAllItems.call(this, 'results', 'GET', `/search`, {}, qs); + } else { + const limit = this.getNodeParameter('limit', i) as number; + qs.per_page = limit; + responseData = await zendeskApiRequest.call(this, 'GET', `/search`, {}, qs); + responseData = responseData.results; + } + } + //https://developer.zendesk.com/rest_api/docs/support/tickets#delete-ticket + if (operation === 'delete') { + const ticketId = this.getNodeParameter('id', i) as string; + try { + responseData = await zendeskApiRequest.call(this, 'DELETE', `/tickets/${ticketId}`, {}); + } catch (error) { + throw new NodeApiError(this.getNode(), error); + } + } + } + //https://developer.zendesk.com/rest_api/docs/support/ticket_fields + if (resource === 'ticketField') { + //https://developer.zendesk.com/rest_api/docs/support/tickets#show-ticket + if (operation === 'get') { + const ticketFieldId = this.getNodeParameter('ticketFieldId', i) as string; + responseData = await zendeskApiRequest.call(this, 'GET', `/ticket_fields/${ticketFieldId}`, {}); + responseData = responseData.ticket_field; + } + //https://developer.zendesk.com/rest_api/docs/support/ticket_fields#list-ticket-fields + if (operation === 'getAll') { + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + if (returnAll) { + responseData = await zendeskApiRequestAllItems.call(this, 'ticket_fields', 'GET', '/ticket_fields', {}, qs); + } else { + const limit = this.getNodeParameter('limit', i) as number; + qs.limit = limit; + responseData = await zendeskApiRequestAllItems.call(this, 'ticket_fields', 'GET', '/ticket_fields', {}, qs); + responseData = responseData.slice(0, limit); + } + } + } + //https://developer.zendesk.com/rest_api/docs/support/users + if (resource === 'user') { + //https://developer.zendesk.com/rest_api/docs/support/users#create-user + if (operation === 'create') { + const name = this.getNodeParameter('name', i) as string; const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - if (additionalFields.type) { - body.type = additionalFields.type as string; - } - if (additionalFields.externalId) { - body.external_id = additionalFields.externalId as string; - } - if (additionalFields.subject) { - body.subject = additionalFields.subject as string; - } - if (additionalFields.status) { - body.status = additionalFields.status as string; - } - if (additionalFields.recipient) { - body.recipient = additionalFields.recipient as string; - } - if (additionalFields.group) { - body.group = additionalFields.group as string; - } - if (additionalFields.tags) { - body.tags = additionalFields.tags as string[]; - } - if (additionalFields.customFieldsUi) { - body.custom_fields = (additionalFields.customFieldsUi as IDataObject).customFieldsValues as IDataObject[]; - } - } - responseData = await zendeskApiRequest.call(this, 'POST', '/tickets', { ticket: body }); - responseData = responseData.ticket; - } - //https://developer.zendesk.com/rest_api/docs/support/tickets#update-ticket - if (operation === 'update') { - const ticketId = this.getNodeParameter('id', i) as string; - const jsonParameters = this.getNodeParameter('jsonParameters', i) as boolean; - const body: ITicket = {}; + const body: IDataObject = { + name, + }; - if (jsonParameters) { - const updateFieldsJson = this.getNodeParameter('updateFieldsJson', i) as string; + Object.assign(body, additionalFields); - if (updateFieldsJson !== '' ) { - - if (validateJSON(updateFieldsJson) !== undefined) { - - Object.assign(body, JSON.parse(updateFieldsJson)); - - } else { - throw new NodeOperationError(this.getNode(), 'Additional fields must be a valid JSON'); + if (body.userFieldsUi) { + const userFields = (body.userFieldsUi as IDataObject).userFieldValues as IDataObject[]; + if (userFields) { + body.user_fields = {}; + for (const userField of userFields) { + //@ts-ignore + body.user_fields[userField.field] = userField.value; + } + delete body.userFieldsUi; } } - } else { - + responseData = await zendeskApiRequest.call(this, 'POST', '/users', { user: body }); + responseData = responseData.user; + } + //https://developer.zendesk.com/rest_api/docs/support/tickets#update-ticket + if (operation === 'update') { + const userId = this.getNodeParameter('id', i) as string; const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; - if (updateFields.type) { - body.type = updateFields.type as string; - } - if (updateFields.externalId) { - body.external_id = updateFields.externalId as string; - } - if (updateFields.subject) { - body.subject = updateFields.subject as string; - } - if (updateFields.status) { - body.status = updateFields.status as string; - } - if (updateFields.recipient) { - body.recipient = updateFields.recipient as string; - } - if (updateFields.group) { - body.group = updateFields.group as string; - } - if (updateFields.tags) { - body.tags = updateFields.tags as string[]; - } - if (updateFields.customFieldsUi) { - body.custom_fields = (updateFields.customFieldsUi as IDataObject).customFieldsValues as IDataObject[]; - } - } - responseData = await zendeskApiRequest.call(this, 'PUT', `/tickets/${ticketId}`, { ticket: body }); - responseData = responseData.ticket; - } - //https://developer.zendesk.com/rest_api/docs/support/tickets#show-ticket - if (operation === 'get') { - const ticketId = this.getNodeParameter('id', i) as string; - responseData = await zendeskApiRequest.call(this, 'GET', `/tickets/${ticketId}`, {}); - responseData = responseData.ticket; - } - //https://developer.zendesk.com/rest_api/docs/support/search#list-search-results - if (operation === 'getAll') { - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - const options = this.getNodeParameter('options', i) as IDataObject; - qs.query = 'type:ticket'; - if (options.status) { - qs.query += ` status:${options.status}`; - } - if (options.sortBy) { - qs.sort_by = options.sortBy; - } - if (options.sortOrder) { - qs.sort_order = options.sortOrder; - } - if (returnAll) { - responseData = await zendeskApiRequestAllItems.call(this, 'results', 'GET', `/search`, {}, qs); - } else { - const limit = this.getNodeParameter('limit', i) as number; - qs.per_page = limit; - responseData = await zendeskApiRequest.call(this, 'GET', `/search`, {}, qs); - responseData = responseData.results; - } - } - //https://developer.zendesk.com/rest_api/docs/support/tickets#delete-ticket - if (operation === 'delete') { - const ticketId = this.getNodeParameter('id', i) as string; - try { - responseData = await zendeskApiRequest.call(this, 'DELETE', `/tickets/${ticketId}`, {}); - } catch (error) { - throw new NodeApiError(this.getNode(), error); - } - } - } - //https://developer.zendesk.com/rest_api/docs/support/ticket_fields - if (resource === 'ticketField') { - //https://developer.zendesk.com/rest_api/docs/support/tickets#show-ticket - if (operation === 'get') { - const ticketFieldId = this.getNodeParameter('ticketFieldId', i) as string; - responseData = await zendeskApiRequest.call(this, 'GET', `/ticket_fields/${ticketFieldId}`, {}); - responseData = responseData.ticket_field; - } - //https://developer.zendesk.com/rest_api/docs/support/ticket_fields#list-ticket-fields - if (operation === 'getAll') { - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - if (returnAll) { - responseData = await zendeskApiRequestAllItems.call(this, 'ticket_fields', 'GET', '/ticket_fields', {}, qs); - } else { - const limit = this.getNodeParameter('limit', i) as number; - qs.limit = limit; - responseData = await zendeskApiRequestAllItems.call(this, 'ticket_fields', 'GET', '/ticket_fields', {}, qs); - responseData = responseData.slice(0, limit); - } - } - } - //https://developer.zendesk.com/rest_api/docs/support/users - if (resource === 'user') { - //https://developer.zendesk.com/rest_api/docs/support/users#create-user - if (operation === 'create') { - const name = this.getNodeParameter('name', i) as string; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const body: IDataObject = {}; - const body: IDataObject = { - name, - }; + Object.assign(body, updateFields); - Object.assign(body, additionalFields); - - if (body.userFieldsUi) { - const userFields = (body.userFieldsUi as IDataObject).userFieldValues as IDataObject[]; - if (userFields) { - body.user_fields = {}; - for (const userField of userFields) { - //@ts-ignore - body.user_fields[userField.field] = userField.value; + if (body.userFieldsUi) { + const userFields = (body.userFieldsUi as IDataObject).userFieldValues as IDataObject[]; + if (userFields) { + body.user_fields = {}; + for (const userField of userFields) { + //@ts-ignore + body.user_fields[userField.field] = userField.value; + } + delete body.userFieldsUi; } - delete body.userFieldsUi; + } + + responseData = await zendeskApiRequest.call(this, 'PUT', `/users/${userId}`, { user: body }); + responseData = responseData.user; + } + //https://developer.zendesk.com/rest_api/docs/support/users#show-user + if (operation === 'get') { + const userId = this.getNodeParameter('id', i) as string; + responseData = await zendeskApiRequest.call(this, 'GET', `/users/${userId}`, {}); + responseData = responseData.user; + } + //https://developer.zendesk.com/rest_api/docs/support/users#list-users + if (operation === 'getAll') { + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + const options = this.getNodeParameter('filters', i) as IDataObject; + + Object.assign(qs, options); + + if (returnAll) { + responseData = await zendeskApiRequestAllItems.call(this, 'users', 'GET', `/users`, {}, qs); + } else { + const limit = this.getNodeParameter('limit', i) as number; + qs.per_page = limit; + responseData = await zendeskApiRequest.call(this, 'GET', `/users`, {}, qs); + responseData = responseData.users; } } + //https://developer.zendesk.com/rest_api/docs/support/users#search-users + if (operation === 'search') { + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + const options = this.getNodeParameter('filters', i) as IDataObject; - responseData = await zendeskApiRequest.call(this, 'POST', '/users', { user: body }); - responseData = responseData.user; - } - //https://developer.zendesk.com/rest_api/docs/support/tickets#update-ticket - if (operation === 'update') { - const userId = this.getNodeParameter('id', i) as string; - const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + Object.assign(qs, options); - const body: IDataObject = {}; - - Object.assign(body, updateFields); - - if (body.userFieldsUi) { - const userFields = (body.userFieldsUi as IDataObject).userFieldValues as IDataObject[]; - if (userFields) { - body.user_fields = {}; - for (const userField of userFields) { - //@ts-ignore - body.user_fields[userField.field] = userField.value; - } - delete body.userFieldsUi; + if (returnAll) { + responseData = await zendeskApiRequestAllItems.call(this, 'users', 'GET', `/users/search`, {}, qs); + } else { + const limit = this.getNodeParameter('limit', i) as number; + qs.per_page = limit; + responseData = await zendeskApiRequest.call(this, 'GET', `/users/search`, {}, qs); + responseData = responseData.users; } } - - responseData = await zendeskApiRequest.call(this, 'PUT', `/users/${userId}`, { user: body }); - responseData = responseData.user; - } - //https://developer.zendesk.com/rest_api/docs/support/users#show-user - if (operation === 'get') { - const userId = this.getNodeParameter('id', i) as string; - responseData = await zendeskApiRequest.call(this, 'GET', `/users/${userId}`, {}); - responseData = responseData.user; - } - //https://developer.zendesk.com/rest_api/docs/support/users#list-users - if (operation === 'getAll') { - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - const options = this.getNodeParameter('filters', i) as IDataObject; - - Object.assign(qs, options); - - if (returnAll) { - responseData = await zendeskApiRequestAllItems.call(this, 'users', 'GET', `/users`, {}, qs); - } else { - const limit = this.getNodeParameter('limit', i) as number; - qs.per_page = limit; - responseData = await zendeskApiRequest.call(this, 'GET', `/users`, {}, qs); - responseData = responseData.users; + //https://developer.zendesk.com/rest_api/docs/support/users#delete-user + if (operation === 'delete') { + const userId = this.getNodeParameter('id', i) as string; + responseData = await zendeskApiRequest.call(this, 'DELETE', `/users/${userId}`, {}); + responseData = responseData.user; } } - //https://developer.zendesk.com/rest_api/docs/support/users#search-users - if (operation === 'search') { - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - const options = this.getNodeParameter('filters', i) as IDataObject; - - Object.assign(qs, options); - - if (returnAll) { - responseData = await zendeskApiRequestAllItems.call(this, 'users', 'GET', `/users/search`, {}, qs); - } else { - const limit = this.getNodeParameter('limit', i) as number; - qs.per_page = limit; - responseData = await zendeskApiRequest.call(this, 'GET', `/users/search`, {}, qs); - responseData = responseData.users; - } + if (Array.isArray(responseData)) { + returnData.push.apply(returnData, responseData as IDataObject[]); + } else { + returnData.push(responseData as IDataObject); } - //https://developer.zendesk.com/rest_api/docs/support/users#delete-user - if (operation === 'delete') { - const userId = this.getNodeParameter('id', i) as string; - responseData = await zendeskApiRequest.call(this, 'DELETE', `/users/${userId}`, {}); - responseData = responseData.user; + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; } - } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else { - returnData.push(responseData as IDataObject); + throw error; } } return [this.helpers.returnJsonArray(returnData)]; diff --git a/packages/nodes-base/nodes/Zoom/Zoom.node.ts b/packages/nodes-base/nodes/Zoom/Zoom.node.ts index 29d1511c51..64e6c9899d 100644 --- a/packages/nodes-base/nodes/Zoom/Zoom.node.ts +++ b/packages/nodes-base/nodes/Zoom/Zoom.node.ts @@ -177,643 +177,651 @@ export class Zoom implements INodeType { const operation = this.getNodeParameter('operation', 0) as string; for (let i = 0; i < items.length; i++) { - qs = {}; - //https://marketplace.zoom.us/docs/api-reference/zoom-api/ - if (resource === 'meeting') { + try { + qs = {}; + //https://marketplace.zoom.us/docs/api-reference/zoom-api/ + if (resource === 'meeting') { - if (operation === 'get') { - //https://marketplace.zoom.us/docs/api-reference/zoom-api/meetings/meeting - const meetingId = this.getNodeParameter('meetingId', i) as string; - const additionalFields = this.getNodeParameter( - 'additionalFields', - i, - ) as IDataObject; + if (operation === 'get') { + //https://marketplace.zoom.us/docs/api-reference/zoom-api/meetings/meeting + const meetingId = this.getNodeParameter('meetingId', i) as string; + const additionalFields = this.getNodeParameter( + 'additionalFields', + i, + ) as IDataObject; - if (additionalFields.showPreviousOccurrences) { - qs.show_previous_occurrences = additionalFields.showPreviousOccurrences as boolean; + if (additionalFields.showPreviousOccurrences) { + qs.show_previous_occurrences = additionalFields.showPreviousOccurrences as boolean; + } + + if (additionalFields.occurrenceId) { + qs.occurrence_id = additionalFields.occurrenceId as string; + } + + responseData = await zoomApiRequest.call( + this, + 'GET', + `/meetings/${meetingId}`, + {}, + qs, + ); } + if (operation === 'getAll') { + //https://marketplace.zoom.us/docs/api-reference/zoom-api/meetings/meetings + const returnAll = this.getNodeParameter('returnAll', i) as boolean; - if (additionalFields.occurrenceId) { - qs.occurrence_id = additionalFields.occurrenceId as string; - } - - responseData = await zoomApiRequest.call( - this, - 'GET', - `/meetings/${meetingId}`, - {}, - qs, - ); - } - if (operation === 'getAll') { - //https://marketplace.zoom.us/docs/api-reference/zoom-api/meetings/meetings - const returnAll = this.getNodeParameter('returnAll', i) as boolean; - - const filters = this.getNodeParameter( - 'filters', - i, - ) as IDataObject; - if (filters.type) { - qs.type = filters.type as string; - } - - if (returnAll) { - responseData = await zoomApiRequestAllItems.call(this, 'meetings', 'GET', '/users/me/meetings', {}, qs); - } else { - qs.page_size = this.getNodeParameter('limit', i) as number; - responseData = await zoomApiRequest.call(this, 'GET', '/users/me/meetings', {}, qs); - responseData = responseData.meetings; - } - - } - if (operation === 'delete') { - //https://marketplace.zoom.us/docs/api-reference/zoom-api/meetings/meetingdelete - const meetingId = this.getNodeParameter('meetingId', i) as string; - const additionalFields = this.getNodeParameter( - 'additionalFields', - i, - ) as IDataObject; - if (additionalFields.scheduleForReminder) { - qs.schedule_for_reminder = additionalFields.scheduleForReminder as boolean; - } - - if (additionalFields.occurrenceId) { - qs.occurrence_id = additionalFields.occurrenceId; - } - - responseData = await zoomApiRequest.call( - this, - 'DELETE', - `/meetings/${meetingId}`, - {}, - qs, - ); - responseData = { success: true }; - } - if (operation === 'create') { - //https://marketplace.zoom.us/docs/api-reference/zoom-api/meetings/meetingcreate - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - - const body: IDataObject = {}; - - if (additionalFields.settings) { - const settingValues: Settings = {}; - const settings = additionalFields.settings as IDataObject; - - if (settings.cnMeeting) { - settingValues.cn_meeting = settings.cnMeeting as boolean; + const filters = this.getNodeParameter( + 'filters', + i, + ) as IDataObject; + if (filters.type) { + qs.type = filters.type as string; } - if (settings.inMeeting) { - settingValues.in_meeting = settings.inMeeting as boolean; - } - - if (settings.joinBeforeHost) { - settingValues.join_before_host = settings.joinBeforeHost as boolean; - } - - if (settings.muteUponEntry) { - settingValues.mute_upon_entry = settings.muteUponEntry as boolean; - } - - if (settings.watermark) { - settingValues.watermark = settings.watermark as boolean; - } - - if (settings.audio) { - settingValues.audio = settings.audio as string; - } - - if (settings.alternativeHosts) { - settingValues.alternative_hosts = settings.alternativeHosts as string; - } - - if (settings.participantVideo) { - settingValues.participant_video = settings.participantVideo as boolean; - } - - if (settings.hostVideo) { - settingValues.host_video = settings.hostVideo as boolean; - } - - if (settings.autoRecording) { - settingValues.auto_recording = settings.autoRecording as string; - } - - if (settings.registrationType) { - settingValues.registration_type = settings.registrationType as number; - } - - body.settings = settingValues; - } - - body.topic = this.getNodeParameter('topic', i) as string; - - if (additionalFields.type) { - body.type = additionalFields.type as string; - } - - if (additionalFields.startTime) { - if (additionalFields.timeZone) { - body.start_time = moment(additionalFields.startTime as string).format('YYYY-MM-DDTHH:mm:ss'); + if (returnAll) { + responseData = await zoomApiRequestAllItems.call(this, 'meetings', 'GET', '/users/me/meetings', {}, qs); } else { - // if none timezone it's defined used n8n timezone - body.start_time = moment.tz(additionalFields.startTime as string, this.getTimezone()).format(); + qs.page_size = this.getNodeParameter('limit', i) as number; + responseData = await zoomApiRequest.call(this, 'GET', '/users/me/meetings', {}, qs); + responseData = responseData.meetings; } - } - if (additionalFields.duration) { - body.duration = additionalFields.duration as number; } + if (operation === 'delete') { + //https://marketplace.zoom.us/docs/api-reference/zoom-api/meetings/meetingdelete + const meetingId = this.getNodeParameter('meetingId', i) as string; + const additionalFields = this.getNodeParameter( + 'additionalFields', + i, + ) as IDataObject; + if (additionalFields.scheduleForReminder) { + qs.schedule_for_reminder = additionalFields.scheduleForReminder as boolean; + } - if (additionalFields.scheduleFor) { - body.schedule_for = additionalFields.scheduleFor as string; + if (additionalFields.occurrenceId) { + qs.occurrence_id = additionalFields.occurrenceId; + } + + responseData = await zoomApiRequest.call( + this, + 'DELETE', + `/meetings/${meetingId}`, + {}, + qs, + ); + responseData = { success: true }; } + if (operation === 'create') { + //https://marketplace.zoom.us/docs/api-reference/zoom-api/meetings/meetingcreate + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - if (additionalFields.timeZone) { - body.timezone = additionalFields.timeZone as string; + const body: IDataObject = {}; + + if (additionalFields.settings) { + const settingValues: Settings = {}; + const settings = additionalFields.settings as IDataObject; + + if (settings.cnMeeting) { + settingValues.cn_meeting = settings.cnMeeting as boolean; + } + + if (settings.inMeeting) { + settingValues.in_meeting = settings.inMeeting as boolean; + } + + if (settings.joinBeforeHost) { + settingValues.join_before_host = settings.joinBeforeHost as boolean; + } + + if (settings.muteUponEntry) { + settingValues.mute_upon_entry = settings.muteUponEntry as boolean; + } + + if (settings.watermark) { + settingValues.watermark = settings.watermark as boolean; + } + + if (settings.audio) { + settingValues.audio = settings.audio as string; + } + + if (settings.alternativeHosts) { + settingValues.alternative_hosts = settings.alternativeHosts as string; + } + + if (settings.participantVideo) { + settingValues.participant_video = settings.participantVideo as boolean; + } + + if (settings.hostVideo) { + settingValues.host_video = settings.hostVideo as boolean; + } + + if (settings.autoRecording) { + settingValues.auto_recording = settings.autoRecording as string; + } + + if (settings.registrationType) { + settingValues.registration_type = settings.registrationType as number; + } + + body.settings = settingValues; + } + + body.topic = this.getNodeParameter('topic', i) as string; + + if (additionalFields.type) { + body.type = additionalFields.type as string; + } + + if (additionalFields.startTime) { + if (additionalFields.timeZone) { + body.start_time = moment(additionalFields.startTime as string).format('YYYY-MM-DDTHH:mm:ss'); + } else { + // if none timezone it's defined used n8n timezone + body.start_time = moment.tz(additionalFields.startTime as string, this.getTimezone()).format(); + } + } + + if (additionalFields.duration) { + body.duration = additionalFields.duration as number; + } + + if (additionalFields.scheduleFor) { + body.schedule_for = additionalFields.scheduleFor as string; + } + + if (additionalFields.timeZone) { + body.timezone = additionalFields.timeZone as string; + } + + if (additionalFields.password) { + body.password = additionalFields.password as string; + } + + if (additionalFields.agenda) { + body.agenda = additionalFields.agenda as string; + } + + responseData = await zoomApiRequest.call( + this, + 'POST', + `/users/me/meetings`, + body, + qs, + ); } + if (operation === 'update') { + //https://marketplace.zoom.us/docs/api-reference/zoom-api/meetings/meetingupdate + const meetingId = this.getNodeParameter('meetingId', i) as string; + const updateFields = this.getNodeParameter( + 'updateFields', + i, + ) as IDataObject; + + const body: IDataObject = {}; + + if (updateFields.settings) { + const settingValues: Settings = {}; + const settings = updateFields.settings as IDataObject; + + if (settings.cnMeeting) { + settingValues.cn_meeting = settings.cnMeeting as boolean; + } + + if (settings.inMeeting) { + settingValues.in_meeting = settings.inMeeting as boolean; + } + + if (settings.joinBeforeHost) { + settingValues.join_before_host = settings.joinBeforeHost as boolean; + } + + if (settings.muteUponEntry) { + settingValues.mute_upon_entry = settings.muteUponEntry as boolean; + } + + if (settings.watermark) { + settingValues.watermark = settings.watermark as boolean; + } + + if (settings.audio) { + settingValues.audio = settings.audio as string; + } + + if (settings.alternativeHosts) { + settingValues.alternative_hosts = settings.alternativeHosts as string; + } + + if (settings.participantVideo) { + settingValues.participant_video = settings.participantVideo as boolean; + } + + if (settings.hostVideo) { + settingValues.host_video = settings.hostVideo as boolean; + } + + if (settings.autoRecording) { + settingValues.auto_recording = settings.autoRecording as string; + } + + if (settings.registrationType) { + settingValues.registration_type = settings.registrationType as number; + } + + body.settings = settingValues; + } + + if (updateFields.topic) { + body.topic = updateFields.topic as string; + } + + if (updateFields.type) { + body.type = updateFields.type as string; + } + + if (updateFields.startTime) { + body.start_time = updateFields.startTime as string; + } + + if (updateFields.duration) { + body.duration = updateFields.duration as number; + } + + if (updateFields.scheduleFor) { + body.schedule_for = updateFields.scheduleFor as string; + } + + if (updateFields.timeZone) { + body.timezone = updateFields.timeZone as string; + } + + if (updateFields.password) { + body.password = updateFields.password as string; + } + + if (updateFields.agenda) { + body.agenda = updateFields.agenda as string; + } + + responseData = await zoomApiRequest.call( + this, + 'PATCH', + `/meetings/${meetingId}`, + body, + qs, + ); + + responseData = { success: true }; - if (additionalFields.password) { - body.password = additionalFields.password as string; } - - if (additionalFields.agenda) { - body.agenda = additionalFields.agenda as string; - } - - responseData = await zoomApiRequest.call( - this, - 'POST', - `/users/me/meetings`, - body, - qs, - ); } - if (operation === 'update') { - //https://marketplace.zoom.us/docs/api-reference/zoom-api/meetings/meetingupdate - const meetingId = this.getNodeParameter('meetingId', i) as string; - const updateFields = this.getNodeParameter( - 'updateFields', - i, - ) as IDataObject; + // if (resource === 'meetingRegistrant') { + // if (operation === 'create') { + // //https://marketplace.zoom.us/docs/api-reference/zoom-api/meetings/meetingregistrantcreate + // const meetingId = this.getNodeParameter('meetingId', i) as string; + // const emailId = this.getNodeParameter('email', i) as string; + // body.email = emailId; + // const firstName = this.getNodeParameter('firstName', i) as string; + // body.first_name = firstName; + // const additionalFields = this.getNodeParameter( + // 'additionalFields', + // i + // ) as IDataObject; + // if (additionalFields.occurrenceId) { + // qs.occurrence_ids = additionalFields.occurrenceId as string; + // } + // if (additionalFields.lastName) { + // body.last_name = additionalFields.lastName as string; + // } + // if (additionalFields.address) { + // body.address = additionalFields.address as string; + // } + // if (additionalFields.city) { + // body.city = additionalFields.city as string; + // } + // if (additionalFields.state) { + // body.state = additionalFields.state as string; + // } + // if (additionalFields.country) { + // body.country = additionalFields.country as string; + // } + // if (additionalFields.zip) { + // body.zip = additionalFields.zip as string; + // } + // if (additionalFields.phone) { + // body.phone = additionalFields.phone as string; + // } + // if (additionalFields.comments) { + // body.comments = additionalFields.comments as string; + // } + // if (additionalFields.org) { + // body.org = additionalFields.org as string; + // } + // if (additionalFields.jobTitle) { + // body.job_title = additionalFields.jobTitle as string; + // } + // if (additionalFields.purchasingTimeFrame) { + // body.purchasing_time_frame = additionalFields.purchasingTimeFrame as string; + // } + // if (additionalFields.roleInPurchaseProcess) { + // body.role_in_purchase_process = additionalFields.roleInPurchaseProcess as string; + // } + // responseData = await zoomApiRequest.call( + // this, + // 'POST', + // `/meetings/${meetingId}/registrants`, + // body, + // qs + // ); + // } + // if (operation === 'getAll') { + // //https://marketplace.zoom.us/docs/api-reference/zoom-api/meetings/meetingregistrants + // const meetingId = this.getNodeParameter('meetingId', i) as string; + // const additionalFields = this.getNodeParameter( + // 'additionalFields', + // i + // ) as IDataObject; + // if (additionalFields.occurrenceId) { + // qs.occurrence_id = additionalFields.occurrenceId as string; + // } + // if (additionalFields.status) { + // qs.status = additionalFields.status as string; + // } + // const returnAll = this.getNodeParameter('returnAll', i) as boolean; + // if (returnAll) { + // responseData = await zoomApiRequestAllItems.call(this, 'results', 'GET', `/meetings/${meetingId}/registrants`, {}, qs); + // } else { + // qs.page_size = this.getNodeParameter('limit', i) as number; + // responseData = await zoomApiRequest.call(this, 'GET', `/meetings/${meetingId}/registrants`, {}, qs); - const body: IDataObject = {}; + // } - if (updateFields.settings) { - const settingValues: Settings = {}; - const settings = updateFields.settings as IDataObject; + // } + // if (operation === 'update') { + // //https://marketplace.zoom.us/docs/api-reference/zoom-api/meetings/meetingregistrantstatus + // const meetingId = this.getNodeParameter('meetingId', i) as string; + // const additionalFields = this.getNodeParameter( + // 'additionalFields', + // i + // ) as IDataObject; + // if (additionalFields.occurrenceId) { + // qs.occurrence_id = additionalFields.occurrenceId as string; + // } + // if (additionalFields.action) { + // body.action = additionalFields.action as string; + // } + // responseData = await zoomApiRequest.call( + // this, + // 'PUT', + // `/meetings/${meetingId}/registrants/status`, + // body, + // qs + // ); + // } + // } + // if (resource === 'webinar') { + // if (operation === 'create') { + // //https://marketplace.zoom.us/docs/api-reference/zoom-api/webinars/webinarcreate + // const userId = this.getNodeParameter('userId', i) as string; + // const additionalFields = this.getNodeParameter( + // 'additionalFields', + // i + // ) as IDataObject; + // const settings: Settings = {}; - if (settings.cnMeeting) { - settingValues.cn_meeting = settings.cnMeeting as boolean; - } - if (settings.inMeeting) { - settingValues.in_meeting = settings.inMeeting as boolean; - } + // if (additionalFields.audio) { + // settings.audio = additionalFields.audio as string; - if (settings.joinBeforeHost) { - settingValues.join_before_host = settings.joinBeforeHost as boolean; - } + // } - if (settings.muteUponEntry) { - settingValues.mute_upon_entry = settings.muteUponEntry as boolean; - } + // if (additionalFields.alternativeHosts) { + // settings.alternative_hosts = additionalFields.alternativeHosts as string; - if (settings.watermark) { - settingValues.watermark = settings.watermark as boolean; - } + // } - if (settings.audio) { - settingValues.audio = settings.audio as string; - } + // if (additionalFields.panelistsVideo) { + // settings.panelists_video = additionalFields.panelistsVideo as boolean; - if (settings.alternativeHosts) { - settingValues.alternative_hosts = settings.alternativeHosts as string; - } + // } + // if (additionalFields.hostVideo) { + // settings.host_video = additionalFields.hostVideo as boolean; - if (settings.participantVideo) { - settingValues.participant_video = settings.participantVideo as boolean; - } + // } + // if (additionalFields.practiceSession) { + // settings.practice_session = additionalFields.practiceSession as boolean; - if (settings.hostVideo) { - settingValues.host_video = settings.hostVideo as boolean; - } + // } + // if (additionalFields.autoRecording) { + // settings.auto_recording = additionalFields.autoRecording as string; - if (settings.autoRecording) { - settingValues.auto_recording = settings.autoRecording as string; - } + // } - if (settings.registrationType) { - settingValues.registration_type = settings.registrationType as number; - } + // if (additionalFields.registrationType) { + // settings.registration_type = additionalFields.registrationType as number; - body.settings = settingValues; - } + // } + // if (additionalFields.approvalType) { + // settings.approval_type = additionalFields.approvalType as number; - if (updateFields.topic) { - body.topic = updateFields.topic as string; - } + // } - if (updateFields.type) { - body.type = updateFields.type as string; - } + // body = { + // settings, + // }; - if (updateFields.startTime) { - body.start_time = updateFields.startTime as string; - } + // if (additionalFields.topic) { + // body.topic = additionalFields.topic as string; - if (updateFields.duration) { - body.duration = updateFields.duration as number; - } + // } - if (updateFields.scheduleFor) { - body.schedule_for = updateFields.scheduleFor as string; - } + // if (additionalFields.type) { + // body.type = additionalFields.type as string; - if (updateFields.timeZone) { - body.timezone = updateFields.timeZone as string; - } + // } - if (updateFields.password) { - body.password = updateFields.password as string; - } + // if (additionalFields.startTime) { + // body.start_time = additionalFields.startTime as string; - if (updateFields.agenda) { - body.agenda = updateFields.agenda as string; - } + // } - responseData = await zoomApiRequest.call( - this, - 'PATCH', - `/meetings/${meetingId}`, - body, - qs, - ); + // if (additionalFields.duration) { + // body.duration = additionalFields.duration as number; - responseData = { success: true }; + // } + + // if (additionalFields.timeZone) { + // body.timezone = additionalFields.timeZone as string; + + // } + + // if (additionalFields.password) { + // body.password = additionalFields.password as string; + + // } + + // if (additionalFields.agenda) { + // body.agenda = additionalFields.agenda as string; + + // } + // responseData = await zoomApiRequest.call( + // this, + // 'POST', + // `/users/${userId}/webinars`, + // body, + // qs + // ); + // } + // if (operation === 'get') { + // //https://marketplace.zoom.us/docs/api-reference/zoom-api/webinars/webinar + // const webinarId = this.getNodeParameter('webinarId', i) as string; + + // const additionalFields = this.getNodeParameter( + // 'additionalFields', + // i + // ) as IDataObject; + // if (additionalFields.showPreviousOccurrences) { + // qs.show_previous_occurrences = additionalFields.showPreviousOccurrences as boolean; + + // } + + // if (additionalFields.occurrenceId) { + // qs.occurrence_id = additionalFields.occurrenceId as string; + + // } + + // responseData = await zoomApiRequest.call( + // this, + // 'GET', + // `/webinars/${webinarId}`, + // {}, + // qs + // ); + // } + // if (operation === 'getAll') { + // //https://marketplace.zoom.us/docs/api-reference/zoom-api/webinars/webinars + // const userId = this.getNodeParameter('userId', i) as string; + // const returnAll = this.getNodeParameter('returnAll', i) as boolean; + // if (returnAll) { + // responseData = await zoomApiRequestAllItems.call(this, 'results', 'GET', `/users/${userId}/webinars`, {}, qs); + // } else { + // qs.page_size = this.getNodeParameter('limit', i) as number; + // responseData = await zoomApiRequest.call(this, 'GET', `/users/${userId}/webinars`, {}, qs); + + // } + // } + // if (operation === 'delete') { + // //https://marketplace.zoom.us/docs/api-reference/zoom-api/webinars/webinardelete + // const webinarId = this.getNodeParameter('webinarId', i) as string; + // const additionalFields = this.getNodeParameter( + // 'additionalFields', + // i + // ) as IDataObject; + + + // if (additionalFields.occurrenceId) { + // qs.occurrence_id = additionalFields.occurrenceId; + + // } + + // responseData = await zoomApiRequest.call( + // this, + // 'DELETE', + // `/webinars/${webinarId}`, + // {}, + // qs + // ); + // responseData = { success: true }; + // } + // if (operation === 'update') { + // //https://marketplace.zoom.us/docs/api-reference/zoom-api/webinars/webinarupdate + // const webinarId = this.getNodeParameter('webinarId', i) as string; + // const additionalFields = this.getNodeParameter( + // 'additionalFields', + // i + // ) as IDataObject; + // if (additionalFields.occurrenceId) { + // qs.occurrence_id = additionalFields.occurrenceId as string; + + // } + // const settings: Settings = {}; + // if (additionalFields.audio) { + // settings.audio = additionalFields.audio as string; + + // } + // if (additionalFields.alternativeHosts) { + // settings.alternative_hosts = additionalFields.alternativeHosts as string; + + // } + + // if (additionalFields.panelistsVideo) { + // settings.panelists_video = additionalFields.panelistsVideo as boolean; + + // } + // if (additionalFields.hostVideo) { + // settings.host_video = additionalFields.hostVideo as boolean; + + // } + // if (additionalFields.practiceSession) { + // settings.practice_session = additionalFields.practiceSession as boolean; + + // } + // if (additionalFields.autoRecording) { + // settings.auto_recording = additionalFields.autoRecording as string; + + // } + + // if (additionalFields.registrationType) { + // settings.registration_type = additionalFields.registrationType as number; + + // } + // if (additionalFields.approvalType) { + // settings.approval_type = additionalFields.approvalType as number; + + // } + + // body = { + // settings, + // }; + + // if (additionalFields.topic) { + // body.topic = additionalFields.topic as string; + + // } + + // if (additionalFields.type) { + // body.type = additionalFields.type as string; + + // } + + // if (additionalFields.startTime) { + // body.start_time = additionalFields.startTime as string; + + // } + + // if (additionalFields.duration) { + // body.duration = additionalFields.duration as number; + + // } + + + // if (additionalFields.timeZone) { + // body.timezone = additionalFields.timeZone as string; + + // } + + // if (additionalFields.password) { + // body.password = additionalFields.password as string; + + // } + + // if (additionalFields.agenda) { + // body.agenda = additionalFields.agenda as string; + + // } + // responseData = await zoomApiRequest.call( + // this, + // 'PATCH', + // `webinars/${webinarId}`, + // body, + // qs + // ); + // } + // } + if (Array.isArray(responseData)) { + returnData.push.apply(returnData, responseData as IDataObject[]); + } else { + returnData.push(responseData as IDataObject); } + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; + } + throw error; } - // if (resource === 'meetingRegistrant') { - // if (operation === 'create') { - // //https://marketplace.zoom.us/docs/api-reference/zoom-api/meetings/meetingregistrantcreate - // const meetingId = this.getNodeParameter('meetingId', i) as string; - // const emailId = this.getNodeParameter('email', i) as string; - // body.email = emailId; - // const firstName = this.getNodeParameter('firstName', i) as string; - // body.first_name = firstName; - // const additionalFields = this.getNodeParameter( - // 'additionalFields', - // i - // ) as IDataObject; - // if (additionalFields.occurrenceId) { - // qs.occurrence_ids = additionalFields.occurrenceId as string; - // } - // if (additionalFields.lastName) { - // body.last_name = additionalFields.lastName as string; - // } - // if (additionalFields.address) { - // body.address = additionalFields.address as string; - // } - // if (additionalFields.city) { - // body.city = additionalFields.city as string; - // } - // if (additionalFields.state) { - // body.state = additionalFields.state as string; - // } - // if (additionalFields.country) { - // body.country = additionalFields.country as string; - // } - // if (additionalFields.zip) { - // body.zip = additionalFields.zip as string; - // } - // if (additionalFields.phone) { - // body.phone = additionalFields.phone as string; - // } - // if (additionalFields.comments) { - // body.comments = additionalFields.comments as string; - // } - // if (additionalFields.org) { - // body.org = additionalFields.org as string; - // } - // if (additionalFields.jobTitle) { - // body.job_title = additionalFields.jobTitle as string; - // } - // if (additionalFields.purchasingTimeFrame) { - // body.purchasing_time_frame = additionalFields.purchasingTimeFrame as string; - // } - // if (additionalFields.roleInPurchaseProcess) { - // body.role_in_purchase_process = additionalFields.roleInPurchaseProcess as string; - // } - // responseData = await zoomApiRequest.call( - // this, - // 'POST', - // `/meetings/${meetingId}/registrants`, - // body, - // qs - // ); - // } - // if (operation === 'getAll') { - // //https://marketplace.zoom.us/docs/api-reference/zoom-api/meetings/meetingregistrants - // const meetingId = this.getNodeParameter('meetingId', i) as string; - // const additionalFields = this.getNodeParameter( - // 'additionalFields', - // i - // ) as IDataObject; - // if (additionalFields.occurrenceId) { - // qs.occurrence_id = additionalFields.occurrenceId as string; - // } - // if (additionalFields.status) { - // qs.status = additionalFields.status as string; - // } - // const returnAll = this.getNodeParameter('returnAll', i) as boolean; - // if (returnAll) { - // responseData = await zoomApiRequestAllItems.call(this, 'results', 'GET', `/meetings/${meetingId}/registrants`, {}, qs); - // } else { - // qs.page_size = this.getNodeParameter('limit', i) as number; - // responseData = await zoomApiRequest.call(this, 'GET', `/meetings/${meetingId}/registrants`, {}, qs); - - // } - - // } - // if (operation === 'update') { - // //https://marketplace.zoom.us/docs/api-reference/zoom-api/meetings/meetingregistrantstatus - // const meetingId = this.getNodeParameter('meetingId', i) as string; - // const additionalFields = this.getNodeParameter( - // 'additionalFields', - // i - // ) as IDataObject; - // if (additionalFields.occurrenceId) { - // qs.occurrence_id = additionalFields.occurrenceId as string; - // } - // if (additionalFields.action) { - // body.action = additionalFields.action as string; - // } - // responseData = await zoomApiRequest.call( - // this, - // 'PUT', - // `/meetings/${meetingId}/registrants/status`, - // body, - // qs - // ); - // } - // } - // if (resource === 'webinar') { - // if (operation === 'create') { - // //https://marketplace.zoom.us/docs/api-reference/zoom-api/webinars/webinarcreate - // const userId = this.getNodeParameter('userId', i) as string; - // const additionalFields = this.getNodeParameter( - // 'additionalFields', - // i - // ) as IDataObject; - // const settings: Settings = {}; - - - // if (additionalFields.audio) { - // settings.audio = additionalFields.audio as string; - - // } - - // if (additionalFields.alternativeHosts) { - // settings.alternative_hosts = additionalFields.alternativeHosts as string; - - // } - - // if (additionalFields.panelistsVideo) { - // settings.panelists_video = additionalFields.panelistsVideo as boolean; - - // } - // if (additionalFields.hostVideo) { - // settings.host_video = additionalFields.hostVideo as boolean; - - // } - // if (additionalFields.practiceSession) { - // settings.practice_session = additionalFields.practiceSession as boolean; - - // } - // if (additionalFields.autoRecording) { - // settings.auto_recording = additionalFields.autoRecording as string; - - // } - - // if (additionalFields.registrationType) { - // settings.registration_type = additionalFields.registrationType as number; - - // } - // if (additionalFields.approvalType) { - // settings.approval_type = additionalFields.approvalType as number; - - // } - - // body = { - // settings, - // }; - - // if (additionalFields.topic) { - // body.topic = additionalFields.topic as string; - - // } - - // if (additionalFields.type) { - // body.type = additionalFields.type as string; - - // } - - // if (additionalFields.startTime) { - // body.start_time = additionalFields.startTime as string; - - // } - - // if (additionalFields.duration) { - // body.duration = additionalFields.duration as number; - - // } - - - // if (additionalFields.timeZone) { - // body.timezone = additionalFields.timeZone as string; - - // } - - // if (additionalFields.password) { - // body.password = additionalFields.password as string; - - // } - - // if (additionalFields.agenda) { - // body.agenda = additionalFields.agenda as string; - - // } - // responseData = await zoomApiRequest.call( - // this, - // 'POST', - // `/users/${userId}/webinars`, - // body, - // qs - // ); - // } - // if (operation === 'get') { - // //https://marketplace.zoom.us/docs/api-reference/zoom-api/webinars/webinar - // const webinarId = this.getNodeParameter('webinarId', i) as string; - - // const additionalFields = this.getNodeParameter( - // 'additionalFields', - // i - // ) as IDataObject; - // if (additionalFields.showPreviousOccurrences) { - // qs.show_previous_occurrences = additionalFields.showPreviousOccurrences as boolean; - - // } - - // if (additionalFields.occurrenceId) { - // qs.occurrence_id = additionalFields.occurrenceId as string; - - // } - - // responseData = await zoomApiRequest.call( - // this, - // 'GET', - // `/webinars/${webinarId}`, - // {}, - // qs - // ); - // } - // if (operation === 'getAll') { - // //https://marketplace.zoom.us/docs/api-reference/zoom-api/webinars/webinars - // const userId = this.getNodeParameter('userId', i) as string; - // const returnAll = this.getNodeParameter('returnAll', i) as boolean; - // if (returnAll) { - // responseData = await zoomApiRequestAllItems.call(this, 'results', 'GET', `/users/${userId}/webinars`, {}, qs); - // } else { - // qs.page_size = this.getNodeParameter('limit', i) as number; - // responseData = await zoomApiRequest.call(this, 'GET', `/users/${userId}/webinars`, {}, qs); - - // } - // } - // if (operation === 'delete') { - // //https://marketplace.zoom.us/docs/api-reference/zoom-api/webinars/webinardelete - // const webinarId = this.getNodeParameter('webinarId', i) as string; - // const additionalFields = this.getNodeParameter( - // 'additionalFields', - // i - // ) as IDataObject; - - - // if (additionalFields.occurrenceId) { - // qs.occurrence_id = additionalFields.occurrenceId; - - // } - - // responseData = await zoomApiRequest.call( - // this, - // 'DELETE', - // `/webinars/${webinarId}`, - // {}, - // qs - // ); - // responseData = { success: true }; - // } - // if (operation === 'update') { - // //https://marketplace.zoom.us/docs/api-reference/zoom-api/webinars/webinarupdate - // const webinarId = this.getNodeParameter('webinarId', i) as string; - // const additionalFields = this.getNodeParameter( - // 'additionalFields', - // i - // ) as IDataObject; - // if (additionalFields.occurrenceId) { - // qs.occurrence_id = additionalFields.occurrenceId as string; - - // } - // const settings: Settings = {}; - // if (additionalFields.audio) { - // settings.audio = additionalFields.audio as string; - - // } - // if (additionalFields.alternativeHosts) { - // settings.alternative_hosts = additionalFields.alternativeHosts as string; - - // } - - // if (additionalFields.panelistsVideo) { - // settings.panelists_video = additionalFields.panelistsVideo as boolean; - - // } - // if (additionalFields.hostVideo) { - // settings.host_video = additionalFields.hostVideo as boolean; - - // } - // if (additionalFields.practiceSession) { - // settings.practice_session = additionalFields.practiceSession as boolean; - - // } - // if (additionalFields.autoRecording) { - // settings.auto_recording = additionalFields.autoRecording as string; - - // } - - // if (additionalFields.registrationType) { - // settings.registration_type = additionalFields.registrationType as number; - - // } - // if (additionalFields.approvalType) { - // settings.approval_type = additionalFields.approvalType as number; - - // } - - // body = { - // settings, - // }; - - // if (additionalFields.topic) { - // body.topic = additionalFields.topic as string; - - // } - - // if (additionalFields.type) { - // body.type = additionalFields.type as string; - - // } - - // if (additionalFields.startTime) { - // body.start_time = additionalFields.startTime as string; - - // } - - // if (additionalFields.duration) { - // body.duration = additionalFields.duration as number; - - // } - - - // if (additionalFields.timeZone) { - // body.timezone = additionalFields.timeZone as string; - - // } - - // if (additionalFields.password) { - // body.password = additionalFields.password as string; - - // } - - // if (additionalFields.agenda) { - // body.agenda = additionalFields.agenda as string; - - // } - // responseData = await zoomApiRequest.call( - // this, - // 'PATCH', - // `webinars/${webinarId}`, - // body, - // qs - // ); - // } - // } - } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else { - returnData.push(responseData as IDataObject); } return [this.helpers.returnJsonArray(returnData)]; diff --git a/packages/nodes-base/nodes/Zulip/Zulip.node.ts b/packages/nodes-base/nodes/Zulip/Zulip.node.ts index 86b5af80bf..5d77e2f6c9 100644 --- a/packages/nodes-base/nodes/Zulip/Zulip.node.ts +++ b/packages/nodes-base/nodes/Zulip/Zulip.node.ts @@ -155,300 +155,308 @@ export class Zulip implements INodeType { 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 === 'message') { - //https://zulipchat.com/api/send-message - if (operation === 'sendPrivate') { - const to = (this.getNodeParameter('to', i) as string[]).join(','); - const content = this.getNodeParameter('content', i) as string; - const body: IMessage = { - type: 'private', - to, - content, - }; - responseData = await zulipApiRequest.call(this, 'POST', '/messages', body); - } - //https://zulipchat.com/api/send-message - if (operation === 'sendStream') { - const stream = this.getNodeParameter('stream', i) as string; - const topic = this.getNodeParameter('topic', i) as string; - const content = this.getNodeParameter('content', i) as string; - const body: IMessage = { - type: 'stream', - to: stream, - topic, - content, - }; - responseData = await zulipApiRequest.call(this, 'POST', '/messages', body); - } - //https://zulipchat.com/api/update-message - if (operation === 'update') { - const messageId = this.getNodeParameter('messageId', i) as string; - const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; - const body: IMessage = {}; - if (updateFields.content) { - body.content = updateFields.content as string; + try { + if (resource === 'message') { + //https://zulipchat.com/api/send-message + if (operation === 'sendPrivate') { + const to = (this.getNodeParameter('to', i) as string[]).join(','); + const content = this.getNodeParameter('content', i) as string; + const body: IMessage = { + type: 'private', + to, + content, + }; + responseData = await zulipApiRequest.call(this, 'POST', '/messages', body); } - if (updateFields.propagateMode) { - body.propagat_mode = snakeCase(updateFields.propagateMode as string); + //https://zulipchat.com/api/send-message + if (operation === 'sendStream') { + const stream = this.getNodeParameter('stream', i) as string; + const topic = this.getNodeParameter('topic', i) as string; + const content = this.getNodeParameter('content', i) as string; + const body: IMessage = { + type: 'stream', + to: stream, + topic, + content, + }; + responseData = await zulipApiRequest.call(this, 'POST', '/messages', body); } - if (updateFields.topic) { - body.topic = updateFields.topic as string; - } - responseData = await zulipApiRequest.call(this, 'PATCH', `/messages/${messageId}`, body); - } - //https://zulipchat.com/api/get-raw-message - if (operation === 'get') { - const messageId = this.getNodeParameter('messageId', i) as string; - responseData = await zulipApiRequest.call(this, 'GET', `/messages/${messageId}`); - } - //https://zulipchat.com/api/delete-message - if (operation === 'delete') { - const messageId = this.getNodeParameter('messageId', i) as string; - responseData = await zulipApiRequest.call(this, 'DELETE', `/messages/${messageId}`); - } - //https://zulipchat.com/api/upload-file - if (operation === 'updateFile') { - const credentials = this.getCredentials('zulipApi'); - const binaryProperty = this.getNodeParameter('dataBinaryProperty', i) as string; - if (items[i].binary === undefined) { - throw new NodeOperationError(this.getNode(), 'No binary data exists on item!'); - } - //@ts-ignore - if (items[i].binary[binaryProperty] === undefined) { - throw new NodeOperationError(this.getNode(), `No binary data property "${binaryProperty}" does not exists on item!`); - } - const formData = { - file: { - //@ts-ignore - value: Buffer.from(items[i].binary[binaryProperty].data, BINARY_ENCODING), - options: { - //@ts-ignore - filename: items[i].binary[binaryProperty].fileName, - //@ts-ignore - contentType: items[i].binary[binaryProperty].mimeType, - }, - }, - }; - responseData = await zulipApiRequest.call(this, 'POST', '/user_uploads', {}, {}, undefined, { formData }); - responseData.uri = `${credentials!.url}${responseData.uri}`; - } - } - - if (resource === 'stream') { - const body: IStream = {}; - - if (operation === 'getAll') { - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - - if (additionalFields.includePublic) { - body.include_public = additionalFields.includePublic as boolean; - } - if (additionalFields.includeSubscribed) { - body.include_subscribed = additionalFields.includeSubscribed as boolean; - } - if (additionalFields.includeAllActive) { - body.include_all_active = additionalFields.includeAllActive as boolean; - } - if (additionalFields.includeDefault) { - body.include_default = additionalFields.includeDefault as boolean; - } - if (additionalFields.includeOwnersubscribed) { - body.include_owner_subscribed = additionalFields.includeOwnersubscribed as boolean; - } - - responseData = await zulipApiRequest.call(this, 'GET', `/streams`, body); - responseData = responseData.streams; - } - - if (operation === 'getSubscribed') { - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - - if (additionalFields.includeSubscribers) { - body.include_subscribers = additionalFields.includeSubscribers as boolean; - } - - responseData = await zulipApiRequest.call(this, 'GET', `/users/me/subscriptions`, body); - responseData = responseData.subscriptions; - } - - if (operation === 'create') { - const jsonParameters = this.getNodeParameter('jsonParameters', i) as boolean; - const subscriptions = this.getNodeParameter('subscriptions', i) as IDataObject; - - body.subscriptions = JSON.stringify(subscriptions.properties); - - if (jsonParameters) { - const additionalFieldsJson = this.getNodeParameter('additionalFieldsJson', i) as string; - - if (additionalFieldsJson !== '') { - if (validateJSON(additionalFieldsJson) !== undefined) { - Object.assign(body, JSON.parse(additionalFieldsJson)); - } else { - throw new NodeOperationError(this.getNode(), 'Additional fields must be a valid JSON'); - } + //https://zulipchat.com/api/update-message + if (operation === 'update') { + const messageId = this.getNodeParameter('messageId', i) as string; + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + const body: IMessage = {}; + if (updateFields.content) { + body.content = updateFields.content as string; } + if (updateFields.propagateMode) { + body.propagat_mode = snakeCase(updateFields.propagateMode as string); + } + if (updateFields.topic) { + body.topic = updateFields.topic as string; + } + responseData = await zulipApiRequest.call(this, 'PATCH', `/messages/${messageId}`, body); + } + //https://zulipchat.com/api/get-raw-message + if (operation === 'get') { + const messageId = this.getNodeParameter('messageId', i) as string; + responseData = await zulipApiRequest.call(this, 'GET', `/messages/${messageId}`); + } + //https://zulipchat.com/api/delete-message + if (operation === 'delete') { + const messageId = this.getNodeParameter('messageId', i) as string; + responseData = await zulipApiRequest.call(this, 'DELETE', `/messages/${messageId}`); + } + //https://zulipchat.com/api/upload-file + if (operation === 'updateFile') { + const credentials = this.getCredentials('zulipApi'); + const binaryProperty = this.getNodeParameter('dataBinaryProperty', i) as string; + if (items[i].binary === undefined) { + throw new NodeOperationError(this.getNode(), 'No binary data exists on item!'); + } + //@ts-ignore + if (items[i].binary[binaryProperty] === undefined) { + throw new NodeOperationError(this.getNode(), `No binary data property "${binaryProperty}" does not exists on item!`); + } + const formData = { + file: { + //@ts-ignore + value: Buffer.from(items[i].binary[binaryProperty].data, BINARY_ENCODING), + options: { + //@ts-ignore + filename: items[i].binary[binaryProperty].fileName, + //@ts-ignore + contentType: items[i].binary[binaryProperty].mimeType, + }, + }, + }; + responseData = await zulipApiRequest.call(this, 'POST', '/user_uploads', {}, {}, undefined, { formData }); + responseData.uri = `${credentials!.url}${responseData.uri}`; + } + } - } else { + if (resource === 'stream') { + const body: IStream = {}; + + if (operation === 'getAll') { const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + if (additionalFields.includePublic) { + body.include_public = additionalFields.includePublic as boolean; + } + if (additionalFields.includeSubscribed) { + body.include_subscribed = additionalFields.includeSubscribed as boolean; + } + if (additionalFields.includeAllActive) { + body.include_all_active = additionalFields.includeAllActive as boolean; + } + if (additionalFields.includeDefault) { + body.include_default = additionalFields.includeDefault as boolean; + } + if (additionalFields.includeOwnersubscribed) { + body.include_owner_subscribed = additionalFields.includeOwnersubscribed as boolean; + } + + responseData = await zulipApiRequest.call(this, 'GET', `/streams`, body); + responseData = responseData.streams; + } + + if (operation === 'getSubscribed') { + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + + if (additionalFields.includeSubscribers) { + body.include_subscribers = additionalFields.includeSubscribers as boolean; + } + + responseData = await zulipApiRequest.call(this, 'GET', `/users/me/subscriptions`, body); + responseData = responseData.subscriptions; + } + + if (operation === 'create') { + const jsonParameters = this.getNodeParameter('jsonParameters', i) as boolean; const subscriptions = this.getNodeParameter('subscriptions', i) as IDataObject; + body.subscriptions = JSON.stringify(subscriptions.properties); - if (additionalFields.inviteOnly) { - body.invite_only = additionalFields.inviteOnly as boolean; - } - if (additionalFields.principals) { - const principals: string[] = []; - //@ts-ignore - additionalFields.principals.properties.map((principal: IPrincipal) => { - principals.push(principal.email); - }); - body.principals = JSON.stringify(principals); - } - if (additionalFields.authorizationErrorsFatal) { - body.authorization_errors_fatal = additionalFields.authorizationErrorsFatal as boolean; - } - if (additionalFields.historyPublicToSubscribers) { - body.history_public_to_subscribers = additionalFields.historyPublicToSubscribers as boolean; - } - if (additionalFields.streamPostPolicy) { - body.stream_post_policy = additionalFields.streamPostPolicy as number; - } - if (additionalFields.announce) { - body.announce = additionalFields.announce as boolean; - } - } + if (jsonParameters) { + const additionalFieldsJson = this.getNodeParameter('additionalFieldsJson', i) as string; - responseData = await zulipApiRequest.call(this, 'POST', `/users/me/subscriptions`, body); - } + if (additionalFieldsJson !== '') { + if (validateJSON(additionalFieldsJson) !== undefined) { + Object.assign(body, JSON.parse(additionalFieldsJson)); + } else { + throw new NodeOperationError(this.getNode(), 'Additional fields must be a valid JSON'); + } + } - if (operation === 'delete') { - const streamId = this.getNodeParameter('streamId', i) as string; + } else { + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - responseData = await zulipApiRequest.call(this, 'DELETE', `/streams/${streamId}`, {}); - } + const subscriptions = this.getNodeParameter('subscriptions', i) as IDataObject; + body.subscriptions = JSON.stringify(subscriptions.properties); - if (operation === 'update') { - const streamId = this.getNodeParameter('streamId', i) as string; - - const jsonParameters = this.getNodeParameter('jsonParameters', i) as boolean; - - if (jsonParameters) { - const additionalFieldsJson = this.getNodeParameter('additionalFieldsJson', i) as string; - - if (additionalFieldsJson !== '') { - - if (validateJSON(additionalFieldsJson) !== undefined) { - - Object.assign(body, JSON.parse(additionalFieldsJson)); - - } else { - throw new NodeOperationError(this.getNode(), 'Additional fields must be a valid JSON'); + if (additionalFields.inviteOnly) { + body.invite_only = additionalFields.inviteOnly as boolean; + } + if (additionalFields.principals) { + const principals: string[] = []; + //@ts-ignore + additionalFields.principals.properties.map((principal: IPrincipal) => { + principals.push(principal.email); + }); + body.principals = JSON.stringify(principals); + } + if (additionalFields.authorizationErrorsFatal) { + body.authorization_errors_fatal = additionalFields.authorizationErrorsFatal as boolean; + } + if (additionalFields.historyPublicToSubscribers) { + body.history_public_to_subscribers = additionalFields.historyPublicToSubscribers as boolean; + } + if (additionalFields.streamPostPolicy) { + body.stream_post_policy = additionalFields.streamPostPolicy as number; + } + if (additionalFields.announce) { + body.announce = additionalFields.announce as boolean; } } - } else { + responseData = await zulipApiRequest.call(this, 'POST', `/users/me/subscriptions`, body); + } + if (operation === 'delete') { + const streamId = this.getNodeParameter('streamId', i) as string; + + responseData = await zulipApiRequest.call(this, 'DELETE', `/streams/${streamId}`, {}); + } + + if (operation === 'update') { + const streamId = this.getNodeParameter('streamId', i) as string; + + const jsonParameters = this.getNodeParameter('jsonParameters', i) as boolean; + + if (jsonParameters) { + const additionalFieldsJson = this.getNodeParameter('additionalFieldsJson', i) as string; + + if (additionalFieldsJson !== '') { + + if (validateJSON(additionalFieldsJson) !== undefined) { + + Object.assign(body, JSON.parse(additionalFieldsJson)); + + } else { + throw new NodeOperationError(this.getNode(), 'Additional fields must be a valid JSON'); + } + } + + } else { + + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + + if (additionalFields.description) { + body.description = JSON.stringify(additionalFields.description as string); + } + if (additionalFields.newName) { + body.new_name = JSON.stringify(additionalFields.newName as string); + } + if (additionalFields.isPrivate) { + body.is_private = additionalFields.isPrivate as boolean; + } + if (additionalFields.isAnnouncementOnly) { + body.is_announcement_only = additionalFields.isAnnouncementOnly as boolean; + } + if (additionalFields.streamPostPolicy) { + body.stream_post_policy = additionalFields.streamPostPolicy as number; + } + if (additionalFields.historyPublicToSubscribers) { + body.history_public_to_subscribers = additionalFields.historyPublicToSubscribers as boolean; + } + + responseData = await zulipApiRequest.call(this, 'PATCH', `/streams/${streamId}`, body); + } + + } + } + + if (resource === 'user') { + const body: IUser = {}; + + if (operation === 'get') { + const userId = this.getNodeParameter('userId', i) as string; const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - if (additionalFields.description) { - body.description = JSON.stringify(additionalFields.description as string); + if (additionalFields.clientGravatar) { + body.client_gravatar = additionalFields.client_gravatar as boolean; } - if (additionalFields.newName) { - body.new_name = JSON.stringify(additionalFields.newName as string); - } - if (additionalFields.isPrivate) { - body.is_private = additionalFields.isPrivate as boolean; - } - if (additionalFields.isAnnouncementOnly) { - body.is_announcement_only = additionalFields.isAnnouncementOnly as boolean; - } - if (additionalFields.streamPostPolicy) { - body.stream_post_policy = additionalFields.streamPostPolicy as number; - } - if (additionalFields.historyPublicToSubscribers) { - body.history_public_to_subscribers = additionalFields.historyPublicToSubscribers as boolean; + if (additionalFields.includeCustomProfileFields) { + body.include_custom_profile_fields = additionalFields.includeCustomProfileFields as boolean; } - responseData = await zulipApiRequest.call(this, 'PATCH', `/streams/${streamId}`, body); + responseData = await zulipApiRequest.call(this, 'GET', `/users/${userId}`, body); + } - } - } + if (operation === 'getAll') { + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - if (resource === 'user') { - const body: IUser = {}; + if (additionalFields.clientGravatar) { + body.client_gravatar = additionalFields.client_gravatar as boolean; + } + if (additionalFields.includeCustomProfileFields) { + body.include_custom_profile_fields = additionalFields.includeCustomProfileFields as boolean; + } - if (operation === 'get') { - const userId = this.getNodeParameter('userId', i) as string; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - - if (additionalFields.clientGravatar) { - body.client_gravatar = additionalFields.client_gravatar as boolean; - } - if (additionalFields.includeCustomProfileFields) { - body.include_custom_profile_fields = additionalFields.includeCustomProfileFields as boolean; + responseData = await zulipApiRequest.call(this, 'GET', `/users`, body); + responseData = responseData.members; } - responseData = await zulipApiRequest.call(this, 'GET', `/users/${userId}`, body); + if (operation === 'create') { + body.email = this.getNodeParameter('email', i) as string; + body.password = this.getNodeParameter('password', i) as string; + body.full_name = this.getNodeParameter('fullName', i) as string; + body.short_name = this.getNodeParameter('shortName', i) as string; + responseData = await zulipApiRequest.call(this, 'POST', `/users`, body); + } + + if (operation === 'update') { + const userId = this.getNodeParameter('userId', i) as string; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + + if (additionalFields.fullName) { + body.full_name = JSON.stringify(additionalFields.fullName as string); + } + if (additionalFields.isAdmin) { + body.is_admin = additionalFields.isAdmin as boolean; + } + if (additionalFields.isGuest) { + body.is_guest = additionalFields.isGuest as boolean; + } + if (additionalFields.profileData) { + //@ts-ignore + body.profile_data = additionalFields.profileData.properties as [{}]; + } + + responseData = await zulipApiRequest.call(this, 'PATCH', `/users/${userId}`, body); + } + + if (operation === 'deactivate') { + const userId = this.getNodeParameter('userId', i) as string; + + responseData = await zulipApiRequest.call(this, 'DELETE', `/users/${userId}`, body); + } } - if (operation === 'getAll') { - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - - if (additionalFields.clientGravatar) { - body.client_gravatar = additionalFields.client_gravatar as boolean; - } - if (additionalFields.includeCustomProfileFields) { - body.include_custom_profile_fields = additionalFields.includeCustomProfileFields as boolean; - } - - responseData = await zulipApiRequest.call(this, 'GET', `/users`, body); - responseData = responseData.members; + if (Array.isArray(responseData)) { + returnData.push.apply(returnData, responseData as IDataObject[]); + } else { + returnData.push(responseData as IDataObject); } - - if (operation === 'create') { - body.email = this.getNodeParameter('email', i) as string; - body.password = this.getNodeParameter('password', i) as string; - body.full_name = this.getNodeParameter('fullName', i) as string; - body.short_name = this.getNodeParameter('shortName', i) as string; - - responseData = await zulipApiRequest.call(this, 'POST', `/users`, body); + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ error: error.message }); + continue; } - - if (operation === 'update') { - const userId = this.getNodeParameter('userId', i) as string; - const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - - if (additionalFields.fullName) { - body.full_name = JSON.stringify(additionalFields.fullName as string); - } - if (additionalFields.isAdmin) { - body.is_admin = additionalFields.isAdmin as boolean; - } - if (additionalFields.isGuest) { - body.is_guest = additionalFields.isGuest as boolean; - } - if (additionalFields.profileData) { - //@ts-ignore - body.profile_data = additionalFields.profileData.properties as [{}]; - } - - responseData = await zulipApiRequest.call(this, 'PATCH', `/users/${userId}`, body); - } - - if (operation === 'deactivate') { - const userId = this.getNodeParameter('userId', i) as string; - - responseData = await zulipApiRequest.call(this, 'DELETE', `/users/${userId}`, body); - } - } - - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else { - returnData.push(responseData as IDataObject); + throw error; } } return [this.helpers.returnJsonArray(returnData)]; From a8098283af554f8b2687750cd5aae971e42c6187 Mon Sep 17 00:00:00 2001 From: Jan Oberhauser Date: Tue, 20 Jul 2021 09:02:42 +0200 Subject: [PATCH 14/15] :zap: Remove console.log --- packages/nodes-base/nodes/Google/Calendar/GenericFunctions.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/nodes-base/nodes/Google/Calendar/GenericFunctions.ts b/packages/nodes-base/nodes/Google/Calendar/GenericFunctions.ts index 503263ad64..4b9eff2928 100644 --- a/packages/nodes-base/nodes/Google/Calendar/GenericFunctions.ts +++ b/packages/nodes-base/nodes/Google/Calendar/GenericFunctions.ts @@ -30,7 +30,6 @@ export async function googleApiRequest(this: IExecuteFunctions | IExecuteSingleF if (Object.keys(body).length === 0) { delete options.body; } - console.log(options); //@ts-ignore return await this.helpers.requestOAuth2.call(this, 'googleCalendarOAuth2Api', options); } catch (error) { From ce43194e9146993a187031511fa7463dbbaa8e64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Ovejero?= Date: Tue, 20 Jul 2021 15:53:10 +0200 Subject: [PATCH 15/15] :sparkles: Add Leads to Pipedrive node (#1986) * :zap: Add leads to Pipedrive node * :zap: Make org ID required for deal:create * :hammer: Refactor linked entity for lead:create * :hammer: Refactor linked entity for deal:create * :pencil2: Write breaking changes * :zap: Improvements * :bug: Fix issue with returning invalid data * :zap: Make lead-descriptions format consistent Co-authored-by: ricardo Co-authored-by: Jan Oberhauser --- packages/cli/BREAKING-CHANGES.md | 10 + .../nodes/Pipedrive/Pipedrive.node.ts | 701 +++++++++++++++++- packages/nodes-base/nodes/Pipedrive/utils.ts | 89 +++ 3 files changed, 794 insertions(+), 6 deletions(-) create mode 100644 packages/nodes-base/nodes/Pipedrive/utils.ts diff --git a/packages/cli/BREAKING-CHANGES.md b/packages/cli/BREAKING-CHANGES.md index fb393e0f3c..150554886c 100644 --- a/packages/cli/BREAKING-CHANGES.md +++ b/packages/cli/BREAKING-CHANGES.md @@ -2,6 +2,16 @@ This list shows all the versions which include breaking changes and how to upgrade. +## 0.131.0 + +### What changed? + +For the Pipedrive regular node, the `deal:create` operation now requires an organization ID or person ID, in line with upcoming changes to the Pipedrive API. + +### When is action necessary? + +If you are using the `deal:create` operation in the Pipedrive regular node, set an organization ID or a person ID. + ## 0.130.0 ### What changed? diff --git a/packages/nodes-base/nodes/Pipedrive/Pipedrive.node.ts b/packages/nodes-base/nodes/Pipedrive/Pipedrive.node.ts index b9e4394499..2fbb5de908 100644 --- a/packages/nodes-base/nodes/Pipedrive/Pipedrive.node.ts +++ b/packages/nodes-base/nodes/Pipedrive/Pipedrive.node.ts @@ -21,6 +21,10 @@ import { pipedriveResolveCustomProperties, } from './GenericFunctions'; +import { + currencies, +} from './utils'; + interface CustomProperty { name: string; value: string; @@ -118,6 +122,10 @@ export class Pipedrive implements INodeType { name: 'File', value: 'file', }, + { + name: 'Lead', + value: 'lead', + }, { name: 'Note', value: 'note', @@ -285,6 +293,46 @@ export class Pipedrive implements INodeType { description: 'The operation to perform.', }, + { + displayName: 'Operation', + name: 'operation', + type: 'options', + displayOptions: { + show: { + resource: [ + 'lead', + ], + }, + }, + options: [ + { + name: 'Create', + value: 'create', + description: 'Create a lead', + }, + { + name: 'Delete', + value: 'delete', + description: 'Delete a lead', + }, + { + name: 'Get', + value: 'get', + description: 'Get data of a lead', + }, + { + name: 'Get All', + value: 'getAll', + description: 'Get data of all leads', + }, + { + name: 'Update', + value: 'update', + description: 'Update a lead', + }, + ], + default: 'create', + }, { displayName: 'Operation', name: 'operation', @@ -846,6 +894,75 @@ export class Pipedrive implements INodeType { }, description: 'The title of the deal to create', }, + { + displayName: 'Associate With', + name: 'associateWith', + type: 'options', + options: [ + { + name: 'Organization', + value: 'organization', + }, + { + name: 'Person', + value: 'person', + }, + ], + default: 'organization', + description: 'Type of entity to link to this deal', + required: true, + displayOptions: { + show: { + resource: [ + 'deal', + ], + operation: [ + 'create', + ], + }, + }, + }, + { + displayName: 'Organization ID', + name: 'org_id', + type: 'number', + default: 0, + description: 'ID of the organization this deal will be associated with', + required: true, + displayOptions: { + show: { + operation: [ + 'create', + ], + resource: [ + 'deal', + ], + associateWith: [ + 'organization', + ], + }, + }, + }, + { + displayName: 'Person ID', + name: 'person_id', + type: 'number', + default: 0, + description: 'ID of the person this deal will be associated with.', + displayOptions: { + show: { + operation: [ + 'create', + ], + resource: [ + 'deal', + ], + associateWith: [ + 'person', + ], + }, + }, + }, { displayName: 'Additional Fields', name: 'additionalFields', @@ -925,18 +1042,30 @@ export class Pipedrive implements INodeType { { displayName: 'Organization ID', name: 'org_id', - type: 'options', - typeOptions: { - loadOptionsMethod: 'getOrganizationIds', + type: 'number', + default: 0, + required: true, + displayOptions: { + show: { + '/associateWith': [ + 'person', + ], + }, }, - default: '', - description: 'ID of the organization this deal will be associated with.', + description: 'ID of the organization this deal will be associated with', }, { displayName: 'Person ID', name: 'person_id', type: 'number', default: 0, + displayOptions: { + show: { + '/associateWith': [ + 'organization', + ], + }, + }, description: 'ID of the person this deal will be associated with.', }, { @@ -1617,7 +1746,358 @@ export class Pipedrive implements INodeType { }, default: 0, required: true, - description: 'ID of the file to get.', + description: 'ID of the file to get', + }, + + // ---------------------------------------- + // lead: create + // ---------------------------------------- + { + displayName: 'Title', + name: 'title', + description: 'Name of the lead to create', + type: 'string', + required: true, + default: '', + displayOptions: { + show: { + resource: [ + 'lead', + ], + operation: [ + 'create', + ], + }, + }, + }, + { + displayName: 'Associate With', + name: 'associateWith', + type: 'options', + options: [ + { + name: 'Organization', + value: 'organization', + }, + { + name: 'Person', + value: 'person', + }, + ], + default: 'organization', + description: 'Type of entity to link to this lead', + required: true, + displayOptions: { + show: { + resource: [ + 'lead', + ], + operation: [ + 'create', + ], + }, + }, + }, + { + displayName: 'Organization ID', + name: 'organization_id', + type: 'number', + default: 0, + description: 'ID of the organization to link to this lead', + required: true, + displayOptions: { + show: { + resource: [ + 'lead', + ], + operation: [ + 'create', + ], + associateWith: [ + 'organization', + ], + }, + }, + }, + { + displayName: 'Person ID', + name: 'person_id', + type: 'number', + default: 0, + description: 'ID of the person to link to this lead', + required: true, + displayOptions: { + show: { + resource: [ + 'lead', + ], + operation: [ + 'create', + ], + associateWith: [ + 'person', + ], + }, + }, + }, + { + displayName: 'Additional Fields', + name: 'additionalFields', + type: 'collection', + placeholder: 'Add Field', + default: {}, + displayOptions: { + show: { + resource: [ + 'lead', + ], + operation: [ + 'create', + ], + }, + }, + options: [ + { + displayName: 'Expected Close Date', + name: 'expected_close_date', + type: 'dateTime', + default: '', + description: 'Date when the lead’s deal is expected to be closed, in ISO-8601 format', + }, + { + displayName: 'Label IDs', + name: 'label_ids', + type: 'multiOptions', + typeOptions: { + loadOptionsMethod: 'getLeadLabels', + }, + default: [], + description: 'ID of the labels to attach to the lead to create', + }, + { + displayName: 'Organization ID', + name: 'organization_id', + type: 'number', + default: 0, + description: 'ID of the organization to link to this lead', + displayOptions: { + show: { + '/associateWith': [ + 'person', + ], + }, + }, + }, + { + displayName: 'Owner ID', + name: 'owner_id', + type: 'options', + typeOptions: { + loadOptionsMethod: 'getUserIds', + }, + default: '', + description: 'ID of the user who will own the lead to create', + }, + { + displayName: 'Person ID', + name: 'person_id', + type: 'number', + default: 0, + description: 'ID of the person to link to this lead', + displayOptions: { + show: { + '/associateWith': [ + 'organization', + ], + }, + }, + }, + { + displayName: 'Value', + name: 'value', + type: 'fixedCollection', + description: 'Potential monetary value associated with the lead', + default: {}, + options: [ + { + displayName: 'Value Properties', + name: 'valueProperties', + values: [ + { + displayName: 'Amount', + name: 'amount', + type: 'number', + default: '', + }, + { + displayName: 'Currency', + name: 'currency', + type: 'options', + default: 'USD', + options: currencies.sort((a, b) => a.name.localeCompare(b.name)), + }, + ], + }, + ], + }, + ], + }, + + // ---------------------------------------- + // lead: delete + // ---------------------------------------- + { + displayName: 'Lead ID', + name: 'leadId', + description: 'ID of the lead to delete', + type: 'string', + required: true, + default: '', + displayOptions: { + show: { + resource: [ + 'lead', + ], + operation: [ + 'delete', + ], + }, + }, + }, + + // ---------------------------------------- + // lead: get + // ---------------------------------------- + { + displayName: 'Lead ID', + name: 'leadId', + description: 'ID of the lead to retrieve', + type: 'string', + required: true, + default: '', + displayOptions: { + show: { + resource: [ + 'lead', + ], + operation: [ + 'get', + ], + }, + }, + }, + + // ---------------------------------------- + // lead: update + // ---------------------------------------- + { + displayName: 'Lead ID', + name: 'leadId', + description: 'ID of the lead to update', + type: 'string', + required: true, + default: '', + displayOptions: { + show: { + resource: [ + 'lead', + ], + operation: [ + 'update', + ], + }, + }, + }, + { + displayName: 'Update Fields', + name: 'updateFields', + type: 'collection', + placeholder: 'Add Field', + default: {}, + displayOptions: { + show: { + resource: [ + 'lead', + ], + operation: [ + 'update', + ], + }, + }, + options: [ + { + displayName: 'Title', + name: 'title', + type: 'string', + default: '', + description: 'Name of the lead to update', + }, + { + displayName: 'Owner ID', + name: 'owner_id', + type: 'options', + typeOptions: { + loadOptionsMethod: 'getUserIds', + }, + default: '', + description: 'ID of the user who will own the lead to update', + }, + { + displayName: 'Label IDs', + name: 'label_ids', + type: 'multiOptions', + typeOptions: { + loadOptionsMethod: 'getLeadLabels', + }, + default: [], + description: 'ID of the labels to attach to the lead to update', + }, + { + displayName: 'Person ID', + name: 'person_id', + type: 'options', + typeOptions: { + loadOptionsMethod: 'getPersons', + }, + default: '', + description: 'ID of the person to link to this lead', + }, + { + displayName: 'Value', + name: 'value', + type: 'fixedCollection', + description: 'Potential monetary value associated with the lead', + default: {}, + options: [ + { + displayName: 'Value Properties', + name: 'valueProperties', + values: [ + { + displayName: 'Amount', + name: 'amount', + type: 'number', + default: '', + }, + { + displayName: 'Currency', + name: 'currency', + type: 'options', + default: 'USD', + options: currencies.sort((a, b) => a.name.localeCompare(b.name)), + }, + ], + }, + ], + }, + { + displayName: 'Expected Close Date', + name: 'expected_close_date', + type: 'dateTime', + default: '', + description: 'Date when the lead’s deal is expected to be closed, in ISO-8601 format', + }, + ], }, @@ -2487,6 +2967,49 @@ export class Pipedrive implements INodeType { description: 'How many results to return.', }, + // ---------------------------------------- + // lead: getAll + // ---------------------------------------- + { + displayName: 'Filters', + name: 'filters', + type: 'collection', + placeholder: 'Add Filter', + default: {}, + displayOptions: { + show: { + resource: [ + 'lead', + ], + operation: [ + 'getAll', + ], + }, + }, + options: [ + { + displayName: 'Archived Status', + name: 'archived_status', + type: 'options', + default: 'all', + options: [ + { + name: 'Archived', + value: 'archived', + }, + { + name: 'All', + value: 'all', + }, + { + name: 'Not Archived', + value: 'not_archived', + }, + ], + }, + ], + }, + // ---------------------------------- // person:getAll // ---------------------------------- @@ -2981,6 +3504,27 @@ export class Pipedrive implements INodeType { } return returnData; }, + + // Get all the persons to display them to user so that he can + // select them easily + async getPersons(this: ILoadOptionsFunctions): Promise { + const { data } = await pipedriveApiRequest.call(this, 'GET', '/persons', {}) as { + data: Array<{ id: string; name: string; }> + }; + + return data.map(({ id, name }) => ({ value: id, name })); + }, + + // Get all the lead labels to display them to user so that he can + // select them easily + async getLeadLabels(this: ILoadOptionsFunctions): Promise { + const { data } = await pipedriveApiRequest.call(this, 'GET', '/leadLabels', {}) as { + data: Array<{ id: string; name: string; }> + }; + + return data.map(({ id, name }) => ({ value: id, name })); + }, + // Get all the labels to display them to user so that he can // select them easily async getDealLabels(this: ILoadOptionsFunctions): Promise { @@ -3147,6 +3691,15 @@ export class Pipedrive implements INodeType { endpoint = '/deals'; body.title = this.getNodeParameter('title', i) as string; + + const associateWith = this.getNodeParameter('associateWith', i) as 'organization' | 'person'; + + if (associateWith === 'organization') { + body.org_id = this.getNodeParameter('org_id', i) as string; + } else { + body.person_id = this.getNodeParameter('person_id', i) as string; + } + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; addAdditionalFields(body, additionalFields); @@ -3376,6 +3929,140 @@ export class Pipedrive implements INodeType { addAdditionalFields(body, updateFields); } + + } else if (resource === 'lead') { + + if (operation === 'create') { + + // ---------------------------------------- + // lead: create + // ---------------------------------------- + + // https://developers.pipedrive.com/docs/api/v1/Leads#addLead + + body = { + title: this.getNodeParameter('title', i), + } as IDataObject; + + const associateWith = this.getNodeParameter('associateWith', i) as 'organization' | 'person'; + + if (associateWith === 'organization') { + body.organization_id = this.getNodeParameter('organization_id', i) as number; + } else { + body.person_id = this.getNodeParameter('person_id', i) as number; + } + + const { value, expected_close_date, ...rest } = this.getNodeParameter('additionalFields', i) as { + value: { + valueProperties: { + amount: number; + currency: string; + } + }; + expected_close_date: string; + person_id: number, + organization_id: number, + }; + + if (Object.keys(rest).length) { + Object.assign(body, rest); + } + + if (value) { + Object.assign(body, { value: value.valueProperties }); + } + + if (expected_close_date) { + body.expected_close_date = expected_close_date.split('T')[0]; + } + + requestMethod = 'POST'; + endpoint = '/leads'; + + } else if (operation === 'delete') { + + // ---------------------------------------- + // lead: delete + // ---------------------------------------- + + // https://developers.pipedrive.com/docs/api/v1/Leads#deleteLead + + const leadId = this.getNodeParameter('leadId', i); + + requestMethod = 'DELETE'; + endpoint = `/leads/${leadId}`; + + } else if (operation === 'get') { + + // ---------------------------------------- + // lead: get + // ---------------------------------------- + + // https://developers.pipedrive.com/docs/api/v1/Leads#getLead + + const leadId = this.getNodeParameter('leadId', i); + + requestMethod = 'GET'; + endpoint = `/leads/${leadId}`; + + } else if (operation === 'getAll') { + + // ---------------------------------------- + // lead: getAll + // ---------------------------------------- + + // https://developers.pipedrive.com/docs/api/v1/Leads#getLeads + + const filters = this.getNodeParameter('filters', i) as IDataObject; + + if (Object.keys(filters).length) { + Object.assign(qs, filters); + } + + requestMethod = 'GET'; + endpoint = '/leads'; + + } else if (operation === 'update') { + + // ---------------------------------------- + // lead: update + // ---------------------------------------- + + // https://developers.pipedrive.com/docs/api/v1/Leads#updateLead + + const { value, expected_close_date, ...rest } = this.getNodeParameter('updateFields', i) as { + value: { + valueProperties: { + amount: number; + currency: string; + } + }; + expected_close_date: string; + }; + + if (Object.keys(rest).length) { + Object.assign(body, rest); + } + + if (value) { + Object.assign(body, { value: value.valueProperties }); + } + + if (expected_close_date) { + body.expected_close_date = expected_close_date.split('T')[0]; + } + + if (Object.keys(rest).length) { + Object.assign(body, rest); + } + + const leadId = this.getNodeParameter('leadId', i); + + requestMethod = 'PATCH'; + endpoint = `/leads/${leadId}`; + + } + } else if (resource === 'organization') { if (operation === 'create') { // ---------------------------------- @@ -3624,6 +4311,8 @@ export class Pipedrive implements INodeType { if (Array.isArray(responseData.data)) { returnData.push.apply(returnData, responseData.data as IDataObject[]); + } else if (responseData.data === true) { + returnData.push({ success: true }); } else { returnData.push(responseData.data as IDataObject); } diff --git a/packages/nodes-base/nodes/Pipedrive/utils.ts b/packages/nodes-base/nodes/Pipedrive/utils.ts new file mode 100644 index 0000000000..e8d88b0363 --- /dev/null +++ b/packages/nodes-base/nodes/Pipedrive/utils.ts @@ -0,0 +1,89 @@ +export const currencies = [ + { name: 'US Dollar', value: 'USD' }, + { name: 'Euro', value: 'EUR' }, + { name: 'UAE Dirham', value: 'AED' }, + { name: 'Afghani', value: 'AFN' }, + { name: 'Lek', value: 'ALL' }, + { name: 'Argentine Peso', value: 'ARS' }, + { name: 'Australian Dollar', value: 'AUD' }, + { name: 'Azerbaijan Manat', value: 'AZN' }, + { name: 'Barbados Dollar', value: 'BBD' }, + { name: 'Taka', value: 'BDT' }, + { name: 'Bulgarian Lev', value: 'BGN' }, + { name: 'Bermudian Dollar', value: 'BMD' }, + { name: 'Brunei Dollar', value: 'BND' }, + { name: 'Boliviano', value: 'BOB' }, + { name: 'Brazilian Real', value: 'BRL' }, + { name: 'Bahamian Dollar', value: 'BSD' }, + { name: 'Pula', value: 'BWP' }, + { name: 'Belize Dollar', value: 'BZD' }, + { name: 'Canadian Dollar', value: 'CAD' }, + { name: 'Swiss Franc', value: 'CHF' }, + { name: 'Chilean Peso', value: 'CLP' }, + { name: 'Yuan Renminbi', value: 'CNY' }, + { name: 'Colombian Peso', value: 'COP' }, + { name: 'Costa Rican Colon', value: 'CRC' }, + { name: 'Czech Koruna', value: 'CZK' }, + { name: 'Danish Krone', value: 'DKK' }, + { name: 'Dominican Peso', value: 'DOP' }, + { name: 'Algerian Dinar', value: 'DZD' }, + { name: 'Egyptian Pound', value: 'EGP' }, + { name: 'Fiji Dollar', value: 'FJD' }, + { name: 'Pound Sterling', value: 'GBP' }, + { name: 'Quetzal', value: 'GTQ' }, + { name: 'Hong Kong Dollar', value: 'HKD' }, + { name: 'Lempira', value: 'HNL' }, + { name: 'Kuna', value: 'HRK' }, + { name: 'Forint', value: 'HUF' }, + { name: 'Rupiah', value: 'IDR' }, + { name: 'New Israeli Sheqel', value: 'ILS' }, + { name: 'Indian Rupee', value: 'INR' }, + { name: 'Jamaican Dollar', value: 'JMD' }, + { name: 'Yen', value: 'JPY' }, + { name: 'Kenyan Shilling', value: 'KES' }, + { name: 'Won', value: 'KRW' }, + { name: 'Tenge', value: 'KZT' }, + { name: 'Lao Kip', value: 'LAK' }, + { name: 'Lebanese Pound', value: 'LBP' }, + { name: 'Sri Lanka Rupee', value: 'LKR' }, + { name: 'Liberian Dollar', value: 'LRD' }, + { name: 'Moroccan Dirham', value: 'MAD' }, + { name: 'Kyat', value: 'MMK' }, + { name: 'Pataca', value: 'MOP' }, + { name: 'Ouguiya', value: 'MRO' }, + { name: 'Mauritius Rupee', value: 'MUR' }, + { name: 'Rufiyaa', value: 'MVR' }, + { name: 'Mexican Peso', value: 'MXN' }, + { name: 'Malaysian Ringgit', value: 'MYR' }, + { name: 'Cordoba Oro', value: 'NIO' }, + { name: 'Norwegian Krone', value: 'NOK' }, + { name: 'Nepalese Rupee', value: 'NPR' }, + { name: 'New Zealand Dollar', value: 'NZD' }, + { name: 'Sol', value: 'PEN' }, + { name: 'Kina', value: 'PGK' }, + { name: 'Philippine Peso', value: 'PHP' }, + { name: 'Pakistan Rupee', value: 'PKR' }, + { name: 'Zloty', value: 'PLN' }, + { name: 'Qatari Rial', value: 'QAR' }, + { name: 'Romanian Leu', value: 'RON' }, + { name: 'Russian Ruble', value: 'RUB' }, + { name: 'Saudi Riyal', value: 'SAR' }, + { name: 'Solomon Islands Dollar ', value: 'SBD' }, + { name: 'Seychelles Rupee', value: 'SCR' }, + { name: 'Swedish Krona', value: 'SEK' }, + { name: 'Singapore Dollar', value: 'SGD' }, + { name: 'Syrian Pound', value: 'SYP' }, + { name: 'Baht', value: 'THB' }, + { name: 'Pa’anga', value: 'TOP' }, + { name: 'Turkish Lira', value: 'TRY' }, + { name: 'Trinidad and Tobago Dollar', value: 'TTD' }, + { name: 'New Taiwan Dollar', value: 'TWD' }, + { name: 'Hryvnia', value: 'UAH' }, + { name: 'Dong', value: 'VND' }, + { name: 'Vatu', value: 'VUV' }, + { name: 'Tala', value: 'WST' }, + { name: 'East Caribbean Dollar', value: 'XCD' }, + { name: 'West African CFA Franc', value: 'XOF' }, + { name: 'Yemeni Rial', value: 'YER' }, + { name: 'Rand', value: 'ZAR' }, +];