From d6239d5bfbc1d701c7a3bebc2c59e1f23ef6aebb Mon Sep 17 00:00:00 2001 From: Omar Ajoue Date: Tue, 20 Jul 2021 08:58:54 +0200 Subject: [PATCH] :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)];