Move options around and also allow no data for last node

This commit is contained in:
Jan Oberhauser 2022-02-19 12:37:41 +01:00
parent cb3f0a0ec6
commit ea1b627ab0
3 changed files with 67 additions and 50 deletions

View file

@ -204,14 +204,15 @@ export async function executeWebhook(
200, 200,
) as number; ) as number;
if ( const responseData = workflow.expression.getSimpleParameterValue(
![ workflowStartNode,
'onReceived', webhookData.webhookDescription.responseData,
'lastNode', executionMode,
'responseNode', additionalKeys,
'noBodyResponse' 'firstEntryJson',
].includes(responseMode as string) );
) {
if (!['onReceived', 'lastNode', 'responseNode'].includes(responseMode as string)) {
// If the mode is not known we error. Is probably best like that instead of using // If the mode is not known we error. Is probably best like that instead of using
// the default that people know as early as possible (probably already testing phase) // the default that people know as early as possible (probably already testing phase)
// that something does not resolve properly. // that something does not resolve properly.
@ -338,7 +339,12 @@ export async function executeWebhook(
// directly if responseMode it set to "onReceived" and a respone should be sent // directly if responseMode it set to "onReceived" and a respone should be sent
if (responseMode === 'onReceived' && !didSendResponse) { if (responseMode === 'onReceived' && !didSendResponse) {
// Return response directly and do not wait for the workflow to finish // Return response directly and do not wait for the workflow to finish
if (webhookResultData.webhookResponse !== undefined) { if (responseData === 'noData') {
// Return without data
responseCallback(null, {
responseCode,
});
} else if (webhookResultData.webhookResponse !== undefined) {
// Data to respond with is given // Data to respond with is given
responseCallback(null, { responseCallback(null, {
data: webhookResultData.webhookResponse, data: webhookResultData.webhookResponse,
@ -356,17 +362,6 @@ export async function executeWebhook(
didSendResponse = true; didSendResponse = true;
} }
// Some systems require that a webhook doesn't respond with any data
// if responseMode is set to noBodyResponse we will see this fire
if (responseMode === 'noBodyResponse' && !didSendResponse) {
// Return response without data
responseCallback(null, {
responseCode,
});
didSendResponse = true;
}
// Initialize the data of the webhook node // Initialize the data of the webhook node
const nodeExecutionStack: IExecuteData[] = []; const nodeExecutionStack: IExecuteData[] = [];
nodeExecutionStack.push({ nodeExecutionStack.push({
@ -526,16 +521,8 @@ export async function executeWebhook(
$executionId: executionId, $executionId: executionId,
}; };
const responseData = workflow.expression.getSimpleParameterValue(
workflowStartNode,
webhookData.webhookDescription.responseData,
executionMode,
additionalKeys,
'firstEntryJson',
);
if (!didSendResponse) { if (!didSendResponse) {
let data: IDataObject | IDataObject[]; let data: IDataObject | IDataObject[] | undefined;
if (responseData === 'firstEntryJson') { if (responseData === 'firstEntryJson') {
// Return the JSON data of the first entry // Return the JSON data of the first entry
@ -639,6 +626,9 @@ export async function executeWebhook(
noWebhookResponse: true, noWebhookResponse: true,
}); });
} }
} else if (responseData === 'noData') {
// Return without data
data = undefined;
} else { } else {
// Return the JSON data of all the entries // Return the JSON data of all the entries
data = []; data = [];

View file

@ -85,7 +85,7 @@ export class Webhook implements INodeType {
isFullPath: true, isFullPath: true,
responseCode: '={{$parameter["responseCode"]}}', responseCode: '={{$parameter["responseCode"]}}',
responseMode: '={{$parameter["responseMode"]}}', responseMode: '={{$parameter["responseMode"]}}',
responseData: '={{$parameter["responseData"]}}', responseData: '={{$parameter["responseData"] || ($parameter.options.noResponseBody ? "noData" : undefined) }}',
responseBinaryPropertyName: '={{$parameter["responseBinaryPropertyName"]}}', responseBinaryPropertyName: '={{$parameter["responseBinaryPropertyName"]}}',
responseContentType: '={{$parameter["options"]["responseContentType"]}}', responseContentType: '={{$parameter["options"]["responseContentType"]}}',
responsePropertyName: '={{$parameter["options"]["responsePropertyName"]}}', responsePropertyName: '={{$parameter["options"]["responsePropertyName"]}}',
@ -165,11 +165,6 @@ export class Webhook implements INodeType {
value: 'responseNode', value: 'responseNode',
description: 'Response defined in that node', description: 'Response defined in that node',
}, },
{
name: 'No Body Response',
value: 'noBodyResponse',
description: 'Returns data without a body',
},
], ],
default: 'onReceived', default: 'onReceived',
description: 'When and how to respond to the webhook.', description: 'When and how to respond to the webhook.',
@ -232,6 +227,11 @@ export class Webhook implements INodeType {
value: 'firstEntryBinary', value: 'firstEntryBinary',
description: 'Returns the binary data of the first entry of the last node. Always returns a binary file.', description: 'Returns the binary data of the first entry of the last node. Always returns a binary file.',
}, },
{
name: 'No Response Body',
value: 'noData',
description: 'Returns without a body.',
},
], ],
default: 'firstEntryJson', default: 'firstEntryJson',
description: 'What data should be returned. If it should return all items as an array or only the first item as object.', description: 'What data should be returned. If it should return all items as an array or only the first item as object.',
@ -296,6 +296,42 @@ export class Webhook implements INodeType {
default: false, default: false,
description: 'Set to true to ignore requests from bots like link previewers and web crawlers', description: 'Set to true to ignore requests from bots like link previewers and web crawlers',
}, },
{
displayName: 'No Response Body',
name: 'noResponseBody',
type: 'boolean',
default: false,
description: 'Do not send any body in the response',
displayOptions: {
hide: {
'rawBody': [
true,
],
},
show: {
'/responseMode': [
'onReceived',
],
},
},
},
{
displayName: 'Raw Body',
name: 'rawBody',
type: 'boolean',
displayOptions: {
hide: {
binaryData: [
true,
],
'noResponseBody': [
true,
],
},
},
default: false,
description: 'Raw body (binary)',
},
{ {
displayName: 'Response Data', displayName: 'Response Data',
name: 'responseData', name: 'responseData',
@ -306,6 +342,11 @@ export class Webhook implements INodeType {
'onReceived', 'onReceived',
], ],
}, },
hide: {
'noResponseBody': [
true,
],
},
}, },
default: '', default: '',
placeholder: 'success', placeholder: 'success',
@ -379,20 +420,6 @@ export class Webhook implements INodeType {
default: 'data', default: 'data',
description: 'Name of the property to return the data of instead of the whole JSON.', description: 'Name of the property to return the data of instead of the whole JSON.',
}, },
{
displayName: 'Raw Body',
name: 'rawBody',
type: 'boolean',
displayOptions: {
hide: {
binaryData: [
true,
],
},
},
default: false,
description: 'Raw body (binary)',
},
], ],
}, },
], ],

View file

@ -1186,7 +1186,7 @@ export interface IWebhookResponseData {
noWebhookResponse?: boolean; noWebhookResponse?: boolean;
} }
export type WebhookResponseData = 'allEntries' | 'firstEntryJson' | 'firstEntryBinary'; export type WebhookResponseData = 'allEntries' | 'firstEntryJson' | 'firstEntryBinary' | 'noData';
export type WebhookResponseMode = 'onReceived' | 'lastNode'; export type WebhookResponseMode = 'onReceived' | 'lastNode';
export interface INodeTypes { export interface INodeTypes {