From bae541e13b1ed44be998e829b55d56f82c90d815 Mon Sep 17 00:00:00 2001 From: Tanay Pant <7481165+tanay1337@users.noreply.github.com> Date: Thu, 18 Jun 2020 10:08:31 +0200 Subject: [PATCH 1/6] :books: Make a few language changes (#681) --- CONTRIBUTING.md | 10 +++++----- LICENSE.md | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 568f8fc9a7..fcc046beef 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -38,7 +38,7 @@ The most important directories: execution, active webhooks and workflows - [/packages/editor-ui](/packages/editor-ui) - Vue frontend workflow editor - - [/packages/node-dev](/packages/node-dev) - Simple CLI to create new n8n-nodes + - [/packages/node-dev](/packages/node-dev) - CLI to create new n8n-nodes - [/packages/nodes-base](/packages/nodes-base) - Base n8n nodes - [/packages/workflow](/packages/workflow) - Workflow code with interfaces which get used by front- & backend @@ -159,7 +159,7 @@ tests of all packages. ## Create Custom Nodes -It is very easy to create own nodes for n8n. More information about that can +It is very straightforward to create your own nodes for n8n. More information about that can be found in the documentation of "n8n-node-dev" which is a small CLI which helps with n8n-node-development. @@ -177,9 +177,9 @@ If you want to create a node which should be added to n8n follow these steps: 1. Create a new folder for the new node. For a service named "Example" the folder would be called: `/packages/nodes-base/nodes/Example` - 1. If there is already a similar node simply copy the existing one in the new folder and rename it. If none exists yet, create a boilerplate node with [n8n-node-dev](https://github.com/n8n-io/n8n/tree/master/packages/node-dev) and copy that one in the folder. + 1. If there is already a similar node, copy the existing one in the new folder and rename it. If none exists yet, create a boilerplate node with [n8n-node-dev](https://github.com/n8n-io/n8n/tree/master/packages/node-dev) and copy that one in the folder. - 1. If the node needs credentials because it has to authenticate with an API or similar create new ones. Existing ones can be found in folder `/packages/nodes-base/credentials`. Also there it is the easiest to simply copy existing similar ones. + 1. If the node needs credentials because it has to authenticate with an API or similar create new ones. Existing ones can be found in folder `/packages/nodes-base/credentials`. Also there it is the easiest to copy existing similar ones. 1. Add the path to the new node (and optionally credentials) to package.json of `nodes-base`. It already contains a property `n8n` with its own keys `credentials` and `nodes`. @@ -236,6 +236,6 @@ docsify serve ./docs That we do not have any potential problems later it is sadly necessary to sign a [Contributor License Agreement](CONTRIBUTOR_LICENSE_AGREEMENT.md). That can be done literally with the push of a button. -We used the most simple one that exists. It is from [Indie Open Source](https://indieopensource.com/forms/cla) which uses plain English and is literally just a few lines long. +We used the most simple one that exists. It is from [Indie Open Source](https://indieopensource.com/forms/cla) which uses plain English and is literally only a few lines long. A bot will automatically comment on the pull request once it got opened asking for the agreement to be signed. Before it did not get signed it is sadly not possible to merge it in. diff --git a/LICENSE.md b/LICENSE.md index aac54547eb..c2aec2148e 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -215,7 +215,7 @@ Licensor: n8n GmbH same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright [yyyy] [name of copyright owner] + Copyright [2020] [n8n GmbH] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. From d9906e1b24989db2c200f38542127cc98846ab0a Mon Sep 17 00:00:00 2001 From: Jan Oberhauser Date: Thu, 18 Jun 2020 10:12:13 +0200 Subject: [PATCH 2/6] :books: Text fix --- LICENSE.md | 2 +- packages/cli/LICENSE.md | 2 +- packages/core/LICENSE.md | 2 +- packages/editor-ui/LICENSE.md | 2 +- packages/node-dev/LICENSE.md | 2 +- packages/nodes-base/LICENSE.md | 2 +- packages/workflow/LICENSE.md | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/LICENSE.md b/LICENSE.md index c2aec2148e..24a7d38fc9 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -215,7 +215,7 @@ Licensor: n8n GmbH same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright [2020] [n8n GmbH] + Copyright 2020 n8n GmbH Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/packages/cli/LICENSE.md b/packages/cli/LICENSE.md index aac54547eb..24a7d38fc9 100644 --- a/packages/cli/LICENSE.md +++ b/packages/cli/LICENSE.md @@ -215,7 +215,7 @@ Licensor: n8n GmbH same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright [yyyy] [name of copyright owner] + Copyright 2020 n8n GmbH Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/packages/core/LICENSE.md b/packages/core/LICENSE.md index aac54547eb..24a7d38fc9 100644 --- a/packages/core/LICENSE.md +++ b/packages/core/LICENSE.md @@ -215,7 +215,7 @@ Licensor: n8n GmbH same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright [yyyy] [name of copyright owner] + Copyright 2020 n8n GmbH Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/packages/editor-ui/LICENSE.md b/packages/editor-ui/LICENSE.md index aac54547eb..24a7d38fc9 100644 --- a/packages/editor-ui/LICENSE.md +++ b/packages/editor-ui/LICENSE.md @@ -215,7 +215,7 @@ Licensor: n8n GmbH same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright [yyyy] [name of copyright owner] + Copyright 2020 n8n GmbH Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/packages/node-dev/LICENSE.md b/packages/node-dev/LICENSE.md index aac54547eb..24a7d38fc9 100644 --- a/packages/node-dev/LICENSE.md +++ b/packages/node-dev/LICENSE.md @@ -215,7 +215,7 @@ Licensor: n8n GmbH same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright [yyyy] [name of copyright owner] + Copyright 2020 n8n GmbH Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/packages/nodes-base/LICENSE.md b/packages/nodes-base/LICENSE.md index aac54547eb..24a7d38fc9 100644 --- a/packages/nodes-base/LICENSE.md +++ b/packages/nodes-base/LICENSE.md @@ -215,7 +215,7 @@ Licensor: n8n GmbH same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright [yyyy] [name of copyright owner] + Copyright 2020 n8n GmbH Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/packages/workflow/LICENSE.md b/packages/workflow/LICENSE.md index aac54547eb..24a7d38fc9 100644 --- a/packages/workflow/LICENSE.md +++ b/packages/workflow/LICENSE.md @@ -215,7 +215,7 @@ Licensor: n8n GmbH same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright [yyyy] [name of copyright owner] + Copyright 2020 n8n GmbH Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. From 5db2ce2924f08a462ad58616e0e9ab779fdf1422 Mon Sep 17 00:00:00 2001 From: Jan Oberhauser Date: Sat, 20 Jun 2020 12:28:56 +0200 Subject: [PATCH 3/6] :bug: Fix issue that changed static data in webhook function did not get saved --- packages/cli/src/WebhookHelpers.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/cli/src/WebhookHelpers.ts b/packages/cli/src/WebhookHelpers.ts index d39e3f5dee..64e4c101ff 100644 --- a/packages/cli/src/WebhookHelpers.ts +++ b/packages/cli/src/WebhookHelpers.ts @@ -149,6 +149,9 @@ export function getWorkflowWebhooks(workflow: Workflow, additionalData: IWorkflo }; } + // Save static data if it changed + await WorkflowHelpers.saveStaticData(workflow); + if (webhookData.webhookDescription['responseHeaders'] !== undefined) { const responseHeaders = workflow.getComplexParameterValue(workflowStartNode, webhookData.webhookDescription['responseHeaders'], undefined) as { entries?: Array<{ From 6d7368d7237d9fc5020da8ce872fc18823ee6fce Mon Sep 17 00:00:00 2001 From: Ricardo Espinoza Date: Sat, 20 Jun 2020 11:51:11 -0400 Subject: [PATCH 4/6] :zap: Added description and fixed issue with colors (#686) --- .../nodes/Google/Calendar/EventDescription.ts | 18 ++++++++++++++++++ .../nodes/Google/Calendar/GenericFunctions.ts | 10 ++++++++-- .../Google/Calendar/GoogleCalendar.node.ts | 8 ++++---- 3 files changed, 30 insertions(+), 6 deletions(-) diff --git a/packages/nodes-base/nodes/Google/Calendar/EventDescription.ts b/packages/nodes-base/nodes/Google/Calendar/EventDescription.ts index 44af95a151..545ed841f1 100644 --- a/packages/nodes-base/nodes/Google/Calendar/EventDescription.ts +++ b/packages/nodes-base/nodes/Google/Calendar/EventDescription.ts @@ -177,6 +177,15 @@ export const eventFields = [ default: '', description: 'The color of the event.', }, + { + displayName: 'Description', + name: 'description', + type: 'string', + typeOptions: { + alwaysOpenEditWindow: true, + }, + default: '', + }, { displayName: 'Guests Can Invite Others', name: 'guestsCanInviteOthers', @@ -858,6 +867,15 @@ export const eventFields = [ default: '', description: 'The color of the event.', }, + { + displayName: 'Description', + name: 'description', + type: 'string', + typeOptions: { + alwaysOpenEditWindow: true, + }, + default: '', + }, { displayName: 'End', name: 'end', diff --git a/packages/nodes-base/nodes/Google/Calendar/GenericFunctions.ts b/packages/nodes-base/nodes/Google/Calendar/GenericFunctions.ts index 18d808cef7..caf4c9868d 100644 --- a/packages/nodes-base/nodes/Google/Calendar/GenericFunctions.ts +++ b/packages/nodes-base/nodes/Google/Calendar/GenericFunctions.ts @@ -33,9 +33,15 @@ export async function googleApiRequest(this: IExecuteFunctions | IExecuteSingleF //@ts-ignore return await this.helpers.requestOAuth2.call(this, 'googleCalendarOAuth2Api', options); } catch (error) { - if (error.response && error.response.body && error.response.body.message) { + if (error.response && error.response.body && error.response.body.error) { + + let errors = error.response.body.error.errors; + + errors = errors.map((e: IDataObject) => e.message); // Try to return the error prettier - throw new Error(`Google Calendar error response [${error.statusCode}]: ${error.response.body.message}`); + throw new Error( + `Google Calendar error response [${error.statusCode}]: ${errors.join('|')}` + ); } throw error; } diff --git a/packages/nodes-base/nodes/Google/Calendar/GoogleCalendar.node.ts b/packages/nodes-base/nodes/Google/Calendar/GoogleCalendar.node.ts index dc0ddad947..4c8208590e 100644 --- a/packages/nodes-base/nodes/Google/Calendar/GoogleCalendar.node.ts +++ b/packages/nodes-base/nodes/Google/Calendar/GoogleCalendar.node.ts @@ -97,16 +97,16 @@ export class GoogleCalendar implements INodeType { this: ILoadOptionsFunctions ): Promise { const returnData: INodePropertyOptions[] = []; - const { calendar } = await googleApiRequest.call( + const { event } = await googleApiRequest.call( this, 'GET', '/calendar/v3/colors' ); - for (const key of Object.keys(calendar)) { - const colorName = calendar[key].background; + for (const key of Object.keys(event)) { + const colorName = `Background: ${event[key].background} - Foreground: ${event[key].foreground}`; const colorId = key; returnData.push({ - name: `${colorName} - ${colorId}`, + name: `${colorName}`, value: colorId }); } From 3d45b67d50477dc02bdc2b73cdd90e33e71e45e7 Mon Sep 17 00:00:00 2001 From: Ricardo Espinoza Date: Sat, 20 Jun 2020 12:08:30 -0400 Subject: [PATCH 5/6] :bug: Fixes issue #663 and #664 --- .../nodes/Gitlab/GenericFunctions.ts | 7 ++++-- .../nodes/Gitlab/GitlabTrigger.node.ts | 23 +++++++++++++++---- 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/packages/nodes-base/nodes/Gitlab/GenericFunctions.ts b/packages/nodes-base/nodes/Gitlab/GenericFunctions.ts index 8f1811b8c7..6362896cff 100644 --- a/packages/nodes-base/nodes/Gitlab/GenericFunctions.ts +++ b/packages/nodes-base/nodes/Gitlab/GenericFunctions.ts @@ -1,6 +1,7 @@ import { IExecuteFunctions, IHookFunctions, + ILoadOptionsFunctions, } from 'n8n-core'; import { @@ -16,7 +17,7 @@ import { * @param {object} body * @returns {Promise} */ -export async function gitlabApiRequest(this: IHookFunctions | IExecuteFunctions, method: string, endpoint: string, body: object, query?: object): Promise { // tslint:disable-line:no-any +export async function gitlabApiRequest(this: IHookFunctions | IExecuteFunctions | ILoadOptionsFunctions, method: string, endpoint: string, body: object, query?: object): Promise { // tslint:disable-line:no-any const credentials = this.getCredentials('gitlabApi'); if (credentials === undefined) { throw new Error('No credentials got returned!'); @@ -34,7 +35,9 @@ export async function gitlabApiRequest(this: IHookFunctions | IExecuteFunctions, }; try { - return await this.helpers.request(options); + //@ts-ignore + return await this.helpers?.request(options); + } catch (error) { if (error.statusCode === 401) { // Return a clear error diff --git a/packages/nodes-base/nodes/Gitlab/GitlabTrigger.node.ts b/packages/nodes-base/nodes/Gitlab/GitlabTrigger.node.ts index 28987c2458..a97f2be536 100644 --- a/packages/nodes-base/nodes/Gitlab/GitlabTrigger.node.ts +++ b/packages/nodes-base/nodes/Gitlab/GitlabTrigger.node.ts @@ -135,7 +135,10 @@ export class GitlabTrigger implements INodeType { // Webhook got created before so check if it still exists const owner = this.getNodeParameter('owner') as string; const repository = this.getNodeParameter('repository') as string; - const endpoint = `/projects/${owner}%2F${repository}/hooks/${webhookData.webhookId}`; + + const path = (`${owner}/${repository}`).replace(/\//g,'%2F'); + + const endpoint = `/projects/${path}/hooks/${webhookData.webhookId}`; try { await gitlabApiRequest.call(this, 'GET', endpoint, {}); @@ -175,15 +178,22 @@ export class GitlabTrigger implements INodeType { events[`${e}_events`] = true; } - const endpoint = `/projects/${owner}%2F${repository}/hooks`; + // gitlab set the push_events to true when the field it's not sent. + // set it to false when it's not picked by the user. + if (events['push_events'] === undefined) { + events['push_events'] = false; + } + + const path = (`${owner}/${repository}`).replace(/\//g,'%2F'); + + const endpoint = `/projects/${path}/hooks`; const body = { url: webhookUrl, - events, + ...events, enable_ssl_verification: false, }; - let responseData; try { responseData = await gitlabApiRequest.call(this, 'POST', endpoint, body); @@ -208,7 +218,10 @@ export class GitlabTrigger implements INodeType { if (webhookData.webhookId !== undefined) { const owner = this.getNodeParameter('owner') as string; const repository = this.getNodeParameter('repository') as string; - const endpoint = `/projects/${owner}%2F${repository}/hooks/${webhookData.webhookId}`; + + const path = (`${owner}/${repository}`).replace(/\//g,'%2F'); + + const endpoint = `/projects/${path}/hooks/${webhookData.webhookId}`; const body = {}; try { From 54a670c0de778d6db8d64ecf39c21f50b9901f0f Mon Sep 17 00:00:00 2001 From: Ricardo Espinoza Date: Sat, 20 Jun 2020 12:11:11 -0400 Subject: [PATCH 6/6] :bug: Fixes issue #651 and #652 (#668) * :bug: Fixes issue #651 and #652 * :zap: Added description to username field --- .../credentials/SlackOAuth2Api.credentials.ts | 3 --- .../nodes/Slack/MessageDescription.ts | 22 +------------------ packages/nodes-base/nodes/Slack/Slack.node.ts | 8 +++---- 3 files changed, 5 insertions(+), 28 deletions(-) diff --git a/packages/nodes-base/credentials/SlackOAuth2Api.credentials.ts b/packages/nodes-base/credentials/SlackOAuth2Api.credentials.ts index b56699fe68..0426ceee02 100644 --- a/packages/nodes-base/credentials/SlackOAuth2Api.credentials.ts +++ b/packages/nodes-base/credentials/SlackOAuth2Api.credentials.ts @@ -6,15 +6,12 @@ import { //https://api.slack.com/authentication/oauth-v2 const userScopes = [ 'chat:write', - 'conversations:history', - 'conversations:read', 'files:read', 'files:write', 'stars:read', 'stars:write', ]; - export class SlackOAuth2Api implements ICredentialType { name = 'slackOAuth2Api'; extends = [ diff --git a/packages/nodes-base/nodes/Slack/MessageDescription.ts b/packages/nodes-base/nodes/Slack/MessageDescription.ts index d5170aba67..8d91663155 100644 --- a/packages/nodes-base/nodes/Slack/MessageDescription.ts +++ b/packages/nodes-base/nodes/Slack/MessageDescription.ts @@ -111,7 +111,7 @@ export const messageFields = [ ], }, }, - description: 'Set the bot\'s user name.', + description: 'Set the bot\'s user name. This field will be ignored if you are using a user token.', }, { displayName: 'JSON parameters', @@ -486,26 +486,6 @@ export const messageFields = [ }, description: `Timestamp of the message to be updated.`, }, - { - displayName: 'As User', - name: 'as_user', - type: 'boolean', - default: false, - displayOptions: { - show: { - authentication: [ - 'accessToken', - ], - operation: [ - 'update' - ], - resource: [ - 'message', - ], - }, - }, - description: 'Pass true to update the message as the authed user. Bot users in this context are considered authed users.', - }, { displayName: 'Update Fields', name: 'updateFields', diff --git a/packages/nodes-base/nodes/Slack/Slack.node.ts b/packages/nodes-base/nodes/Slack/Slack.node.ts index 57fe569d22..befe931fb5 100644 --- a/packages/nodes-base/nodes/Slack/Slack.node.ts +++ b/packages/nodes-base/nodes/Slack/Slack.node.ts @@ -454,6 +454,10 @@ export class Slack implements INodeType { body.username = this.getNodeParameter('username', i) as string; } + // ignore body.as_user as it's deprecated + + delete body.as_user; + if (!jsonParameters) { const attachments = this.getNodeParameter('attachments', i, []) as unknown as Attachment[]; const blocksUi = (this.getNodeParameter('blocksUi', i, []) as IDataObject).blocksValues as IDataObject[]; @@ -691,10 +695,6 @@ export class Slack implements INodeType { ts, }; - if (authentication === 'accessToken') { - body.as_user = this.getNodeParameter('as_user', i) as boolean; - } - // 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) {