Make it possible to return custom content-type and data with

webhook
This commit is contained in:
Jan Oberhauser 2019-10-16 14:01:39 +02:00
parent 1173c998fc
commit ded2152d61
3 changed files with 87 additions and 12 deletions

View file

@ -1,4 +1,5 @@
import * as express from 'express';
import { get } from 'lodash';
import {
ActiveExecutions,
@ -275,24 +276,54 @@ export function getWorkflowWebhooks(workflow: Workflow, additionalData: IWorkflo
if (responseData === 'firstEntryJson') {
// Return the JSON data of the first entry
data = returnData.data!.main[0]![0].json;
const responsePropertyName = webhookData.workflow.getSimpleParameterValue(workflowStartNode, webhookData.webhookDescription['responsePropertyName'], undefined);
if (responsePropertyName !== undefined) {
data = get(data, responsePropertyName as string) as IDataObject;
}
const responseContentType = webhookData.workflow.getSimpleParameterValue(workflowStartNode, webhookData.webhookDescription['responseContentType'], undefined);
if (responseContentType !== undefined) {
// Send the webhook response manually to be able to set the content-type
res.setHeader('Content-Type', responseContentType as string);
// Returning an object, boolean, number, ... causes problems so make sure to stringify if needed
if (data !== null && data !== undefined && ['Buffer', 'String'].includes(data.constructor.name)) {
res.end(data);
} else {
res.end(JSON.stringify(data));
}
responseCallback(null, {
noWebhookResponse: true,
});
didSendResponse = true;
}
} else if (responseData === 'firstEntryBinary') {
// Return the binary data of the first entry
data = returnData.data!.main[0]![0];
if (data.binary === undefined) {
responseCallback(new Error('No binary data to return got found.'), {});
didSendResponse = true;
}
const responseBinaryPropertyName = webhookData.workflow.getSimpleParameterValue(workflowStartNode, webhookData.webhookDescription['responseBinaryPropertyName'], 'data');
if (responseBinaryPropertyName === undefined) {
if (responseBinaryPropertyName === undefined && didSendResponse === false) {
responseCallback(new Error('No "responseBinaryPropertyName" is set.'), {});
didSendResponse = true;
}
const binaryData = (data.binary as IBinaryKeyData)[responseBinaryPropertyName as string];
if (binaryData === undefined) {
if (binaryData === undefined && didSendResponse === false) {
responseCallback(new Error(`The binary property "${responseBinaryPropertyName}" which should be returned does not exist.`), {});
didSendResponse = true;
}
if (didSendResponse === false) {
// Send the webhook response manually
res.setHeader('Content-Type', binaryData.mimeType);
res.end(Buffer.from(binaryData.data, BINARY_ENCODING));
@ -300,6 +331,8 @@ export function getWorkflowWebhooks(workflow: Workflow, additionalData: IWorkflo
responseCallback(null, {
noWebhookResponse: true,
});
}
} else {
// Return the JSON data of all the entries
data = [];
@ -308,11 +341,13 @@ export function getWorkflowWebhooks(workflow: Workflow, additionalData: IWorkflo
}
}
if (didSendResponse === false) {
responseCallback(null, {
data,
responseCode,
});
}
}
didSendResponse = true;
return data;

View file

@ -75,6 +75,8 @@ export class Webhook implements INodeType {
responseMode: '={{$parameter["responseMode"]}}',
responseData: '={{$parameter["responseData"]}}',
responseBinaryPropertyName: '={{$parameter["responseBinaryPropertyName"]}}',
responseContentType: '={{$parameter["options"]["responseContentType"]}}',
responsePropertyName: '={{$parameter["options"]["responsePropertyName"]}}',
path: '={{$parameter["path"]}}',
},
],
@ -203,6 +205,42 @@ export class Webhook implements INodeType {
},
description: 'Name of the binary property to return',
},
{
displayName: 'Options',
name: 'options',
type: 'collection',
displayOptions: {
show: {
responseData: [
'firstEntryJson',
],
responseMode: [
'lastNode',
],
},
},
placeholder: 'Add Option',
default: {},
options: [
{
displayName: 'Response Content-Type',
name: 'responseContentType',
type: 'string',
default: '',
placeholder: 'application/xml',
description: 'Set a custom content-type to return if another one as the "application/json" should be returned.',
},
{
displayName: 'Property Name',
name: 'responsePropertyName',
type: 'string',
default: 'data',
description: 'Name of the property to return the data of instead of the whole JSON.',
},
],
},
],
};

View file

@ -467,6 +467,8 @@ export interface IWebhookDescription {
name: string;
path: string;
responseBinaryPropertyName?: string;
responseContentType?: string;
responsePropertyName?: string;
responseMode?: WebhookResponseMode | string;
responseData?: WebhookResponseData | string;
}