{ "nodes": [ { "name": "Webhook", "type": "n8n-nodes-base.webhook", "position": [ 240, -120 ], "parameters": { "httpMethod": "POST", "path": "form-testimonial-capture", "responseMode": "onReceived", "options": {} }, "typeVersion": 1, "id": "form-testimonial-source-0" }, { "name": "Read Author and Feedback", "type": "n8n-nodes-base.code", "position": [ 460, -120 ], "parameters": { "mode": "runOnceForAllItems", "jsCode": "const prepare = function prepareTestimonial(inputs) {\n const fields = inputs.body?.data?.fields;\n if (!Array.isArray(fields)) throw new Error('Expected data.fields with author first and feedback second.');\n const Author = fields[0]?.value;\n const Content = fields[1]?.value;\n if (typeof Author !== 'string' || !Author.trim() || typeof Content !== 'string' || !Content.trim()) throw new Error('Author and feedback must be nonempty text fields.');\n const Created = new Date().toISOString();\n return { Author, Content, Created, URL: '', request: { document: { type: 'PLAIN_TEXT', content: Content }, encodingType: 'UTF16' } };\n}\n\nreturn [{json:prepare({body:$input.first().json.body}),pairedItem:{item:0}}];\n" }, "typeVersion": 2, "id": "form-testimonial-source-1" }, { "name": "Analyze Form Submission", "type": "n8n-nodes-base.googleCloudNaturalLanguage", "position": [ 680, -220 ], "parameters": { "resource": "document", "operation": "analyzeSentiment", "source": "content", "content": "={{ $json.Content }}", "options": { "documentType": "PLAIN_TEXT", "encodingType": "UTF16" } }, "typeVersion": 1, "id": "form-testimonial-source-2" }, { "name": "Positive Form Sentiment?", "type": "n8n-nodes-base.if", "position": [ 1120, -120 ], "parameters": { "conditions": { "number": [ { "value1": "={{ $json.score }}", "operation": "larger", "value2": 0.4 } ] }, "combineOperation": "all" }, "typeVersion": 1, "id": "form-testimonial-source-3" }, { "name": "Store Form Submission in Strapi", "type": "n8n-nodes-base.strapi", "position": [ 1340, -120 ], "parameters": { "authentication": "token", "resource": "entry", "operation": "create", "contentType": "posts", "columns": "Content,Author,Created,URL" }, "typeVersion": 1, "id": "form-testimonial-source-4" }, { "id": "validate-testimonial-score", "name": "Validate Form Score", "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ 650, 300 ], "parameters": { "mode": "runOnceForAllItems", "jsCode": "const validate = function readSentiment(inputs) {\n const body = inputs.body;\n const score = body?.documentSentiment?.score;\n if (!body || typeof body !== 'object' || Array.isArray(body) || body.error || typeof score !== 'number' || !Number.isFinite(score) || score < -1 || score > 1) throw new Error('The sentiment service did not return a valid document score.');\n return { score };\n}\n\nreturn [{json:validate({body:$input.first().json}),pairedItem:{item:0}}];\n" } }, { "id": "select-testimonial-fields", "name": "Select Strapi Entry Fields", "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ 1050, 200 ], "parameters": { "mode": "runOnceForAllItems", "jsCode": "const payload = function prepareStrapiPayload(inputs) {\n const { Author, Content, Created, URL } = inputs;\n return { record: { Content, Author, Created, URL }, body: { data: { Content, Author, Created, URL } } };\n}\n\nreturn [{json:payload($('Read Author and Feedback').first().json).record,pairedItem:{item:0}}];\n" } }, { "id": "confirm-testimonial-created", "name": "Confirm Captured Entry", "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ 1450, 200 ], "parameters": { "mode": "runOnceForAllItems", "jsCode": "const pack = function testimonialResult(inputs) {\n if (inputs.body === null) return { result: { status: 'ignored', score: inputs.score, entry: null } };\n const body = inputs.body;\n const entry = body?.data;\n if (!body || typeof body !== 'object' || body.error || !entry || typeof entry !== 'object' || Array.isArray(entry) || !(typeof entry.documentId === 'string' && entry.documentId || typeof entry.id === 'number' && Number.isFinite(entry.id) || typeof entry.id === 'string' && entry.id)) throw new Error('Strapi did not confirm a created entry.');\n return { result: { status: 'captured', score: inputs.score, entry } };\n}\n\nreturn [{json:pack({body:$input.first().json,score:$('Validate Form Score').first().json.score}).result,pairedItem:{item:0}}];\n" } }, { "id": "return-testimonial-ignored", "name": "Return Ignored Feedback", "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ 1050, 500 ], "parameters": { "mode": "runOnceForAllItems", "jsCode": "const pack = function testimonialResult(inputs) {\n if (inputs.body === null) return { result: { status: 'ignored', score: inputs.score, entry: null } };\n const body = inputs.body;\n const entry = body?.data;\n if (!body || typeof body !== 'object' || body.error || !entry || typeof entry !== 'object' || Array.isArray(entry) || !(typeof entry.documentId === 'string' && entry.documentId || typeof entry.id === 'number' && Number.isFinite(entry.id) || typeof entry.id === 'string' && entry.id)) throw new Error('Strapi did not confirm a created entry.');\n return { result: { status: 'captured', score: inputs.score, entry } };\n}\n\nreturn [{json:pack({body:null,score:$input.first().json.score}).result,pairedItem:{item:0}}];\n" } }, { "id": "testimonial-result", "name": "Capture Result", "type": "n8n-nodes-base.noOp", "typeVersion": 1, "position": [ 1650, 300 ], "parameters": {} } ], "connections": { "Webhook": { "main": [ [ { "node": "Read Author and Feedback", "type": "main", "index": 0 } ] ] }, "Read Author and Feedback": { "main": [ [ { "node": "Analyze Form Submission", "type": "main", "index": 0 } ] ] }, "Analyze Form Submission": { "main": [ [ { "node": "Validate Form Score", "type": "main", "index": 0 } ] ] }, "Validate Form Score": { "main": [ [ { "node": "Positive Form Sentiment?", "type": "main", "index": 0 } ] ] }, "Positive Form Sentiment?": { "main": [ [ { "node": "Select Strapi Entry Fields", "type": "main", "index": 0 } ], [ { "node": "Return Ignored Feedback", "type": "main", "index": 0 } ] ] }, "Select Strapi Entry Fields": { "main": [ [ { "node": "Store Form Submission in Strapi", "type": "main", "index": 0 } ] ] }, "Store Form Submission in Strapi": { "main": [ [ { "node": "Confirm Captured Entry", "type": "main", "index": 0 } ] ] }, "Confirm Captured Entry": { "main": [ [ { "node": "Capture Result", "type": "main", "index": 0 } ] ] }, "Return Ignored Feedback": { "main": [ [ { "node": "Capture Result", "type": "main", "index": 0 } ] ] } }, "settings": { "executionOrder": "v1" }, "active": false, "pinData": {} }