2023-01-27 03:22:44 -08:00
import type { IWebhookFunctions } from 'n8n-core' ;
import { BINARY_ENCODING } from 'n8n-core' ;
2019-06-23 03:35:23 -07:00
2023-01-27 03:22:44 -08:00
import type {
2022-04-14 23:00:47 -07:00
ICredentialDataDecryptedObject ,
2019-06-23 03:35:23 -07:00
IDataObject ,
2019-12-21 17:03:24 -08:00
INodeExecutionData ,
2019-06-23 03:35:23 -07:00
INodeType ,
2020-10-01 05:01:39 -07:00
INodeTypeDescription ,
2019-10-11 04:02:44 -07:00
IWebhookResponseData ,
2019-06-23 03:35:23 -07:00
} from 'n8n-workflow' ;
2023-01-27 03:22:44 -08:00
import { NodeOperationError } from 'n8n-workflow' ;
2019-06-23 03:35:23 -07:00
2022-04-08 14:32:08 -07:00
import fs from 'fs' ;
2022-11-24 07:54:43 -08:00
import stream from 'stream' ;
import { promisify } from 'util' ;
import basicAuth from 'basic-auth' ;
import type { Response } from 'express' ;
2022-04-08 14:32:08 -07:00
import formidable from 'formidable' ;
import isbot from 'isbot' ;
2022-11-24 07:54:43 -08:00
import { file as tmpFile } from 'tmp-promise' ;
const pipeline = promisify ( stream . pipeline ) ;
2021-12-09 05:28:14 -08:00
2019-06-23 03:35:23 -07:00
function authorizationError ( resp : Response , realm : string , responseCode : number , message? : string ) {
if ( message === undefined ) {
message = 'Authorization problem!' ;
if ( responseCode === 401 ) {
message = 'Authorization is required!' ;
} else if ( responseCode === 403 ) {
message = 'Authorization data is wrong!' ;
}
}
resp . writeHead ( responseCode , { 'WWW-Authenticate' : ` Basic realm=" ${ realm } " ` } ) ;
resp . end ( message ) ;
return {
noWebhookResponse : true ,
} ;
}
export class Webhook implements INodeType {
description : INodeTypeDescription = {
displayName : 'Webhook' ,
2021-06-18 14:48:38 -07:00
icon : 'file:webhook.svg' ,
2019-06-23 03:35:23 -07:00
name : 'webhook' ,
group : [ 'trigger' ] ,
version : 1 ,
2021-07-03 05:40:16 -07:00
description : 'Starts the workflow when a webhook is called' ,
2021-11-26 03:42:08 -08:00
eventTriggerDescription : 'Waiting for you to call the Test URL' ,
2022-01-21 09:00:00 -08:00
activationMessage : 'You can now make calls to your production webhook URL.' ,
2019-06-23 03:35:23 -07:00
defaults : {
name : 'Webhook' ,
} ,
2022-06-20 12:39:24 -07:00
triggerPanel : {
header : '' ,
executionsHelp : {
2022-08-17 08:50:24 -07:00
inactive :
'Webhooks have two modes: test and production. <br /> <br /> <b>Use test mode while you build your workflow</b>. Click the \'listen\' button, then make a request to the test URL. The executions will show up in the editor.<br /> <br /> <b>Use production mode to run your workflow automatically</b>. <a data-key="activate">Activate</a> the workflow, then make requests to the production URL. These executions will show up in the executions list, but not in the editor.' ,
active :
'Webhooks have two modes: test and production. <br /> <br /> <b>Use test mode while you build your workflow</b>. Click the \'listen\' button, then make a request to the test URL. The executions will show up in the editor.<br /> <br /> <b>Use production mode to run your workflow automatically</b>. Since the workflow is activated, you can make requests to the production URL. These executions will show up in the <a data-key="executions">executions list</a>, but not in the editor.' ,
2022-06-20 12:39:24 -07:00
} ,
2022-08-17 08:50:24 -07:00
activationHint :
'Once you’ ve finished building your workflow, run it without having to click this button by using the production webhook URL.' ,
2022-06-20 12:39:24 -07:00
} ,
2022-04-22 09:29:51 -07:00
// eslint-disable-next-line n8n-nodes-base/node-class-description-inputs-wrong-regular-node
2019-06-23 03:35:23 -07:00
inputs : [ ] ,
outputs : [ 'main' ] ,
credentials : [
{
name : 'httpBasicAuth' ,
required : true ,
displayOptions : {
show : {
2022-08-17 08:50:24 -07:00
authentication : [ 'basicAuth' ] ,
2019-06-23 03:35:23 -07:00
} ,
} ,
} ,
{
name : 'httpHeaderAuth' ,
required : true ,
displayOptions : {
show : {
2022-08-17 08:50:24 -07:00
authentication : [ 'headerAuth' ] ,
2019-06-23 03:35:23 -07:00
} ,
} ,
} ,
] ,
webhooks : [
{
name : 'default' ,
httpMethod : '={{$parameter["httpMethod"]}}' ,
2020-06-10 06:39:15 -07:00
isFullPath : true ,
2019-08-28 08:03:35 -07:00
responseCode : '={{$parameter["responseCode"]}}' ,
2019-08-28 08:16:09 -07:00
responseMode : '={{$parameter["responseMode"]}}' ,
2022-08-17 08:50:24 -07:00
responseData :
'={{$parameter["responseData"] || ($parameter.options.noResponseBody ? "noData" : undefined) }}' ,
2019-06-23 03:35:23 -07:00
responseBinaryPropertyName : '={{$parameter["responseBinaryPropertyName"]}}' ,
2019-10-16 05:01:39 -07:00
responseContentType : '={{$parameter["options"]["responseContentType"]}}' ,
responsePropertyName : '={{$parameter["options"]["responsePropertyName"]}}' ,
2020-04-26 02:01:20 -07:00
responseHeaders : '={{$parameter["options"]["responseHeaders"]}}' ,
2019-06-23 03:35:23 -07:00
path : '={{$parameter["path"]}}' ,
} ,
] ,
properties : [
{
displayName : 'Authentication' ,
name : 'authentication' ,
type : 'options' ,
options : [
{
name : 'Basic Auth' ,
2020-10-22 06:46:03 -07:00
value : 'basicAuth' ,
2019-06-23 03:35:23 -07:00
} ,
{
name : 'Header Auth' ,
2020-10-22 06:46:03 -07:00
value : 'headerAuth' ,
2019-06-23 03:35:23 -07:00
} ,
{
name : 'None' ,
2020-10-22 06:46:03 -07:00
value : 'none' ,
2019-06-23 03:35:23 -07:00
} ,
] ,
default : 'none' ,
2022-05-06 14:01:25 -07:00
description : 'The way to authenticate' ,
2019-06-23 03:35:23 -07:00
} ,
{
displayName : 'HTTP Method' ,
name : 'httpMethod' ,
type : 'options' ,
options : [
2022-02-20 01:30:01 -08:00
{
name : 'DELETE' ,
value : 'DELETE' ,
} ,
2019-06-23 03:35:23 -07:00
{
name : 'GET' ,
value : 'GET' ,
} ,
2020-12-30 02:00:06 -08:00
{
name : 'HEAD' ,
value : 'HEAD' ,
} ,
2022-02-20 01:30:01 -08:00
{
name : 'PATCH' ,
value : 'PATCH' ,
} ,
2019-06-23 03:35:23 -07:00
{
name : 'POST' ,
value : 'POST' ,
} ,
2022-02-20 01:30:01 -08:00
{
name : 'PUT' ,
value : 'PUT' ,
} ,
2019-06-23 03:35:23 -07:00
] ,
default : 'GET' ,
2022-05-06 14:01:25 -07:00
description : 'The HTTP method to listen to' ,
2019-06-23 03:35:23 -07:00
} ,
{
displayName : 'Path' ,
name : 'path' ,
type : 'string' ,
default : '' ,
2019-08-28 08:03:35 -07:00
placeholder : 'webhook' ,
2019-06-23 03:35:23 -07:00
required : true ,
2022-05-06 14:01:25 -07:00
description : 'The path to listen to' ,
2019-06-23 03:35:23 -07:00
} ,
2019-08-28 08:03:35 -07:00
{
2021-11-05 09:45:51 -07:00
displayName : 'Respond' ,
2019-08-28 08:16:09 -07:00
name : 'responseMode' ,
2019-06-23 03:35:23 -07:00
type : 'options' ,
options : [
{
2021-11-05 09:45:51 -07:00
name : 'Immediately' ,
2019-06-23 03:35:23 -07:00
value : 'onReceived' ,
2021-11-05 09:45:51 -07:00
description : 'As soon as this node executes' ,
2019-06-23 03:35:23 -07:00
} ,
{
2022-06-03 10:23:49 -07:00
name : 'When Last Node Finishes' ,
2019-06-23 03:35:23 -07:00
value : 'lastNode' ,
2021-11-05 09:45:51 -07:00
description : 'Returns data of the last-executed node' ,
} ,
{
2022-08-17 08:50:24 -07:00
name : "Using 'Respond to Webhook' Node" ,
2021-11-05 09:45:51 -07:00
value : 'responseNode' ,
description : 'Response defined in that node' ,
2019-06-23 03:35:23 -07:00
} ,
] ,
default : 'onReceived' ,
2022-05-06 14:01:25 -07:00
description : 'When and how to respond to the webhook' ,
2019-06-23 03:35:23 -07:00
} ,
2021-11-05 09:45:51 -07:00
{
2022-08-17 08:50:24 -07:00
displayName :
2022-09-29 03:33:16 -07:00
'Insert a \'Respond to Webhook\' node to control when and how you respond. <a href="https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.respondtowebhook/" target="_blank">More details</a>' ,
2021-11-05 09:45:51 -07:00
name : 'webhookNotice' ,
type : 'notice' ,
displayOptions : {
show : {
2022-08-17 08:50:24 -07:00
responseMode : [ 'responseNode' ] ,
2021-11-05 09:45:51 -07:00
} ,
} ,
default : '' ,
} ,
{
displayName : 'Response Code' ,
name : 'responseCode' ,
type : 'number' ,
displayOptions : {
hide : {
2022-08-17 08:50:24 -07:00
responseMode : [ 'responseNode' ] ,
2021-11-05 09:45:51 -07:00
} ,
} ,
typeOptions : {
minValue : 100 ,
maxValue : 599 ,
} ,
default : 200 ,
description : 'The HTTP Response code to return' ,
} ,
2019-06-23 03:35:23 -07:00
{
2019-08-28 08:16:09 -07:00
displayName : 'Response Data' ,
name : 'responseData' ,
2019-06-23 03:35:23 -07:00
type : 'options' ,
displayOptions : {
show : {
2022-08-17 08:50:24 -07:00
responseMode : [ 'lastNode' ] ,
2019-06-23 03:35:23 -07:00
} ,
} ,
options : [
{
name : 'All Entries' ,
value : 'allEntries' ,
description : 'Returns all the entries of the last node. Always returns an array.' ,
} ,
{
name : 'First Entry JSON' ,
value : 'firstEntryJson' ,
2022-08-17 08:50:24 -07:00
description :
'Returns the JSON data of the first entry of the last node. Always returns a JSON object.' ,
2019-06-23 03:35:23 -07:00
} ,
{
name : 'First Entry Binary' ,
value : 'firstEntryBinary' ,
2022-08-17 08:50:24 -07:00
description :
'Returns the binary data of the first entry of the last node. Always returns a binary file.' ,
2019-06-23 03:35:23 -07:00
} ,
2022-02-19 03:37:41 -08:00
{
name : 'No Response Body' ,
value : 'noData' ,
2022-05-06 14:01:25 -07:00
description : 'Returns without a body' ,
2022-02-19 03:37:41 -08:00
} ,
2019-06-23 03:35:23 -07:00
] ,
default : 'firstEntryJson' ,
2022-08-17 08:50:24 -07:00
description :
'What data should be returned. If it should return all items as an array or only the first item as object.' ,
2019-06-23 03:35:23 -07:00
} ,
{
displayName : 'Property Name' ,
name : 'responseBinaryPropertyName' ,
type : 'string' ,
required : true ,
default : 'data' ,
displayOptions : {
show : {
2022-08-17 08:50:24 -07:00
responseData : [ 'firstEntryBinary' ] ,
2019-06-23 03:35:23 -07:00
} ,
} ,
description : 'Name of the binary property to return' ,
} ,
2019-10-16 05:01:39 -07:00
{
displayName : 'Options' ,
name : 'options' ,
type : 'collection' ,
placeholder : 'Add Option' ,
default : { } ,
options : [
2020-03-21 15:39:40 -07:00
{
displayName : 'Binary Data' ,
name : 'binaryData' ,
type : 'boolean' ,
displayOptions : {
show : {
2022-08-17 08:50:24 -07:00
'/httpMethod' : [ 'PATCH' , 'PUT' , 'POST' ] ,
2020-03-21 15:39:40 -07:00
} ,
} ,
default : false ,
2022-06-20 07:54:01 -07:00
description : 'Whether the webhook will receive binary data' ,
2020-03-21 15:39:40 -07:00
} ,
{
displayName : 'Binary Property' ,
name : 'binaryPropertyName' ,
type : 'string' ,
default : 'data' ,
required : true ,
displayOptions : {
show : {
2022-08-17 08:50:24 -07:00
binaryData : [ true ] ,
2020-03-21 15:39:40 -07:00
} ,
} ,
2022-08-17 08:50:24 -07:00
description :
'Name of the binary property to write the data of the received file to. If the data gets received via "Form-Data Multipart" it will be the prefix and a number starting with 0 will be attached to it.' ,
2020-03-21 15:39:40 -07:00
} ,
2022-01-02 01:20:12 -08:00
{
displayName : 'Ignore Bots' ,
name : 'ignoreBots' ,
type : 'boolean' ,
default : false ,
2022-08-17 08:50:24 -07:00
description :
'Whether to ignore requests from bots like link previewers and web crawlers' ,
2022-01-02 01:20:12 -08:00
} ,
2022-02-19 03:37:41 -08:00
{
displayName : 'No Response Body' ,
name : 'noResponseBody' ,
type : 'boolean' ,
default : false ,
2022-06-20 07:54:01 -07:00
description : 'Whether to send any body in the response' ,
2022-02-19 03:37:41 -08:00
displayOptions : {
hide : {
2022-08-17 08:50:24 -07:00
rawBody : [ true ] ,
2022-02-19 03:37:41 -08:00
} ,
show : {
2022-08-17 08:50:24 -07:00
'/responseMode' : [ 'onReceived' ] ,
2022-02-19 03:37:41 -08:00
} ,
} ,
} ,
{
displayName : 'Raw Body' ,
name : 'rawBody' ,
type : 'boolean' ,
displayOptions : {
hide : {
2022-08-17 08:50:24 -07:00
binaryData : [ true ] ,
noResponseBody : [ true ] ,
2022-02-19 03:37:41 -08:00
} ,
} ,
default : false ,
2022-06-20 07:54:01 -07:00
// eslint-disable-next-line n8n-nodes-base/node-param-description-boolean-without-whether
2022-02-19 03:37:41 -08:00
description : 'Raw body (binary)' ,
} ,
2020-12-14 08:19:20 -08:00
{
displayName : 'Response Data' ,
name : 'responseData' ,
type : 'string' ,
displayOptions : {
show : {
2022-08-17 08:50:24 -07:00
'/responseMode' : [ 'onReceived' ] ,
2020-12-14 08:19:20 -08:00
} ,
2022-02-19 03:37:41 -08:00
hide : {
2022-08-17 08:50:24 -07:00
noResponseBody : [ true ] ,
2022-02-19 03:37:41 -08:00
} ,
2020-12-14 08:19:20 -08:00
} ,
default : '' ,
placeholder : 'success' ,
2022-05-06 14:01:25 -07:00
description : 'Custom response data to send' ,
2020-12-14 08:19:20 -08:00
} ,
2019-10-16 05:01:39 -07:00
{
displayName : 'Response Content-Type' ,
name : 'responseContentType' ,
type : 'string' ,
2019-12-21 17:03:24 -08:00
displayOptions : {
show : {
2022-08-17 08:50:24 -07:00
'/responseData' : [ 'firstEntryJson' ] ,
'/responseMode' : [ 'lastNode' ] ,
2019-12-21 17:03:24 -08:00
} ,
} ,
2019-10-16 05:01:39 -07:00
default : '' ,
placeholder : 'application/xml' ,
2022-05-20 14:47:24 -07:00
// eslint-disable-next-line n8n-nodes-base/node-param-description-miscased-json
2022-08-17 08:50:24 -07:00
description :
'Set a custom content-type to return if another one as the "application/json" should be returned' ,
2019-10-16 05:01:39 -07:00
} ,
2020-04-26 02:01:20 -07:00
{
displayName : 'Response Headers' ,
name : 'responseHeaders' ,
placeholder : 'Add Response Header' ,
2022-05-06 14:01:25 -07:00
description : 'Add headers to the webhook response' ,
2020-04-26 02:01:20 -07:00
type : 'fixedCollection' ,
typeOptions : {
multipleValues : true ,
} ,
default : { } ,
options : [
{
name : 'entries' ,
displayName : 'Entries' ,
values : [
{
displayName : 'Name' ,
name : 'name' ,
type : 'string' ,
default : '' ,
2022-05-06 14:01:25 -07:00
description : 'Name of the header' ,
2020-04-26 02:01:20 -07:00
} ,
{
displayName : 'Value' ,
name : 'value' ,
type : 'string' ,
default : '' ,
2022-05-06 14:01:25 -07:00
description : 'Value of the header' ,
2020-04-26 02:01:20 -07:00
} ,
2020-10-22 06:46:03 -07:00
] ,
2020-04-26 02:01:20 -07:00
} ,
] ,
} ,
2019-10-16 05:01:39 -07:00
{
displayName : 'Property Name' ,
name : 'responsePropertyName' ,
type : 'string' ,
2019-12-21 17:03:24 -08:00
displayOptions : {
show : {
2022-08-17 08:50:24 -07:00
'/responseData' : [ 'firstEntryJson' ] ,
'/responseMode' : [ 'lastNode' ] ,
2019-12-21 17:03:24 -08:00
} ,
} ,
2019-10-16 05:01:39 -07:00
default : 'data' ,
2022-05-06 14:01:25 -07:00
description : 'Name of the property to return the data of instead of the whole JSON' ,
2019-10-16 05:01:39 -07:00
} ,
2019-12-21 12:36:08 -08:00
] ,
} ,
2019-06-23 03:35:23 -07:00
] ,
} ;
2019-10-11 04:02:44 -07:00
async webhook ( this : IWebhookFunctions ) : Promise < IWebhookResponseData > {
2020-03-21 15:39:40 -07:00
const authentication = this . getNodeParameter ( 'authentication' ) as string ;
const options = this . getNodeParameter ( 'options' , { } ) as IDataObject ;
2019-06-23 03:35:23 -07:00
const req = this . getRequestObject ( ) ;
const resp = this . getResponseObject ( ) ;
const headers = this . getHeaderData ( ) ;
const realm = 'Webhook' ;
2021-12-09 05:28:14 -08:00
const ignoreBots = options . ignoreBots as boolean ;
if ( ignoreBots && isbot ( ( headers as IDataObject ) [ 'user-agent' ] as string ) ) {
return authorizationError ( resp , realm , 403 ) ;
}
2019-06-23 03:35:23 -07:00
if ( authentication === 'basicAuth' ) {
// Basic authorization is needed to call webhook
2022-04-14 23:00:47 -07:00
let httpBasicAuth : ICredentialDataDecryptedObject | undefined ;
try {
httpBasicAuth = await this . getCredentials ( 'httpBasicAuth' ) ;
} catch ( error ) {
// Do nothing
}
2019-06-23 03:35:23 -07:00
if ( httpBasicAuth === undefined || ! httpBasicAuth . user || ! httpBasicAuth . password ) {
// Data is not defined on node so can not authenticate
return authorizationError ( resp , realm , 500 , 'No authentication data defined on node!' ) ;
}
const basicAuthData = basicAuth ( req ) ;
if ( basicAuthData === undefined ) {
// Authorization data is missing
return authorizationError ( resp , realm , 401 ) ;
}
2022-08-17 08:50:24 -07:00
if (
2022-12-02 12:54:28 -08:00
basicAuthData . name !== httpBasicAuth . user ||
basicAuthData . pass !== httpBasicAuth . password
2022-08-17 08:50:24 -07:00
) {
2019-06-23 03:35:23 -07:00
// Provided authentication data is wrong
return authorizationError ( resp , realm , 403 ) ;
}
} else if ( authentication === 'headerAuth' ) {
// Special header with value is needed to call webhook
2022-04-14 23:00:47 -07:00
let httpHeaderAuth : ICredentialDataDecryptedObject | undefined ;
try {
httpHeaderAuth = await this . getCredentials ( 'httpHeaderAuth' ) ;
} catch ( error ) {
// Do nothing
}
2019-06-23 03:35:23 -07:00
if ( httpHeaderAuth === undefined || ! httpHeaderAuth . name || ! httpHeaderAuth . value ) {
// Data is not defined on node so can not authenticate
return authorizationError ( resp , realm , 500 , 'No authentication data defined on node!' ) ;
}
const headerName = ( httpHeaderAuth . name as string ) . toLowerCase ( ) ;
2022-08-17 08:50:24 -07:00
const headerValue = httpHeaderAuth . value as string ;
2019-06-23 03:35:23 -07:00
2022-08-17 08:50:24 -07:00
if (
! headers . hasOwnProperty ( headerName ) ||
( headers as IDataObject ) [ headerName ] !== headerValue
) {
2019-06-23 03:35:23 -07:00
// Provided authentication data is wrong
return authorizationError ( resp , realm , 403 ) ;
}
}
2019-12-21 17:03:24 -08:00
2022-11-24 07:54:43 -08:00
const mimeType = headers [ 'content-type' ] ? ? 'application/json' ;
2020-02-06 08:21:25 -08:00
if ( mimeType . includes ( 'multipart/form-data' ) ) {
2021-08-29 11:56:19 -07:00
const form = new formidable . IncomingForm ( { multiples : true } ) ;
2020-02-06 08:21:25 -08:00
2022-11-08 06:28:21 -08:00
return new Promise ( ( resolve , _reject ) = > {
2020-02-06 08:21:25 -08:00
form . parse ( req , async ( err , data , files ) = > {
2020-03-30 05:53:42 -07:00
const returnItem : INodeExecutionData = {
binary : { } ,
json : {
headers ,
2021-01-23 11:00:32 -08:00
params : this.getParamsData ( ) ,
2020-03-30 05:53:42 -07:00
query : this.getQueryData ( ) ,
2021-01-23 11:00:32 -08:00
body : data ,
2020-03-30 05:53:42 -07:00
} ,
} ;
let count = 0 ;
2021-08-29 11:56:19 -07:00
for ( const xfile of Object . keys ( files ) ) {
2021-08-29 14:08:56 -07:00
const processFiles : formidable.File [ ] = [ ] ;
2021-08-29 11:56:19 -07:00
let multiFile = false ;
if ( Array . isArray ( files [ xfile ] ) ) {
2022-08-17 08:50:24 -07:00
processFiles . push ( . . . ( files [ xfile ] as formidable . File [ ] ) ) ;
2021-08-29 11:56:19 -07:00
multiFile = true ;
} else {
2021-08-29 14:08:56 -07:00
processFiles . push ( files [ xfile ] as formidable . File ) ;
2020-03-30 05:53:42 -07:00
}
2021-08-29 11:56:19 -07:00
let fileCount = 0 ;
2021-08-29 14:08:56 -07:00
for ( const file of processFiles ) {
2021-08-29 11:56:19 -07:00
let binaryPropertyName = xfile ;
if ( binaryPropertyName . endsWith ( '[]' ) ) {
binaryPropertyName = binaryPropertyName . slice ( 0 , - 2 ) ;
}
2022-12-02 12:54:28 -08:00
if ( multiFile ) {
2021-08-29 11:56:19 -07:00
binaryPropertyName += fileCount ++ ;
}
if ( options . binaryPropertyName ) {
binaryPropertyName = ` ${ options . binaryPropertyName } ${ count } ` ;
}
2022-11-24 07:54:43 -08:00
const fileJson = file . toJSON ( ) ;
returnItem . binary ! [ binaryPropertyName ] = await this . helpers . copyBinaryFile (
file . path ,
2023-01-19 04:37:19 -08:00
fileJson . name || fileJson . filename ,
2022-08-17 08:50:24 -07:00
fileJson . type as string ,
) ;
2020-03-30 05:53:42 -07:00
2021-08-29 11:56:19 -07:00
count += 1 ;
}
2020-02-06 08:21:25 -08:00
}
resolve ( {
2022-08-17 08:50:24 -07:00
workflowData : [ [ returnItem ] ] ,
2020-02-06 08:21:25 -08:00
} ) ;
} ) ;
} ) ;
}
2019-12-21 17:03:24 -08:00
2020-03-21 15:39:40 -07:00
if ( options . binaryData === true ) {
2022-11-24 07:54:43 -08:00
const binaryFile = await tmpFile ( { prefix : 'n8n-webhook-' } ) ;
2020-03-21 15:39:40 -07:00
2022-11-24 07:54:43 -08:00
try {
await pipeline ( req , fs . createWriteStream ( binaryFile . path ) ) ;
const returnItem : INodeExecutionData = {
binary : { } ,
json : {
headers ,
params : this.getParamsData ( ) ,
query : this.getQueryData ( ) ,
body : this.getBodyData ( ) ,
} ,
} ;
2020-03-21 15:39:40 -07:00
2023-01-19 04:37:19 -08:00
const binaryPropertyName = ( options . binaryPropertyName || 'data' ) as string ;
2022-11-24 07:54:43 -08:00
returnItem . binary ! [ binaryPropertyName ] = await this . helpers . copyBinaryFile (
binaryFile . path ,
mimeType ,
) ;
2020-03-20 11:53:51 -07:00
2022-11-24 07:54:43 -08:00
return {
workflowData : [ [ returnItem ] ] ,
} ;
} catch ( error ) {
throw new NodeOperationError ( this . getNode ( ) , error ) ;
} finally {
await binaryFile . cleanup ( ) ;
}
2020-03-20 11:53:51 -07:00
}
2019-12-21 17:03:24 -08:00
const response : INodeExecutionData = {
2019-12-21 12:36:08 -08:00
json : {
2019-06-23 03:35:23 -07:00
headers ,
2021-01-23 11:00:32 -08:00
params : this.getParamsData ( ) ,
2019-06-23 03:35:23 -07:00
query : this.getQueryData ( ) ,
2021-01-23 11:00:32 -08:00
body : this.getBodyData ( ) ,
2019-12-21 12:36:08 -08:00
} ,
} ;
if ( options . rawBody ) {
response . binary = {
2019-12-21 17:03:24 -08:00
data : {
2020-03-20 14:47:47 -07:00
data : req.rawBody.toString ( BINARY_ENCODING ) ,
2019-12-21 17:03:24 -08:00
mimeType ,
2020-10-22 06:46:03 -07:00
} ,
2019-12-21 12:36:08 -08:00
} ;
}
2020-12-14 08:19:20 -08:00
let webhookResponse : string | undefined ;
if ( options . responseData ) {
webhookResponse = options . responseData as string ;
}
2019-06-23 03:35:23 -07:00
return {
2020-12-14 08:19:20 -08:00
webhookResponse ,
2022-08-17 08:50:24 -07:00
workflowData : [ [ response ] ] ,
2019-06-23 03:35:23 -07:00
} ;
}
}