mirror of
https://github.com/n8n-io/n8n.git
synced 2024-11-14 08:34:07 -08:00
70ae90fa3c
* ⚡ Update `lintfix` script * 👕 Remove unneeded lint exceptions * 👕 Run baseline `lintfix` * 👕 Apply `node-param-description-miscased-url` (#3441) * 👕 Apply `rule node-param-placeholder-miscased-id` (#3443) Co-authored-by: Iván Ovejero <ivov.src@gmail.com> * 👕 Apply `node-param-option-name-wrong-for-upsert` (#3446) * 👕 Apply `node-param-min-value-wrong-for-limit` (#3442) Co-authored-by: Iván Ovejero <ivov.src@gmail.com> * Apply `node-param-display-name-wrong-for-dynamic-options` (#3454) * 🔨 fix * ⚡ Fix `Assigned To` fields Co-authored-by: Michael Kret <michael.k@radency.com> * 👕 Apply `rule node-param-default-wrong-for-number` (#3453) * 👕 Apply `node-param-default-wrong-for-string` (#3452) Co-authored-by: Iván Ovejero <ivov.src@gmail.com> * Apply `node-param-display-name-miscased` (#3449) * 🔨 fix * 🔨 exceptions * ⚡ review fixes * 👕 Apply `node-param-description-lowercase-first-char` (#3451) * ⚡ fix * ⚡ review fixes * ⚡ fix Co-authored-by: Iván Ovejero <ivov.src@gmail.com> * 👕 Apply `node-param-description-wrong-for-dynamic-options` (#3456) * Rule working as intended * Add rule * 🔥 Remove repetitions * 👕 Add exceptions Co-authored-by: Iván Ovejero <ivov.src@gmail.com> * 👕 Small fix for `node-param-description-wrong-for-dynamic-options` * 👕 Apply `node-param-default-wrong-for-fixed-collection` (#3460) * 👕 Apply `node-param-description-line-break-html-tag` (#3462) * 👕 Run baseline `lintfix` * 👕 Apply `node-param-options-type-unsorted-items` (#3459) * ⚡ fix * 🔨 exceptions * Add exception for Salesmate and Zoom Co-authored-by: Michael Kret <michael.k@radency.com> Co-authored-by: Iván Ovejero <ivov.src@gmail.com> * ⚡ Restore `lintfix` command Co-authored-by: Omar Ajoue <krynble@gmail.com> Co-authored-by: Michael Kret <88898367+michael-radency@users.noreply.github.com> Co-authored-by: agobrech <45268029+agobrech@users.noreply.github.com> Co-authored-by: Michael Kret <michael.k@radency.com> Co-authored-by: brianinoa <54530642+brianinoa@users.noreply.github.com>
278 lines
6.6 KiB
TypeScript
278 lines
6.6 KiB
TypeScript
import {
|
|
IExecuteFunctions,
|
|
} from 'n8n-core';
|
|
|
|
import {
|
|
IDataObject,
|
|
IN8nHttpFullResponse,
|
|
IN8nHttpResponse,
|
|
INodeExecutionData,
|
|
INodeType,
|
|
INodeTypeDescription,
|
|
NodeOperationError,
|
|
} from 'n8n-workflow';
|
|
|
|
export class RespondToWebhook implements INodeType {
|
|
description: INodeTypeDescription = {
|
|
displayName: 'Respond to Webhook',
|
|
icon: 'file:webhook.svg',
|
|
name: 'respondToWebhook',
|
|
group: ['transform'],
|
|
version: 1,
|
|
description: 'Returns data for Webhook',
|
|
defaults: {
|
|
name: 'Respond to Webhook',
|
|
},
|
|
inputs: ['main'],
|
|
outputs: ['main'],
|
|
credentials: [
|
|
],
|
|
properties: [
|
|
{
|
|
displayName: 'Respond With',
|
|
name: 'respondWith',
|
|
type: 'options',
|
|
options: [
|
|
{
|
|
name: 'Binary',
|
|
value: 'binary',
|
|
},
|
|
{
|
|
name: 'First Incoming Item',
|
|
value: 'firstIncomingItem',
|
|
},
|
|
{
|
|
name: 'JSON',
|
|
value: 'json',
|
|
},
|
|
{
|
|
name: 'No Data',
|
|
value: 'noData',
|
|
},
|
|
{
|
|
name: 'Text',
|
|
value: 'text',
|
|
},
|
|
],
|
|
default: 'firstIncomingItem',
|
|
description: 'The data that should be returned',
|
|
},
|
|
{
|
|
displayName: 'When using expressions, note that this node will only run for the first item in the input data.',
|
|
name: 'webhookNotice',
|
|
type: 'notice',
|
|
displayOptions: {
|
|
show: {
|
|
respondWith: [
|
|
'json',
|
|
'text',
|
|
],
|
|
},
|
|
},
|
|
default: '',
|
|
},
|
|
{
|
|
displayName: 'Response Body',
|
|
name: 'responseBody',
|
|
type: 'json',
|
|
displayOptions: {
|
|
show: {
|
|
respondWith: [
|
|
'json',
|
|
],
|
|
},
|
|
},
|
|
default: '',
|
|
placeholder: '{ "key": "value" }',
|
|
description: 'The HTTP Response JSON data',
|
|
},
|
|
{
|
|
displayName: 'Response Body',
|
|
name: 'responseBody',
|
|
type: 'string',
|
|
displayOptions: {
|
|
show: {
|
|
respondWith: [
|
|
'text',
|
|
],
|
|
},
|
|
},
|
|
default: '',
|
|
placeholder: 'e.g. Workflow started',
|
|
description: 'The HTTP Response text data',
|
|
},
|
|
{
|
|
displayName: 'Response Data Source',
|
|
name: 'responseDataSource',
|
|
type: 'options',
|
|
displayOptions: {
|
|
show: {
|
|
respondWith: [
|
|
'binary',
|
|
],
|
|
},
|
|
},
|
|
options: [
|
|
{
|
|
name: 'Choose Automatically From Input',
|
|
value: 'automatically',
|
|
description: 'Use if input data will contain a single piece of binary data',
|
|
},
|
|
{
|
|
name: 'Specify Myself',
|
|
value: 'set',
|
|
description: 'Enter the name of the input field the binary data will be in',
|
|
},
|
|
],
|
|
default: 'automatically',
|
|
},
|
|
{
|
|
displayName: 'Input Field Name',
|
|
name: 'inputFieldName',
|
|
type: 'string',
|
|
required: true,
|
|
default: 'data',
|
|
displayOptions: {
|
|
show: {
|
|
respondWith: [
|
|
'binary',
|
|
],
|
|
responseDataSource: [
|
|
'set',
|
|
],
|
|
},
|
|
},
|
|
description: 'The name of the node input field with the binary data',
|
|
},
|
|
|
|
{
|
|
displayName: 'Options',
|
|
name: 'options',
|
|
type: 'collection',
|
|
placeholder: 'Add Option',
|
|
default: {},
|
|
options: [
|
|
{
|
|
displayName: 'Response Code',
|
|
name: 'responseCode',
|
|
type: 'number',
|
|
typeOptions: {
|
|
minValue: 100,
|
|
maxValue: 599,
|
|
},
|
|
default: 200,
|
|
description: 'The HTTP Response code to return. Defaults to 200.',
|
|
},
|
|
{
|
|
displayName: 'Response Headers',
|
|
name: 'responseHeaders',
|
|
placeholder: 'Add Response Header',
|
|
description: 'Add headers to the webhook response',
|
|
type: 'fixedCollection',
|
|
typeOptions: {
|
|
multipleValues: true,
|
|
},
|
|
default: {},
|
|
options: [
|
|
{
|
|
name: 'entries',
|
|
displayName: 'Entries',
|
|
values: [
|
|
{
|
|
displayName: 'Name',
|
|
name: 'name',
|
|
type: 'string',
|
|
default: '',
|
|
description: 'Name of the header',
|
|
},
|
|
{
|
|
displayName: 'Value',
|
|
name: 'value',
|
|
type: 'string',
|
|
default: '',
|
|
description: 'Value of the header',
|
|
},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
],
|
|
};
|
|
|
|
async execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {
|
|
const items = this.getInputData();
|
|
|
|
const respondWith = this.getNodeParameter('respondWith', 0) as string;
|
|
const options = this.getNodeParameter('options', 0, {}) as IDataObject;
|
|
|
|
const headers = {} as IDataObject;
|
|
if (options.responseHeaders) {
|
|
for (const header of (options.responseHeaders as IDataObject).entries as IDataObject[]) {
|
|
if (typeof header.name !== 'string') {
|
|
header.name = header.name?.toString();
|
|
}
|
|
headers[header.name?.toLowerCase() as string] = header.value?.toString();
|
|
}
|
|
}
|
|
|
|
let responseBody: IN8nHttpResponse;
|
|
if (respondWith === 'json') {
|
|
const responseBodyParameter = this.getNodeParameter('responseBody', 0) as string;
|
|
if (responseBodyParameter) {
|
|
responseBody = JSON.parse(responseBodyParameter);
|
|
}
|
|
} else if (respondWith === 'firstIncomingItem') {
|
|
responseBody = items[0].json;
|
|
} else if (respondWith === 'text') {
|
|
responseBody = this.getNodeParameter('responseBody', 0) as string;
|
|
} else if (respondWith === 'binary') {
|
|
const item = this.getInputData()[0];
|
|
|
|
if (item.binary === undefined) {
|
|
throw new NodeOperationError(this.getNode(), 'No binary data exists on the first item!');
|
|
}
|
|
|
|
let responseBinaryPropertyName: string;
|
|
|
|
const responseDataSource = this.getNodeParameter('responseDataSource', 0) as string;
|
|
|
|
if (responseDataSource === 'set') {
|
|
responseBinaryPropertyName = this.getNodeParameter('inputFieldName', 0) as string;
|
|
} else {
|
|
const binaryKeys = Object.keys(item.binary);
|
|
if (binaryKeys.length === 0) {
|
|
throw new NodeOperationError(this.getNode(), 'No binary data exists on the first item!');
|
|
}
|
|
responseBinaryPropertyName = binaryKeys[0];
|
|
}
|
|
|
|
const binaryData = item.binary[responseBinaryPropertyName];
|
|
const binaryDataBuffer = await this.helpers.getBinaryDataBuffer(0, responseBinaryPropertyName);
|
|
|
|
if (binaryData === undefined) {
|
|
throw new NodeOperationError(this.getNode(), `No binary data property "${responseBinaryPropertyName}" does not exists on item!`);
|
|
}
|
|
|
|
if (headers['content-type']) {
|
|
headers['content-type'] = binaryData.mimeType;
|
|
}
|
|
responseBody = binaryDataBuffer;
|
|
} else if (respondWith !== 'noData') {
|
|
throw new NodeOperationError(this.getNode(), `The Response Data option "${respondWith}" is not supported!`);
|
|
}
|
|
|
|
const response: IN8nHttpFullResponse = {
|
|
body: responseBody,
|
|
headers,
|
|
statusCode: options.responseCode as number || 200,
|
|
};
|
|
|
|
this.sendResponse(response);
|
|
|
|
return this.prepareOutputData(items);
|
|
}
|
|
|
|
}
|