diff --git a/packages/nodes-base/nodes/JotForm/JotFormTrigger.node.ts b/packages/nodes-base/nodes/JotForm/JotFormTrigger.node.ts index cb86720dfc..9d05edcacf 100644 --- a/packages/nodes-base/nodes/JotForm/JotFormTrigger.node.ts +++ b/packages/nodes-base/nodes/JotForm/JotFormTrigger.node.ts @@ -1,3 +1,5 @@ +import * as formidable from 'formidable'; + import { IHookFunctions, IWebhookFunctions, @@ -16,6 +18,12 @@ import { jotformApiRequest, } from './GenericFunctions'; + +interface IQuestionData { + name: string; + text: string; +} + export class JotFormTrigger implements INodeType { description: INodeTypeDescription = { displayName: 'JotForm Trigger', @@ -56,6 +64,20 @@ export class JotFormTrigger implements INodeType { default: '', description: '', }, + { + displayName: 'Resolve Data', + name: 'resolveData', + type: 'boolean', + default: true, + description: 'By default does the webhook-data use internal keys instead of the names.
If this option gets activated it will resolve the keys automatically to the actual names.', + }, + { + displayName: 'Only Answers', + name: 'onlyAnswers', + type: 'boolean', + default: true, + description: 'Returns only the answers of the form and not any of the other data.', + }, ], }; @@ -141,10 +163,75 @@ export class JotFormTrigger implements INodeType { //@ts-ignore async webhook(this: IWebhookFunctions): Promise { const req = this.getRequestObject(); - return { - workflowData: [ - this.helpers.returnJsonArray(req.body) - ], - }; + const formId = this.getNodeParameter('form') as string; + const resolveData = this.getNodeParameter('resolveData', false) as boolean; + const onlyAnswers = this.getNodeParameter('onlyAnswers', false) as boolean; + + const form = new formidable.IncomingForm(); + + return new Promise((resolve, reject) => { + + form.parse(req, async (err, data, files) => { + + const rawRequest = JSON.parse(data.rawRequest as string); + data.rawRequest = rawRequest; + + let returnData: IDataObject; + if (resolveData === false) { + if (onlyAnswers === true) { + returnData = data.rawRequest as unknown as IDataObject; + } else { + returnData = data; + } + + resolve({ + workflowData: [ + this.helpers.returnJsonArray(returnData), + ], + }); + } + + // Resolve the data by requesting the information via API + const endpoint = `/form/${formId}/questions`; + const responseData = await jotformApiRequest.call(this, 'GET', endpoint, {}); + + // Create a dictionary to resolve the keys + const questionNames: IDataObject = {}; + for (const question of Object.values(responseData.content) as IQuestionData[]) { + questionNames[question.name] = question.text; + } + + // Resolve the keys + let questionKey: string; + const questionsData: IDataObject = {}; + for (const key of Object.keys(rawRequest)) { + if (!key.includes('_')) { + continue; + } + + questionKey = key.split('_').slice(1).join('_'); + if (questionNames[questionKey] === undefined) { + continue; + } + + questionsData[questionNames[questionKey] as string] = rawRequest[key]; + } + + if (onlyAnswers === true) { + returnData = questionsData as unknown as IDataObject; + } else { + // @ts-ignore + data.rawRequest = questionsData; + returnData = data; + } + + resolve({ + workflowData: [ + this.helpers.returnJsonArray(returnData), + ], + }); + }); + + }); } } diff --git a/packages/nodes-base/package.json b/packages/nodes-base/package.json index eb19ffcb5c..91b18e90e5 100644 --- a/packages/nodes-base/package.json +++ b/packages/nodes-base/package.json @@ -207,6 +207,7 @@ "@types/cron": "^1.6.1", "@types/eventsource": "^1.1.2", "@types/express": "^4.16.1", + "@types/formidable": "^1.0.31", "@types/gm": "^1.18.2", "@types/imap-simple": "^4.2.0", "@types/jest": "^24.0.18", @@ -232,6 +233,7 @@ "cheerio": "^1.0.0-rc.3", "cron": "^1.7.2", "eventsource": "^1.0.7", + "formidable": "^1.2.1", "glob-promise": "^3.4.0", "gm": "^1.23.1", "googleapis": "^46.0.0",