diff --git a/packages/nodes-base/nodes/Webhook.node.ts b/packages/nodes-base/nodes/Webhook.node.ts index e2efa73e1..00e56a13f 100644 --- a/packages/nodes-base/nodes/Webhook.node.ts +++ b/packages/nodes-base/nodes/Webhook.node.ts @@ -219,6 +219,35 @@ export class Webhook implements INodeType { placeholder: 'Add Option', default: {}, options: [ + { + displayName: 'Binary Data', + name: 'binaryData', + type: 'boolean', + displayOptions: { + show: { + '/httpMethod': [ + 'POST', + ], + }, + }, + default: false, + description: 'Set to true if webhook will receive binary data.', + }, + { + displayName: 'Binary Property', + name: 'binaryPropertyName', + type: 'string', + default: 'data', + required: true, + displayOptions: { + show: { + binaryData: [ + true, + ], + }, + }, + description: 'Name of the binary property to which to
write the data of the received file.', + }, { displayName: 'Response Content-Type', name: 'responseContentType', @@ -258,6 +287,13 @@ export class Webhook implements INodeType { displayName: 'Raw Body', name: 'rawBody', type: 'boolean', + displayOptions: { + hide: { + binaryData: [ + true, + ], + }, + }, default: false, description: 'Raw body (binary)', }, @@ -266,10 +302,9 @@ export class Webhook implements INodeType { ], }; - async webhook(this: IWebhookFunctions): Promise { - const authentication = this.getNodeParameter('authentication', 0) as string; - const options = this.getNodeParameter('options', 0) as IDataObject; + const authentication = this.getNodeParameter('authentication') as string; + const options = this.getNodeParameter('options', {}) as IDataObject; const req = this.getRequestObject(); const resp = this.getResponseObject(); const headers = this.getHeaderData(); @@ -347,6 +382,43 @@ export class Webhook implements INodeType { }); } + if (options.binaryData === true) { + return new Promise((resolve, reject) => { + const binaryPropertyName = options.binaryPropertyName || 'data'; + const data: Buffer[] = []; + + req.on('data', (chunk) => { + data.push(chunk); + }); + + req.on('end', async () => { + const returnItem: INodeExecutionData = { + binary: {}, + json: {}, + }; + + const returnData: IDataObject[] = [{ json: {} }]; + set(returnData[0], `binary[${binaryPropertyName}]`, { + data: Buffer.concat(data).toString(BINARY_ENCODING), + mimeType: req.headers['content-type'], + }); + returnItem.binary![binaryPropertyName as string] = await this.helpers.prepareBinaryData(Buffer.concat(data)); + + return resolve({ + workflowData: [ + [ + returnItem + ] + ], + }); + }); + + req.on('error', (err) => { + throw new Error(err.message); + }); + }); + } + const response: INodeExecutionData = { json: { body: this.getBodyData(), @@ -354,6 +426,7 @@ export class Webhook implements INodeType { query: this.getQueryData(), }, }; + if (options.rawBody) { response.binary = { data: {