mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-17 18:12:04 +00:00
feat(Respond to Webhook Node): Additional output branch - Response (#13734)
This commit is contained in:
@@ -216,6 +216,7 @@ export const GITHUB_NODE_TYPE = 'n8n-nodes-base.github';
|
|||||||
export const SLACK_TRIGGER_NODE_TYPE = 'n8n-nodes-base.slackTrigger';
|
export const SLACK_TRIGGER_NODE_TYPE = 'n8n-nodes-base.slackTrigger';
|
||||||
export const TELEGRAM_TRIGGER_NODE_TYPE = 'n8n-nodes-base.telegramTrigger';
|
export const TELEGRAM_TRIGGER_NODE_TYPE = 'n8n-nodes-base.telegramTrigger';
|
||||||
export const FACEBOOK_LEAD_ADS_TRIGGER_NODE_TYPE = 'n8n-nodes-base.facebookLeadAdsTrigger';
|
export const FACEBOOK_LEAD_ADS_TRIGGER_NODE_TYPE = 'n8n-nodes-base.facebookLeadAdsTrigger';
|
||||||
|
export const RESPOND_TO_WEBHOOK_NODE_TYPE = 'n8n-nodes-base.respondToWebhook';
|
||||||
|
|
||||||
export const CREDENTIAL_ONLY_NODE_PREFIX = 'n8n-creds-base';
|
export const CREDENTIAL_ONLY_NODE_PREFIX = 'n8n-creds-base';
|
||||||
export const CREDENTIAL_ONLY_HTTP_NODE_VERSION = 4.1;
|
export const CREDENTIAL_ONLY_HTTP_NODE_VERSION = 4.1;
|
||||||
@@ -795,6 +796,7 @@ export const NODE_TYPES_EXCLUDED_FROM_OUTPUT_NAME_APPEND = [
|
|||||||
FILTER_NODE_TYPE,
|
FILTER_NODE_TYPE,
|
||||||
SWITCH_NODE_TYPE,
|
SWITCH_NODE_TYPE,
|
||||||
REMOVE_DUPLICATES_NODE_TYPE,
|
REMOVE_DUPLICATES_NODE_TYPE,
|
||||||
|
RESPOND_TO_WEBHOOK_NODE_TYPE,
|
||||||
];
|
];
|
||||||
|
|
||||||
type ClearOutgoingConnectonsEvents = {
|
type ClearOutgoingConnectonsEvents = {
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import {
|
|||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
import type { Readable } from 'stream';
|
import type { Readable } from 'stream';
|
||||||
|
|
||||||
|
import { configuredOutputs } from './utils';
|
||||||
import { formatPrivateKey, generatePairedItemData } from '../../utils/utilities';
|
import { formatPrivateKey, generatePairedItemData } from '../../utils/utilities';
|
||||||
|
|
||||||
const respondWithProperty: INodeProperties = {
|
const respondWithProperty: INodeProperties = {
|
||||||
@@ -80,13 +81,13 @@ export class RespondToWebhook implements INodeType {
|
|||||||
icon: { light: 'file:webhook.svg', dark: 'file:webhook.dark.svg' },
|
icon: { light: 'file:webhook.svg', dark: 'file:webhook.dark.svg' },
|
||||||
name: 'respondToWebhook',
|
name: 'respondToWebhook',
|
||||||
group: ['transform'],
|
group: ['transform'],
|
||||||
version: [1, 1.1, 1.2],
|
version: [1, 1.1, 1.2, 1.3],
|
||||||
description: 'Returns data for Webhook',
|
description: 'Returns data for Webhook',
|
||||||
defaults: {
|
defaults: {
|
||||||
name: 'Respond to Webhook',
|
name: 'Respond to Webhook',
|
||||||
},
|
},
|
||||||
inputs: [NodeConnectionTypes.Main],
|
inputs: [NodeConnectionTypes.Main],
|
||||||
outputs: [NodeConnectionTypes.Main],
|
outputs: `={{(${configuredOutputs})($nodeVersion)}}`,
|
||||||
credentials: [
|
credentials: [
|
||||||
{
|
{
|
||||||
name: 'jwtAuth',
|
name: 'jwtAuth',
|
||||||
@@ -318,6 +319,8 @@ export class RespondToWebhook implements INodeType {
|
|||||||
WAIT_NODE_TYPE,
|
WAIT_NODE_TYPE,
|
||||||
];
|
];
|
||||||
|
|
||||||
|
let response: IN8nHttpFullResponse;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (nodeVersion >= 1.1) {
|
if (nodeVersion >= 1.1) {
|
||||||
const connectedNodes = this.getParentNodes(this.getNode().name);
|
const connectedNodes = this.getParentNodes(this.getNode().name);
|
||||||
@@ -445,7 +448,7 @@ export class RespondToWebhook implements INodeType {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const response: IN8nHttpFullResponse = {
|
response = {
|
||||||
body: responseBody,
|
body: responseBody,
|
||||||
headers,
|
headers,
|
||||||
statusCode,
|
statusCode,
|
||||||
@@ -465,6 +468,10 @@ export class RespondToWebhook implements INodeType {
|
|||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (nodeVersion >= 1.3) {
|
||||||
|
return [items, [{ json: { response } }]];
|
||||||
|
}
|
||||||
|
|
||||||
return [items];
|
return [items];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -202,12 +202,15 @@ describe('RespondToWebhook Node', () => {
|
|||||||
});
|
});
|
||||||
mockExecuteFunctions.sendResponse.mockReturnValue();
|
mockExecuteFunctions.sendResponse.mockReturnValue();
|
||||||
|
|
||||||
await expect(respondToWebhook.execute.call(mockExecuteFunctions)).resolves.not.toThrow();
|
const result = await respondToWebhook.execute.call(mockExecuteFunctions);
|
||||||
expect(mockExecuteFunctions.sendResponse).toHaveBeenCalledWith({
|
expect(mockExecuteFunctions.sendResponse).toHaveBeenCalledWith({
|
||||||
body: inputItems.map((item) => item.json),
|
body: inputItems.map((item) => item.json),
|
||||||
headers: {},
|
headers: {},
|
||||||
statusCode: 200,
|
statusCode: 200,
|
||||||
});
|
});
|
||||||
|
expect(result).toHaveLength(1);
|
||||||
|
expect(result[0]).toHaveLength(2);
|
||||||
|
expect(result[0]).toEqual(inputItems);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should correctly return binary', async () => {
|
it('should correctly return binary', async () => {
|
||||||
@@ -259,5 +262,52 @@ describe('RespondToWebhook Node', () => {
|
|||||||
]);
|
]);
|
||||||
expect(mockExecuteFunctions.sendResponse).not.toHaveBeenCalled();
|
expect(mockExecuteFunctions.sendResponse).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should have two outputs in version 1.3', async () => {
|
||||||
|
const inputItems = [{ json: { index: 0, input: true } }, { json: { index: 1, input: true } }];
|
||||||
|
mockExecuteFunctions.getInputData.mockReturnValue(inputItems);
|
||||||
|
mockExecuteFunctions.getNode.mockReturnValue(mock<INode>({ typeVersion: 1.3 }));
|
||||||
|
mockExecuteFunctions.getParentNodes.mockReturnValue([
|
||||||
|
mock<NodeTypeAndVersion>({ type: WAIT_NODE_TYPE }),
|
||||||
|
]);
|
||||||
|
mockExecuteFunctions.getNodeParameter.mockImplementation((paramName) => {
|
||||||
|
if (paramName === 'respondWith') return 'redirect';
|
||||||
|
if (paramName === 'redirectURL') return 'n8n.io';
|
||||||
|
if (paramName === 'options') return {};
|
||||||
|
});
|
||||||
|
mockExecuteFunctions.sendResponse.mockReturnValue();
|
||||||
|
|
||||||
|
const result = await respondToWebhook.execute.call(mockExecuteFunctions);
|
||||||
|
|
||||||
|
expect(result).toHaveLength(2);
|
||||||
|
expect(result).toEqual([
|
||||||
|
[
|
||||||
|
{
|
||||||
|
json: {
|
||||||
|
index: 0,
|
||||||
|
input: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
json: {
|
||||||
|
index: 1,
|
||||||
|
input: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
json: {
|
||||||
|
response: {
|
||||||
|
headers: {
|
||||||
|
location: 'n8n.io',
|
||||||
|
},
|
||||||
|
statusCode: 307,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
import { configuredOutputs } from '../utils';
|
||||||
|
|
||||||
|
describe('configuredOutputs', () => {
|
||||||
|
it('returns array of objects when version >= 1.3', () => {
|
||||||
|
const result = configuredOutputs(1.3);
|
||||||
|
expect(result).toEqual([
|
||||||
|
{ type: 'main', displayName: 'Input Data' },
|
||||||
|
{ type: 'main', displayName: 'Response' },
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns array of objects when version > 1.3', () => {
|
||||||
|
const result = configuredOutputs(2);
|
||||||
|
expect(result).toEqual([
|
||||||
|
{ type: 'main', displayName: 'Input Data' },
|
||||||
|
{ type: 'main', displayName: 'Response' },
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns ["main"] when version < 1.3', () => {
|
||||||
|
const result = configuredOutputs(1.2);
|
||||||
|
expect(result).toEqual(['main']);
|
||||||
|
});
|
||||||
|
});
|
||||||
16
packages/nodes-base/nodes/RespondToWebhook/utils.ts
Normal file
16
packages/nodes-base/nodes/RespondToWebhook/utils.ts
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
export const configuredOutputs = (version: number) => {
|
||||||
|
if (version >= 1.3) {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
type: 'main',
|
||||||
|
displayName: 'Input Data',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'main',
|
||||||
|
displayName: 'Response',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
return ['main'];
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user