mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-17 10:02:05 +00:00
feat(n8n Form Page Node): New node (#10390)
Co-authored-by: Giulio Andreini <g.andreini@gmail.com> Co-authored-by: Shireen Missi <94372015+ShireenMissi@users.noreply.github.com>
This commit is contained in:
@@ -34,7 +34,10 @@ import {
|
||||
BINARY_ENCODING,
|
||||
createDeferredPromise,
|
||||
ErrorReporterProxy as ErrorReporter,
|
||||
ErrorReporterProxy,
|
||||
FORM_NODE_TYPE,
|
||||
NodeHelpers,
|
||||
NodeOperationError,
|
||||
} from 'n8n-workflow';
|
||||
import { finished } from 'stream/promises';
|
||||
import { Container } from 'typedi';
|
||||
@@ -120,7 +123,7 @@ export async function executeWebhook(
|
||||
);
|
||||
if (nodeType === undefined) {
|
||||
const errorMessage = `The type of the webhook node "${workflowStartNode.name}" is not known`;
|
||||
responseCallback(new Error(errorMessage), {});
|
||||
responseCallback(new ApplicationError(errorMessage), {});
|
||||
throw new InternalServerError(errorMessage);
|
||||
}
|
||||
|
||||
@@ -143,14 +146,37 @@ export async function executeWebhook(
|
||||
}
|
||||
|
||||
// Get the responseMode
|
||||
const responseMode = workflow.expression.getSimpleParameterValue(
|
||||
workflowStartNode,
|
||||
webhookData.webhookDescription.responseMode,
|
||||
executionMode,
|
||||
additionalKeys,
|
||||
undefined,
|
||||
'onReceived',
|
||||
) as WebhookResponseMode;
|
||||
let responseMode;
|
||||
|
||||
// if this is n8n FormTrigger node, check if there is a Form node in child nodes,
|
||||
// if so, set 'responseMode' to 'formPage' to redirect to URL of that Form later
|
||||
if (nodeType.description.name === 'formTrigger') {
|
||||
const connectedNodes = workflow.getChildNodes(workflowStartNode.name);
|
||||
let hasNextPage = false;
|
||||
for (const nodeName of connectedNodes) {
|
||||
const node = workflow.nodes[nodeName];
|
||||
if (node.type === FORM_NODE_TYPE && !node.disabled) {
|
||||
hasNextPage = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (hasNextPage) {
|
||||
responseMode = 'formPage';
|
||||
}
|
||||
}
|
||||
|
||||
if (!responseMode) {
|
||||
responseMode = workflow.expression.getSimpleParameterValue(
|
||||
workflowStartNode,
|
||||
webhookData.webhookDescription.responseMode,
|
||||
executionMode,
|
||||
additionalKeys,
|
||||
undefined,
|
||||
'onReceived',
|
||||
) as WebhookResponseMode;
|
||||
}
|
||||
|
||||
const responseCode = workflow.expression.getSimpleParameterValue(
|
||||
workflowStartNode,
|
||||
webhookData.webhookDescription.responseCode as string,
|
||||
@@ -169,12 +195,12 @@ export async function executeWebhook(
|
||||
'firstEntryJson',
|
||||
);
|
||||
|
||||
if (!['onReceived', 'lastNode', 'responseNode'].includes(responseMode)) {
|
||||
if (!['onReceived', 'lastNode', 'responseNode', 'formPage'].includes(responseMode)) {
|
||||
// If the mode is not known we error. Is probably best like that instead of using
|
||||
// the default that people know as early as possible (probably already testing phase)
|
||||
// that something does not resolve properly.
|
||||
const errorMessage = `The response mode '${responseMode}' is not valid!`;
|
||||
responseCallback(new Error(errorMessage), {});
|
||||
responseCallback(new ApplicationError(errorMessage), {});
|
||||
throw new InternalServerError(errorMessage);
|
||||
}
|
||||
|
||||
@@ -242,8 +268,26 @@ export async function executeWebhook(
|
||||
});
|
||||
} catch (err) {
|
||||
// Send error response to webhook caller
|
||||
const errorMessage = 'Workflow Webhook Error: Workflow could not be started!';
|
||||
responseCallback(new Error(errorMessage), {});
|
||||
const webhookType = ['formTrigger', 'form'].includes(nodeType.description.name)
|
||||
? 'Form'
|
||||
: 'Webhook';
|
||||
let errorMessage = `Workflow ${webhookType} Error: Workflow could not be started!`;
|
||||
|
||||
// if workflow started manually, show an actual error message
|
||||
if (err instanceof NodeOperationError && err.type === 'manual-form-test') {
|
||||
errorMessage = err.message;
|
||||
}
|
||||
|
||||
ErrorReporterProxy.error(err, {
|
||||
extra: {
|
||||
nodeName: workflowStartNode.name,
|
||||
nodeType: workflowStartNode.type,
|
||||
nodeVersion: workflowStartNode.typeVersion,
|
||||
workflowId: workflow.id,
|
||||
},
|
||||
});
|
||||
|
||||
responseCallback(new ApplicationError(errorMessage), {});
|
||||
didSendResponse = true;
|
||||
|
||||
// Add error to execution data that it can be logged and send to Editor-UI
|
||||
@@ -487,6 +531,12 @@ export async function executeWebhook(
|
||||
responsePromise,
|
||||
);
|
||||
|
||||
if (responseMode === 'formPage' && !didSendResponse) {
|
||||
res.redirect(`${additionalData.formWaitingBaseUrl}/${executionId}`);
|
||||
process.nextTick(() => res.end());
|
||||
didSendResponse = true;
|
||||
}
|
||||
|
||||
Container.get(Logger).debug(
|
||||
`Started execution of workflow "${workflow.name}" from webhook with execution ID ${executionId}`,
|
||||
{ executionId },
|
||||
@@ -562,7 +612,7 @@ export async function executeWebhook(
|
||||
// Return the JSON data of the first entry
|
||||
|
||||
if (returnData.data!.main[0]![0] === undefined) {
|
||||
responseCallback(new Error('No item to return got found'), {});
|
||||
responseCallback(new ApplicationError('No item to return got found'), {});
|
||||
didSendResponse = true;
|
||||
return undefined;
|
||||
}
|
||||
@@ -616,13 +666,13 @@ export async function executeWebhook(
|
||||
data = returnData.data!.main[0]![0];
|
||||
|
||||
if (data === undefined) {
|
||||
responseCallback(new Error('No item was found to return'), {});
|
||||
responseCallback(new ApplicationError('No item was found to return'), {});
|
||||
didSendResponse = true;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (data.binary === undefined) {
|
||||
responseCallback(new Error('No binary data was found to return'), {});
|
||||
responseCallback(new ApplicationError('No binary data was found to return'), {});
|
||||
didSendResponse = true;
|
||||
return undefined;
|
||||
}
|
||||
@@ -637,7 +687,10 @@ export async function executeWebhook(
|
||||
);
|
||||
|
||||
if (responseBinaryPropertyName === undefined && !didSendResponse) {
|
||||
responseCallback(new Error("No 'responseBinaryPropertyName' is set"), {});
|
||||
responseCallback(
|
||||
new ApplicationError("No 'responseBinaryPropertyName' is set"),
|
||||
{},
|
||||
);
|
||||
didSendResponse = true;
|
||||
}
|
||||
|
||||
@@ -646,7 +699,7 @@ export async function executeWebhook(
|
||||
];
|
||||
if (binaryData === undefined && !didSendResponse) {
|
||||
responseCallback(
|
||||
new Error(
|
||||
new ApplicationError(
|
||||
`The binary property '${responseBinaryPropertyName}' which should be returned does not exist`,
|
||||
),
|
||||
{},
|
||||
|
||||
Reference in New Issue
Block a user