This commit is contained in:
Rupenieks 2020-05-04 10:03:36 +02:00
commit 0915546296
22 changed files with 271 additions and 38 deletions

View file

@ -21,7 +21,7 @@ Software: n8n
License: Apache 2.0
Licensor: Jan Oberhauser
Licensor: n8n GmbH
---------------------------------------------------------------------

View file

@ -21,7 +21,7 @@ Software: n8n
License: Apache 2.0
Licensor: Jan Oberhauser
Licensor: n8n GmbH
---------------------------------------------------------------------

View file

@ -1,6 +1,6 @@
{
"name": "n8n",
"version": "0.65.0",
"version": "0.66.0",
"description": "n8n Workflow Automation Tool",
"license": "SEE LICENSE IN LICENSE.md",
"homepage": "https://n8n.io",
@ -95,10 +95,10 @@
"lodash.get": "^4.4.2",
"mongodb": "^3.5.5",
"mysql2": "^2.0.1",
"n8n-core": "~0.32.0",
"n8n-editor-ui": "~0.43.0",
"n8n-nodes-base": "~0.60.0",
"n8n-workflow": "~0.29.0",
"n8n-core": "~0.33.0",
"n8n-editor-ui": "~0.44.0",
"n8n-nodes-base": "~0.61.0",
"n8n-workflow": "~0.30.0",
"open": "^7.0.0",
"pg": "^7.11.0",
"request-promise-native": "^1.0.7",

View file

@ -512,11 +512,8 @@ class App {
const sessionId = GenericHelpers.getSessionId(req);
// Check if workflow is saved as webhooks can only be tested with saved workflows.
// If that is the case check if any webhooks calls are present we have to wait for and
// if that is the case wait till we receive it.
if (WorkflowHelpers.isWorkflowIdValid(workflowData.id) === true && (runData === undefined || startNodes === undefined || startNodes.length === 0 || destinationNode === undefined)) {
// Webhooks can only be tested with saved workflows
// If webhooks nodes exist and are active we have to wait for till we receive a call
if (runData === undefined || startNodes === undefined || startNodes.length === 0 || destinationNode === undefined) {
const credentials = await WorkflowCredentials(workflowData.nodes);
const additionalData = await WorkflowExecuteAdditionalData.getBase(credentials);
const nodeTypes = NodeTypes();

View file

@ -129,6 +129,10 @@ export class TestWebhooks {
return false;
}
if (workflow.id === undefined) {
throw new Error('Webhooks can only be added for saved workflows as an id is needed!');
}
// Remove test-webhooks automatically if they do not get called (after 120 seconds)
const timeout = setTimeout(() => {
this.cancelTestWebhook(workflowData.id.toString());

View file

@ -21,7 +21,7 @@ Software: n8n
License: Apache 2.0
Licensor: Jan Oberhauser
Licensor: n8n GmbH
---------------------------------------------------------------------

View file

@ -1,6 +1,6 @@
{
"name": "n8n-core",
"version": "0.32.0",
"version": "0.33.0",
"description": "Core functionality of n8n",
"license": "SEE LICENSE IN LICENSE.md",
"homepage": "https://n8n.io",
@ -44,7 +44,7 @@
"crypto-js": "3.1.9-1",
"lodash.get": "^4.4.2",
"mmmagic": "^0.5.2",
"n8n-workflow": "~0.29.0",
"n8n-workflow": "~0.30.0",
"p-cancelable": "^2.0.0",
"request": "^2.88.2",
"request-promise-native": "^1.0.7"

View file

@ -21,7 +21,7 @@ Software: n8n
License: Apache 2.0
Licensor: Jan Oberhauser
Licensor: n8n GmbH
---------------------------------------------------------------------

View file

@ -1,6 +1,6 @@
{
"name": "n8n-editor-ui",
"version": "0.43.0",
"version": "0.44.0",
"description": "Workflow Editor UI for n8n",
"license": "SEE LICENSE IN LICENSE.md",
"homepage": "https://n8n.io",
@ -64,7 +64,7 @@
"lodash.debounce": "^4.0.8",
"lodash.get": "^4.4.2",
"lodash.set": "^4.3.2",
"n8n-workflow": "~0.29.0",
"n8n-workflow": "~0.30.0",
"node-sass": "^4.12.0",
"prismjs": "^1.17.1",
"quill": "^2.0.0-dev.3",

View file

@ -21,7 +21,7 @@ Software: n8n
License: Apache 2.0
Licensor: Jan Oberhauser
Licensor: n8n GmbH
---------------------------------------------------------------------

View file

@ -21,7 +21,7 @@ Software: n8n
License: Apache 2.0
Licensor: Jan Oberhauser
Licensor: n8n GmbH
---------------------------------------------------------------------

View file

@ -0,0 +1,17 @@
import {
ICredentialType,
NodePropertyTypes,
} from 'n8n-workflow';
export class Sms77Api implements ICredentialType {
name = 'sms77Api';
displayName = 'Sms77 API';
properties = [
{
displayName: 'API Key',
name: 'apiKey',
type: 'string' as NodePropertyTypes,
default: '',
},
];
}

View file

@ -381,7 +381,22 @@ export class FacebookGraphApi implements INodeType {
throw error;
}
returnItems.push(items[itemIndex]);
let errorItem;
if (error.response !== undefined) {
// Since this is a Graph API node and we already know the request was
// not successful, we'll go straight to the error details.
const graphApiErrors = error.response.body?.error ?? {};
errorItem = {
statusCode: error.statusCode,
...graphApiErrors,
headers: error.response.headers,
};
} else {
// Unknown Graph API response, we'll dump everything in the response item
errorItem = error;
}
returnItems.push({ json: { ...errorItem } });
continue;
}
@ -391,7 +406,7 @@ export class FacebookGraphApi implements INodeType {
throw new Error('Response body is not valid JSON.');
}
returnItems.push(items[itemIndex]);
returnItems.push({ json: { message: response } });
continue;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

View file

@ -212,7 +212,7 @@ export class Github implements INodeType {
{
name: 'Get Emails',
value: 'getEmails',
description: 'Returns the repositories of a user',
description: 'Returns the email addresses of a user',
},
{
name: 'Get Repositories',

View file

@ -0,0 +1,58 @@
import {
IExecuteFunctions,
IHookFunctions,
} from 'n8n-core';
import {
ICredentialDataDecryptedObject,
IDataObject,
} from 'n8n-workflow';
/**
* Make an API request to MSG91
*
* @param {IHookFunctions | IExecuteFunctions} this
* @param {string} method
* @param {string} endpoint
* @param {object} form
* @param {object | undefined} qs
* @returns {Promise<any>}
*/
export async function sms77ApiRequest(this: IHookFunctions | IExecuteFunctions, method: string, endpoint: string, form: IDataObject, qs?: IDataObject): Promise<any> { // tslint:disable-line:no-any
const credentials = this.getCredentials('sms77Api');
if (credentials === undefined) {
throw new Error('No credentials got returned!');
}
if ('GET' === method) {
qs = setPayload(credentials, qs);
} else {
form = setPayload(credentials, form);
}
const response = await this.helpers.request({
form,
json: true,
method,
qs,
uri: `https://gateway.sms77.io/api/${endpoint}`,
});
if ('100' !== response.success) {
throw new Error('Invalid sms77 credentials or API error!');
}
return response;
}
function setPayload(credentials: ICredentialDataDecryptedObject, o?: IDataObject) {
if (!o) {
o = {};
}
o.p = credentials!.apiKey as string;
o.json = 1;
o.sendwith = 'n8n';
return o;
}

View file

@ -0,0 +1,144 @@
import {IExecuteFunctions,} from 'n8n-core';
import {IDataObject, INodeExecutionData, INodeType, INodeTypeDescription,} from 'n8n-workflow';
import {sms77ApiRequest} from './GenericFunctions';
export class Sms77 implements INodeType {
description: INodeTypeDescription = {
displayName: 'Sms77',
name: 'sms77',
icon: 'file:sms77.png',
group: ['transform'],
version: 1,
subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}',
description: 'Send SMS',
defaults: {
name: 'Sms77',
color: '#18D46A',
},
inputs: ['main'],
outputs: ['main'],
credentials: [
{
name: 'sms77Api',
required: true,
}
],
properties: [
{
displayName: 'Resource',
name: 'resource',
type: 'options',
options: [
{
name: 'SMS',
value: 'sms',
},
],
default: 'sms',
description: 'The resource to operate on.',
},
{
displayName: 'Operation',
name: 'operation',
type: 'options',
displayOptions: {
show: {
resource: [
'sms',
],
},
},
options: [
{
name: 'Send',
value: 'send',
description: 'Send SMS',
},
],
default: 'send',
description: 'The operation to perform.',
},
{
displayName: 'From',
name: 'from',
type: 'string',
default: '',
placeholder: '+4901234567890',
required: false,
displayOptions: {
show: {
operation: [
'send',
],
resource: [
'sms',
],
},
},
description: 'The number from which to send the message.',
},
{
displayName: 'To',
name: 'to',
type: 'string',
default: '',
placeholder: '+49876543210',
required: true,
displayOptions: {
show: {
operation: [
'send',
],
resource: [
'sms',
],
},
},
description: 'The number, with coutry code, to which to send the message.',
},
{
displayName: 'Message',
name: 'message',
type: 'string',
default: '',
required: true,
displayOptions: {
show: {
operation: [
'send',
],
resource: [
'sms',
],
},
},
description: 'The message to send',
},
],
};
async execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {
const returnData: IDataObject[] = [];
for (let i = 0; i < this.getInputData().length; i++) {
const resource = this.getNodeParameter('resource', i);
if ('sms' !== resource) {
throw new Error(`The resource "${resource}" is not known!`);
}
const operation = this.getNodeParameter('operation', i);
if ('send' !== operation) {
throw new Error(`The operation "${operation}" is not known!`);
}
const responseData = await sms77ApiRequest.call(this, 'POST', 'sms', {}, {
from: this.getNodeParameter('from', i),
to: this.getNodeParameter('to', i),
text: this.getNodeParameter('message', i),
});
returnData.push(responseData);
}
return [this.helpers.returnJsonArray(returnData)];
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

View file

@ -1,6 +1,6 @@
{
"name": "n8n-nodes-base",
"version": "0.60.0",
"version": "0.61.0",
"description": "Base nodes of n8n",
"license": "SEE LICENSE IN LICENSE.md",
"homepage": "https://n8n.io",
@ -93,6 +93,7 @@
"dist/credentials/RundeckApi.credentials.js",
"dist/credentials/ShopifyApi.credentials.js",
"dist/credentials/SlackApi.credentials.js",
"dist/credentials/Sms77Api.credentials.js",
"dist/credentials/Smtp.credentials.js",
"dist/credentials/StripeApi.credentials.js",
"dist/credentials/SalesmateApi.credentials.js",
@ -221,6 +222,7 @@
"dist/nodes/Shopify/Shopify.node.js",
"dist/nodes/Shopify/ShopifyTrigger.node.js",
"dist/nodes/Slack/Slack.node.js",
"dist/nodes/Sms77/Sms77.node.js",
"dist/nodes/SplitInBatches.node.js",
"dist/nodes/SpreadsheetFile.node.js",
"dist/nodes/SseTrigger.node.js",
@ -274,7 +276,7 @@
"@types/xml2js": "^0.4.3",
"gulp": "^4.0.0",
"jest": "^24.9.0",
"n8n-workflow": "~0.29.0",
"n8n-workflow": "~0.30.0",
"ts-jest": "^24.0.2",
"tslint": "^5.17.0",
"typescript": "~3.7.4"
@ -298,7 +300,7 @@
"moment-timezone": "^0.5.28",
"mongodb": "^3.5.5",
"mysql2": "^2.0.1",
"n8n-core": "~0.32.0",
"n8n-core": "~0.33.0",
"nodemailer": "^5.1.1",
"pdf-parse": "^1.1.1",
"pg-promise": "^9.0.3",

View file

@ -21,7 +21,7 @@ Software: n8n
License: Apache 2.0
Licensor: Jan Oberhauser
Licensor: n8n GmbH
---------------------------------------------------------------------

View file

@ -1,6 +1,6 @@
{
"name": "n8n-workflow",
"version": "0.29.0",
"version": "0.30.0",
"description": "Workflow base code of n8n",
"license": "SEE LICENSE IN LICENSE.md",
"homepage": "https://n8n.io",

View file

@ -728,12 +728,6 @@ export function getNodeWebhooks(workflow: Workflow, node: INode, additionalData:
return [];
}
if (workflow.id === undefined) {
// Workflow has no id which means it is not saved and so webhooks
// will not be enabled
return [];
}
const nodeType = workflow.nodeTypes.getByName(node.type) as INodeType;
if (nodeType.description.webhooks === undefined) {
@ -741,12 +735,14 @@ export function getNodeWebhooks(workflow: Workflow, node: INode, additionalData:
return [];
}
const workflowId = workflow.id || '__UNSAVED__';
const returnData: IWebhookData[] = [];
for (const webhookDescription of nodeType.description.webhooks) {
let nodeWebhookPath = workflow.getSimpleParameterValue(node, webhookDescription['path'], 'GET');
if (nodeWebhookPath === undefined) {
// TODO: Use a proper logger
console.error(`No webhook path could be found for node "${node.name}" in workflow "${workflow.id}".`);
console.error(`No webhook path could be found for node "${node.name}" in workflow "${workflowId}".`);
continue;
}
@ -756,13 +752,13 @@ export function getNodeWebhooks(workflow: Workflow, node: INode, additionalData:
nodeWebhookPath = nodeWebhookPath.slice(1);
}
const path = getNodeWebhookPath(workflow.id, node, nodeWebhookPath);
const path = getNodeWebhookPath(workflowId, node, nodeWebhookPath);
const httpMethod = workflow.getSimpleParameterValue(node, webhookDescription['httpMethod'], 'GET');
if (httpMethod === undefined) {
// TODO: Use a proper logger
console.error(`The webhook "${path}" for node "${node.name}" in workflow "${workflow.id}" could not be added because the httpMethod is not defined.`);
console.error(`The webhook "${path}" for node "${node.name}" in workflow "${workflowId}" could not be added because the httpMethod is not defined.`);
continue;
}
@ -771,7 +767,7 @@ export function getNodeWebhooks(workflow: Workflow, node: INode, additionalData:
node: node.name,
path,
webhookDescription,
workflowId: workflow.id,
workflowId,
workflowExecuteAdditionalData: additionalData,
});
}