feat(n8n Form Trigger Node): Improvements (#7571)

Github issue / Community forum post (link here to close automatically):

---------

Co-authored-by: कारतोफ्फेलस्क्रिप्ट™ <aditya@netroy.in>
Co-authored-by: Giulio Andreini <andreini@netseven.it>
This commit is contained in:
Michael Kret
2023-12-13 17:00:51 +02:00
committed by GitHub
parent 26f0d57f5f
commit 953a58f18b
37 changed files with 1163 additions and 496 deletions

View File

@@ -1,13 +1,15 @@
import type { IDataObject } from 'n8n-workflow';
import { jsonParse, type IDataObject, type IWebhookFunctions } from 'n8n-workflow';
import type { FormField, FormTriggerData, FormTriggerInput } from './interfaces';
export const prepareFormData = (
formTitle: string,
formDescription: string,
formSubmittedText: string | undefined,
redirectUrl: string | undefined,
formFields: FormField[],
testRun: boolean,
instanceId?: string,
useResponseData?: boolean,
) => {
const validForm = formFields.length > 0;
const utm_campaign = instanceId ? `&utm_campaign=${instanceId}` : '';
@@ -25,8 +27,16 @@ export const prepareFormData = (
formSubmittedText,
n8nWebsiteLink,
formFields: [],
useResponseData,
};
if (redirectUrl) {
if (!redirectUrl.includes('://')) {
redirectUrl = `http://${redirectUrl}`;
}
formData.redirectUrl = redirectUrl;
}
if (!validForm) {
return formData;
}
@@ -64,3 +74,83 @@ export const prepareFormData = (
return formData;
};
export async function formWebhook(context: IWebhookFunctions) {
const mode = context.getMode() === 'manual' ? 'test' : 'production';
const formFields = context.getNodeParameter('formFields.values', []) as FormField[];
const method = context.getRequestObject().method;
//Show the form on GET request
if (method === 'GET') {
const formTitle = context.getNodeParameter('formTitle', '') as string;
const formDescription = context.getNodeParameter('formDescription', '') as string;
const instanceId = context.getInstanceId();
const responseMode = context.getNodeParameter('responseMode', '') as string;
const options = context.getNodeParameter('options', {}) as IDataObject;
let formSubmittedText;
let redirectUrl;
if (options.respondWithOptions) {
const values = (options.respondWithOptions as IDataObject).values as IDataObject;
if (values.respondWith === 'text') {
formSubmittedText = values.formSubmittedText as string;
}
if (values.respondWith === 'redirect') {
redirectUrl = values.redirectUrl as string;
}
} else {
formSubmittedText = options.formSubmittedText as string;
}
const useResponseData = responseMode === 'responseNode';
const data = prepareFormData(
formTitle,
formDescription,
formSubmittedText,
redirectUrl,
formFields,
mode === 'test',
instanceId,
useResponseData,
);
const res = context.getResponseObject();
res.render('form-trigger', data);
return {
noWebhookResponse: true,
};
}
const bodyData = (context.getBodyData().data as IDataObject) ?? {};
const returnData: IDataObject = {};
for (const [index, field] of formFields.entries()) {
const key = `field-${index}`;
let value = bodyData[key] ?? null;
if (value === null) returnData[field.fieldLabel] = null;
if (field.fieldType === 'number') {
value = Number(value);
}
if (field.fieldType === 'text') {
value = String(value).trim();
}
if (field.multiselect && typeof value === 'string') {
value = jsonParse(value);
}
returnData[field.fieldLabel] = value;
}
returnData.submittedAt = new Date().toISOString();
returnData.formMode = mode;
const webhookResponse: IDataObject = { status: 200 };
return {
webhookResponse,
workflowData: [context.helpers.returnJsonArray(returnData)],
};
}