This commit is contained in:
Dana Lee 2025-01-29 15:07:49 +01:00
parent 09409ad9f0
commit 69e4d5d853
No known key found for this signature in database
4 changed files with 140 additions and 46 deletions

View file

@ -26,6 +26,9 @@
</head>
<body>
{{#if responseText}}
{{responseText}}
{{else}}
<div class='container'>
<section>
<div class='card'>
@ -69,6 +72,7 @@
{{/if}}
</section>
</div>
{{/if}}
<script>
fetch('', { method: 'POST', body: {}, }).catch(() => {});
</script>

View file

@ -115,6 +115,16 @@ const completionProperties = updateDisplayOptions(
value: 'redirect',
description: 'Redirect the user to a URL',
},
{
name: 'Show Text',
value: 'showText',
description: 'Display simple text or HTML',
},
{
name: 'Return Binary File',
value: 'returnBinary',
description: 'Return incoming binary file',
},
],
},
{
@ -138,7 +148,7 @@ const completionProperties = updateDisplayOptions(
required: true,
displayOptions: {
show: {
respondWith: ['text'],
respondWith: ['text', 'returnBinary'],
},
},
},
@ -152,10 +162,41 @@ const completionProperties = updateDisplayOptions(
},
displayOptions: {
show: {
respondWith: ['text'],
respondWith: ['text', 'returnBinary'],
},
},
},
{
displayName: 'Text',
name: 'responseText',
type: 'string',
displayOptions: {
show: {
respondWith: ['showText'],
},
},
typeOptions: {
rows: 2,
},
default: '',
placeholder: 'e.g. Thanks for filling the form',
description: 'The text to display on the page. Use HTML to show a customized web page.',
},
{
displayName: 'Input Data Field Name',
name: 'inputDataFieldName',
type: 'string',
displayOptions: {
show: {
respondWith: ['returnBinary'],
},
},
default: 'data',
placeholder: 'e.g. data',
description:
'Find the name of input field containing the binary data to return in the Input panel on the left, in the Binary tab',
hint: 'The name of the input field containing the binary file data to be returned',
},
{
displayName: 'Options',
name: 'options',
@ -165,7 +206,7 @@ const completionProperties = updateDisplayOptions(
options: [{ ...formTitle, required: false, displayName: 'Completion Page Title' }],
displayOptions: {
show: {
respondWith: ['text'],
respondWith: ['text', 'returnBinary'],
},
},
},

View file

@ -3,7 +3,49 @@ import {
type NodeTypeAndVersion,
type IWebhookFunctions,
type IWebhookResponseData,
type IN8nHttpResponse,
type IDataObject,
ApplicationError,
type IBinaryData,
BINARY_ENCODING,
} from 'n8n-workflow';
import { type Readable } from 'node:stream';
import { sanitizeHtml } from './utils';
const getBinaryDataFromNode = (context: IWebhookFunctions, nodeName: string): IDataObject => {
return context.evaluateExpression(`{{ $('${nodeName}').first().binary }}`) as IDataObject;
};
const respondWithBinary = (context: IWebhookFunctions, res: Response) => {
const inputDataFieldName = context.getNodeParameter('inputDataFieldName', '') as string;
const parentNodes = context.getParentNodes(context.getNode().name);
const binaryNode = parentNodes.find((node) =>
getBinaryDataFromNode(context, node?.name)?.hasOwnProperty(inputDataFieldName),
);
if (!binaryNode) {
throw new ApplicationError('No binary data found.');
}
const binaryData = getBinaryDataFromNode(context, binaryNode?.name)[
inputDataFieldName
] as IBinaryData;
let responseBody: IN8nHttpResponse | Readable;
if (binaryData.id) {
responseBody = { binaryData };
} else {
responseBody = Buffer.from(binaryData.data, BINARY_ENCODING);
}
// res.setHeader('Content-Type', binaryData.mimeType);
// res.send(responseBody);
return { noWebhookResponse: true };
};
export const renderFormCompletion = async (
context: IWebhookFunctions,
@ -14,6 +56,12 @@ export const renderFormCompletion = async (
const completionMessage = context.getNodeParameter('completionMessage', '') as string;
const redirectUrl = context.getNodeParameter('redirectUrl', '') as string;
const options = context.getNodeParameter('options', {}) as { formTitle: string };
const respondWith = context.getNodeParameter('respondWith', '') as string;
const responseText = context.getNodeParameter('responseText', '') as string;
if (respondWith === 'returnBinary') {
return respondWithBinary(context, res);
}
if (redirectUrl) {
res.send(
@ -35,6 +83,7 @@ export const renderFormCompletion = async (
message: completionMessage,
formTitle: title,
appendAttribution,
responseText: sanitizeHtml(responseText),
});
return { noWebhookResponse: true };

View file

@ -220,7 +220,7 @@ export class Webhook extends Node {
});
if (options.binaryData) {
return await this.handleBinaryData(context, prepareOutput);
return await this.handleBinaryData(context, prepareOutput); // magic here
}
if (req.contentType === 'multipart/form-data') {