This workflow corresponds to n8n.io template #14916 — we link there as the canonical source.
This workflow follows the Agent → HTTP Request recipe pattern — see all workflows that pair these two integrations.
The workflow JSON
Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →
{
"id": "oHOypWGqJ2ss3UTc",
"meta": {
"templateCredsSetupCompleted": true
},
"name": "Automated Testimonial & Review Collector",
"tags": [],
"nodes": [
{
"id": "7d97d219-5f0f-4a3f-a8e1-f25a3cab644b",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
0,
-544
],
"parameters": {
"width": 920,
"height": 1884,
"content": "## Automated Testimonial & Review Collector\n\nThis workflow automatically collects, processes, and publishes customer testimonials and reviews after project completion or purchase. It uses AI to generate polished testimonials from raw feedback and distributes them across your marketing channels.\n\n### How it works\n\n1. **Trigger** - Detects project completion, purchase, or manual trigger\n2. **Customer Lookup** - Fetches customer details from CRM/database\n3. **Smart Timing Check** - Determines optimal follow-up timing based on purchase/completion date\n4. **Send Feedback Request** - Sends personalized email/SMS requesting review\n5. **Track Form Submissions** - Monitors feedback form responses\n6. **Sentiment Analysis** - AI analyzes feedback sentiment and quality\n7. **Generate Polished Testimonial** - Claude AI converts raw feedback into professional testimonials\n8. **Quality Filter** - Filters testimonials based on rating and sentiment\n9. **Format for Channels** - Prepares testimonials for different platforms\n10. **Publish to Website** - Auto-posts to WordPress/Webflow/custom CMS\n11. **Post to Social Proof Tools** - Sends to Trustpilot, Google Reviews, testimonial widgets\n12. **Update CRM** - Logs testimonial status in customer records\n13. **Send Thank You** - Automated appreciation message to customer\n14. **Analytics Dashboard** - Tracks collection rates and testimonial performance\n\n### Setup Steps\n\n1. Import workflow into n8n\n2. Configure credentials:\n - **Anthropic API** - Claude AI for testimonial generation\n - **CRM Integration** - HubSpot/Salesforce/Airtable for customer data\n - **Email Service** - SendGrid/Mailgun for follow-up emails\n - **SMS Provider** - Twilio for SMS reminders\n - **Website CMS** - WordPress/Webflow API for publishing\n - **Social Proof Tools** - Trustpilot, Google My Business, Yotpo\n - **Form Builder** - Typeform/Google Forms for feedback collection\n3. Set your timing rules (e.g., 7 days after purchase)\n4. Configure AI testimonial generation prompts\n5. Set quality thresholds (minimum 4-star rating)\n6. Map testimonial fields to your website/tools\n7. Activate the workflow\n\n### Sample Trigger Payload\n```json\n{\n \"customerId\": \"CUST-12345\",\n \"customerEmail\": \"john@example.com\",\n \"customerName\": \"John Smith\",\n \"projectType\": \"Website Development\",\n \"completionDate\": \"2024-04-01\",\n \"projectValue\": 5000,\n \"followUpDelay\": 7,\n \"preferredChannel\": \"email\"\n}\n```\n\n### AI Testimonial Generation Features\n- Converts casual feedback into professional testimonials\n- Maintains authenticity while improving clarity\n- Generates multiple versions for different platforms\n- Extracts key benefits and outcomes mentioned\n- Creates compelling headlines from feedback\n- Suggests best quotes for marketing materials\n\n### Publishing Channels\n- Website testimonial sections (auto-inject HTML)\n- Google My Business reviews\n- Trustpilot/G2/Capterra\n- Social media testimonial posts\n- Email signature testimonials\n- Case study content\n- Landing page social proof widgets\n\n### Smart Features\n- Multi-touch follow-up sequences (email \u2192 SMS \u2192 reminder)\n- Optimal timing based on customer journey stage\n- Personalized feedback requests with project context\n- Automatic language detection and translation\n- Video testimonial collection via integrated forms\n- Screenshot/photo attachment handling\n- Auto-detection of negative feedback for internal review\n- A/B testing of follow-up messaging\n- Response rate tracking and optimization"
},
"typeVersion": 1
},
{
"id": "2b655dc1-2576-499d-8347-c90a11e06672",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
992,
-48
],
"parameters": {
"color": 4,
"width": 640,
"height": 500,
"content": "## 1. Trigger & Customer Data"
},
"typeVersion": 1
},
{
"id": "592db6ef-09dc-49a6-8228-5fa6e1033e9f",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
1694,
-252
],
"parameters": {
"color": 4,
"width": 836,
"height": 700,
"content": "## 2. Smart Follow-up & Feedback Collection"
},
"typeVersion": 1
},
{
"id": "c6b51cab-9103-45d5-83d7-bf65a08d5c5a",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
992,
496
],
"parameters": {
"color": 3,
"width": 792,
"height": 684,
"content": "## 3. AI Processing & Enhancement (Claude)"
},
"typeVersion": 1
},
{
"id": "82d2f881-8dd6-457b-b244-002463ede322",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
1822,
504
],
"parameters": {
"color": 3,
"width": 1412,
"height": 728,
"content": "## 4. Publish, Distribute & Track"
},
"typeVersion": 1
},
{
"id": "ec5a88ea-58e9-4514-866b-1f68af9641d3",
"name": "Webhook Trigger - Project Completion",
"type": "n8n-nodes-base.webhook",
"position": [
1056,
288
],
"parameters": {
"path": "testimonial-trigger",
"options": {},
"httpMethod": "POST",
"responseMode": "responseNode"
},
"typeVersion": 1.1
},
{
"id": "96cdf67a-07d6-4d62-8303-7423f20d2e23",
"name": "Daily Batch Check",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
1056,
96
],
"parameters": {
"rule": {
"interval": [
{
"field": "cronExpression",
"expression": "0 9 * * *"
}
]
}
},
"typeVersion": 1.2
},
{
"id": "9d4d0310-a176-4ee6-afa2-9d8538d00628",
"name": "Prepare Customer Context",
"type": "n8n-nodes-base.set",
"position": [
1280,
192
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "customer-id",
"name": "customerId",
"type": "string",
"value": "={{ $json.body?.customerId || $json.customerId || 'MANUAL-' + Date.now() }}"
},
{
"id": "customer-email",
"name": "customerEmail",
"type": "string",
"value": "={{ $json.body?.customerEmail || $json.customerEmail }}"
},
{
"id": "customer-name",
"name": "customerName",
"type": "string",
"value": "={{ $json.body?.customerName || $json.customerName }}"
},
{
"id": "project-type",
"name": "projectType",
"type": "string",
"value": "={{ $json.body?.projectType || $json.projectType || 'General Service' }}"
},
{
"id": "completion-date",
"name": "completionDate",
"type": "string",
"value": "={{ $json.body?.completionDate || $json.completionDate || new Date().toISOString() }}"
},
{
"id": "followup-days",
"name": "followUpDelay",
"type": "number",
"value": "={{ $json.body?.followUpDelay || 7 }}"
},
{
"id": "preferred-channel",
"name": "preferredChannel",
"type": "string",
"value": "={{ $json.body?.preferredChannel || 'email' }}"
},
{
"id": "job-id",
"name": "jobId",
"type": "string",
"value": "=REVIEW-{{ Date.now() }}-{{ Math.random().toString(36).substr(2, 6).toUpperCase() }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "ddbd4822-9e47-4812-bf45-d59b303a8fd9",
"name": "Fetch Full Customer Profile from CRM",
"type": "n8n-nodes-base.httpRequest",
"position": [
1504,
192
],
"parameters": {
"url": "=https://api.hubspot.com/crm/v3/objects/contacts/{{ $json.customerId }}",
"options": {
"timeout": 10000
},
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Authorization",
"value": "Bearer YOUR_TOKEN_HERE"
},
{
"name": "Content-Type",
"value": "application/json"
}
]
}
},
"typeVersion": 4.2,
"continueOnFail": true
},
{
"id": "74fa2fa2-24d5-47cf-b2ab-a6c44c2900b0",
"name": "Check Optimal Follow-up Timing",
"type": "n8n-nodes-base.code",
"position": [
1728,
192
],
"parameters": {
"mode": "runOnceForEachItem",
"jsCode": "// Determine if now is the right time to send follow-up\nconst context = $input.item.json;\nconst completionDate = new Date(context.completionDate);\nconst now = new Date();\nconst daysSinceCompletion = Math.floor((now - completionDate) / (1000 * 60 * 60 * 24));\nconst targetDelay = context.followUpDelay || 7;\n\n// Check if we're within the follow-up window\nconst isReadyForFollowup = daysSinceCompletion >= targetDelay && daysSinceCompletion <= targetDelay + 3;\n\n// Fetch CRM data if available\nconst crmData = $('Fetch Full Customer Profile from CRM').item?.json?.properties || {};\nconst hasGivenReview = crmData.testimonial_submitted === 'true';\n\nreturn {\n json: {\n ...context,\n customerData: {\n email: context.customerEmail,\n name: context.customerName,\n phone: crmData.phone || null,\n company: crmData.company || null,\n industry: crmData.industry || null,\n totalPurchases: parseInt(crmData.total_purchases) || 1,\n lifetimeValue: parseFloat(crmData.lifetime_value) || 0\n },\n timing: {\n completionDate: completionDate.toISOString(),\n daysSinceCompletion,\n targetDelay,\n isReadyForFollowup,\n hasAlreadyReviewed: hasGivenReview,\n shouldSendFollowup: isReadyForFollowup && !hasGivenReview\n },\n projectContext: {\n type: context.projectType,\n description: crmData.last_project_description || `${context.projectType} project`,\n outcome: crmData.project_outcome || 'Successfully completed',\n deliverables: crmData.project_deliverables?.split(',') || []\n },\n processedAt: new Date().toISOString()\n }\n};"
},
"typeVersion": 2
},
{
"id": "9d665f13-302f-4232-8f7b-b64594da2988",
"name": "Filter Ready for Follow-up",
"type": "n8n-nodes-base.filter",
"position": [
1952,
192
],
"parameters": {
"options": {},
"conditions": {
"options": {
"leftValue": "",
"caseSensitive": false,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"operator": {
"type": "boolean",
"operation": "true"
},
"leftValue": "={{ $json.timing.shouldSendFollowup }}"
},
{
"operator": {
"type": "string",
"operation": "exists"
},
"leftValue": "={{ $json.customerData.email }}"
}
]
}
},
"typeVersion": 2.2
},
{
"id": "5e21bf1c-0d45-41e6-98f1-4d7c4230e5a0",
"name": "Generate Personalized Feedback Form",
"type": "n8n-nodes-base.httpRequest",
"position": [
2176,
96
],
"parameters": {
"url": "https://api.typeform.com/forms",
"method": "POST",
"options": {
"timeout": 10000
},
"jsonBody": "={\n \"title\": \"How was your {{ $json.projectContext.type }} experience?\",\n \"fields\": [\n {\n \"type\": \"opinion_scale\",\n \"title\": \"How satisfied are you with our service?\",\n \"properties\": {\n \"start_at_one\": true,\n \"steps\": 5,\n \"labels\": {\n \"left\": \"Not satisfied\",\n \"right\": \"Extremely satisfied\"\n }\n },\n \"required\": true\n },\n {\n \"type\": \"long_text\",\n \"title\": \"What did you like most about working with us?\",\n \"required\": true\n },\n {\n \"type\": \"long_text\",\n \"title\": \"What specific results or outcomes did you achieve?\",\n \"required\": false\n },\n {\n \"type\": \"yes_no\",\n \"title\": \"Would you recommend us to others?\",\n \"required\": true\n },\n {\n \"type\": \"long_text\",\n \"title\": \"Any additional feedback or suggestions?\",\n \"required\": false\n }\n ],\n \"hidden\": [\n \"customer_id={{ $json.customerId }}\",\n \"project_type={{ $json.projectContext.type }}\"\n ]\n}",
"sendBody": true,
"sendHeaders": true,
"specifyBody": "json",
"headerParameters": {
"parameters": [
{
"name": "Authorization",
"value": "Bearer YOUR_TOKEN_HERE"
},
{
"name": "Content-Type",
"value": "application/json"
}
]
}
},
"typeVersion": 4.2,
"continueOnFail": true
},
{
"id": "391a9654-395d-4b88-8494-0890af98f558",
"name": "Send Feedback Request Email",
"type": "n8n-nodes-base.httpRequest",
"position": [
2176,
288
],
"parameters": {
"url": "https://api.sendgrid.com/v3/mail/send",
"method": "POST",
"options": {
"timeout": 10000
},
"jsonBody": "={\n \"personalizations\": [{\n \"to\": [{\"email\": \"{{ $json.customerData.email }}\", \"name\": \"{{ $json.customerData.name }}\"}],\n \"dynamic_template_data\": {\n \"customer_name\": \"{{ $json.customerData.name }}\",\n \"project_type\": \"{{ $json.projectContext.type }}\",\n \"completion_date\": \"{{ new Date($json.timing.completionDate).toLocaleDateString() }}\",\n \"feedback_form_url\": \"{{ $('Generate Personalized Feedback Form').item.json.form_url || 'https://form.example.com/feedback' }}\",\n \"company_name\": \"Your Company\"\n }\n }],\n \"from\": {\"email\": \"reviews@yourcompany.com\", \"name\": \"Your Company Team\"},\n \"template_id\": \"YOUR_SENDGRID_TEMPLATE_ID\"\n}",
"sendBody": true,
"sendHeaders": true,
"specifyBody": "json",
"headerParameters": {
"parameters": [
{
"name": "Authorization",
"value": "Bearer YOUR_TOKEN_HERE"
},
{
"name": "Content-Type",
"value": "application/json"
}
]
}
},
"typeVersion": 4.2,
"continueOnFail": true
},
{
"id": "807672f4-1fab-4bf7-828e-7b9453d332f5",
"name": "Webhook - Form Submission Received",
"type": "n8n-nodes-base.webhook",
"position": [
1056,
816
],
"parameters": {
"path": "feedback-submission",
"options": {},
"httpMethod": "POST",
"responseMode": "responseNode"
},
"typeVersion": 1.1
},
{
"id": "66675c6f-b2ea-4736-a49a-2d744060eaa1",
"name": "Parse Feedback Response",
"type": "n8n-nodes-base.code",
"position": [
1280,
816
],
"parameters": {
"mode": "runOnceForEachItem",
"jsCode": "// Parse incoming feedback form submission\nconst submission = $input.item.json;\nconst formData = submission.form_response || submission;\n\n// Extract answers (adapt based on your form platform)\nconst answers = formData.answers || [];\nconst rating = answers.find(a => a.type === 'opinion_scale')?.opinion_scale || 5;\nconst whatLiked = answers.find(a => a.field?.title?.includes('like most'))?.text || '';\nconst results = answers.find(a => a.field?.title?.includes('results'))?.text || '';\nconst wouldRecommend = answers.find(a => a.type === 'yes_no')?.boolean || true;\nconst additionalFeedback = answers.find(a => a.field?.title?.includes('additional'))?.text || '';\n\n// Extract hidden fields\nconst customerId = formData.hidden?.customer_id || 'UNKNOWN';\nconst projectType = formData.hidden?.project_type || 'General Service';\n\n// Combine all feedback text\nconst fullFeedback = [\n whatLiked,\n results,\n additionalFeedback\n].filter(Boolean).join(' ');\n\nreturn {\n json: {\n submissionId: formData.response_id || `SUB-${Date.now()}`,\n customerId,\n projectType,\n rating,\n wouldRecommend,\n feedback: {\n whatLiked,\n results,\n additionalFeedback,\n fullText: fullFeedback\n },\n metadata: {\n submittedAt: formData.submitted_at || new Date().toISOString(),\n formId: formData.form_id,\n responseId: formData.response_id\n },\n rawSubmission: formData\n }\n};"
},
"typeVersion": 2
},
{
"id": "83ef5b59-949a-44fd-851d-e9e4f675d8f5",
"name": "AI Sentiment & Quality Analysis",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
1504,
512
],
"parameters": {
"text": "=Analyze this customer feedback and provide a structured assessment.\n\n**Customer Feedback:**\nRating: {{ $json.rating }}/5 stars\nWould Recommend: {{ $json.wouldRecommend ? 'Yes' : 'No' }}\n\nWhat they liked: {{ $json.feedback.whatLiked }}\n\nResults achieved: {{ $json.feedback.results }}\n\nAdditional comments: {{ $json.feedback.additionalFeedback }}\n\n**Analysis Required:**\n1. Sentiment (VERY_POSITIVE, POSITIVE, NEUTRAL, NEGATIVE, VERY_NEGATIVE)\n2. Quality score (0-100) - how detailed and useful is this feedback?\n3. Key themes mentioned (max 5)\n4. Specific benefits/outcomes mentioned\n5. Emotional tone indicators\n6. Testimonial-worthy quotes (extract 1-3 best sentences)\n7. Suggestion for improvement areas mentioned\n8. Authenticity score (does it sound genuine?)\n\nReturn JSON only:\n{\n \"sentiment\": \"POSITIVE\",\n \"sentimentScore\": 85,\n \"qualityScore\": 75,\n \"keyThemes\": [\"professional service\", \"timely delivery\", \"great communication\"],\n \"benefitsMentioned\": [\"increased sales by 40%\", \"saved 10 hours per week\"],\n \"emotionalTone\": \"enthusiastic and grateful\",\n \"bestQuotes\": [\"Working with them was a game-changer for our business\"],\n \"improvementSuggestions\": [],\n \"authenticityScore\": 90,\n \"isTestimonialWorthy\": true,\n \"reasoning\": \"Specific results, genuine enthusiasm, concrete benefits\"\n}",
"options": {
"systemMessage": "You are an expert in analyzing customer feedback and testimonials. Return only valid JSON with no markdown formatting."
},
"promptType": "define"
},
"typeVersion": 1.6
},
{
"id": "b5fecc46-14b7-42e1-b266-52ff9aae2b1a",
"name": "Generate Polished Testimonial with Claude",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
1504,
912
],
"parameters": {
"text": "=Transform this raw customer feedback into professional testimonials while maintaining authenticity.\n\n**Raw Feedback:**\nRating: {{ $json.rating }}/5 stars\nCustomer: {{ $json.customerId }}\nProject: {{ $json.projectType }}\n\nFeedback: {{ $json.feedback.fullText }}\n\n**Sentiment Analysis:**\n{{ JSON.stringify($('AI Sentiment & Quality Analysis').item.json, null, 2) }}\n\n**Requirements:**\n1. Create 3 versions: Short (1 sentence), Medium (2-3 sentences), Long (paragraph)\n2. Maintain the customer's voice and authenticity\n3. Highlight specific results and benefits mentioned\n4. Make it compelling but truthful\n5. Include a headline/title for each version\n6. Suggest best use cases for each version\n\nReturn JSON only:\n{\n \"testimonials\": {\n \"short\": {\n \"text\": \"One sentence testimonial\",\n \"headline\": \"Great Results!\",\n \"bestFor\": [\"social media\", \"email signatures\"]\n },\n \"medium\": {\n \"text\": \"2-3 sentence testimonial\",\n \"headline\": \"Transformed Our Business\",\n \"bestFor\": [\"website homepage\", \"landing pages\"]\n },\n \"long\": {\n \"text\": \"Full paragraph testimonial\",\n \"headline\": \"A Game-Changing Partnership\",\n \"bestFor\": [\"case studies\", \"detailed reviews\"]\n }\n },\n \"pullQuote\": \"Most impactful single sentence\",\n \"socialMediaPost\": \"Ready-to-post version with emojis\",\n \"metaDescription\": \"SEO-friendly summary\",\n \"keyBenefits\": [\"benefit 1\", \"benefit 2\"],\n \"recommendedPlatforms\": [\"website\", \"google\", \"trustpilot\"],\n \"contentRating\": \"family_friendly\"\n}",
"options": {
"systemMessage": "You are an expert copywriter specializing in testimonials. Transform raw feedback into compelling, authentic testimonials that maintain the customer's voice. Return only valid JSON."
},
"promptType": "define"
},
"typeVersion": 1.6
},
{
"id": "d2467b46-4251-4299-aa67-b18e430ea2ce",
"name": "Claude AI Model",
"type": "@n8n/n8n-nodes-langchain.lmChatAnthropic",
"position": [
1576,
736
],
"parameters": {
"model": "=claude-sonnet-4-20250514",
"options": {
"temperature": 0.3
}
},
"credentials": {
"anthropicApi": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "d8b3bbdb-ebb0-4b97-957c-6f1f27f97aec",
"name": "Parse AI Generated Content",
"type": "n8n-nodes-base.code",
"position": [
1856,
816
],
"parameters": {
"mode": "runOnceForEachItem",
"jsCode": "// Parse both sentiment analysis and testimonial generation\nconst sentimentResponse = $('AI Sentiment & Quality Analysis').item.json;\nconst testimonialResponse = $('Generate Polished Testimonial with Claude').item.json;\n\nconst originalFeedback = $('Parse Feedback Response').item.json;\n\n// Extract AI responses (handle different response formats)\nlet sentimentData, testimonialData;\n\ntry {\n const sentimentText = sentimentResponse.response || sentimentResponse.output || sentimentResponse.text || '';\n const cleanSentiment = sentimentText.replace(/```json\\s*/g, '').replace(/```\\s*/g, '').trim();\n sentimentData = JSON.parse(cleanSentiment);\n} catch (e) {\n sentimentData = {\n sentiment: 'POSITIVE',\n qualityScore: 70,\n isTestimonialWorthy: true\n };\n}\n\ntry {\n const testimonialText = testimonialResponse.response || testimonialResponse.output || testimonialResponse.text || '';\n const cleanTestimonial = testimonialText.replace(/```json\\s*/g, '').replace(/```\\s*/g, '').trim();\n testimonialData = JSON.parse(cleanTestimonial);\n} catch (e) {\n testimonialData = {\n testimonials: {\n short: { text: originalFeedback.feedback.fullText.substring(0, 100) }\n }\n };\n}\n\nreturn {\n json: {\n submissionId: originalFeedback.submissionId,\n customerId: originalFeedback.customerId,\n projectType: originalFeedback.projectType,\n rating: originalFeedback.rating,\n wouldRecommend: originalFeedback.wouldRecommend,\n originalFeedback: originalFeedback.feedback,\n sentimentAnalysis: sentimentData,\n generatedTestimonials: testimonialData,\n metadata: {\n ...originalFeedback.metadata,\n processedAt: new Date().toISOString()\n }\n }\n};"
},
"typeVersion": 2
},
{
"id": "50807ec9-88fc-4534-a2f1-e8a5ee4a1cb1",
"name": "Filter High-Quality Testimonials",
"type": "n8n-nodes-base.filter",
"position": [
2080,
720
],
"parameters": {
"options": {},
"conditions": {
"options": {
"leftValue": "",
"caseSensitive": false,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"operator": {
"type": "number",
"operation": "gte"
},
"leftValue": "={{ $json.rating }}",
"rightValue": 4
},
{
"operator": {
"type": "boolean",
"operation": "true"
},
"leftValue": "={{ $json.sentimentAnalysis.isTestimonialWorthy }}"
},
{
"operator": {
"type": "number",
"operation": "gte"
},
"leftValue": "={{ $json.sentimentAnalysis.qualityScore }}",
"rightValue": 60
}
]
}
},
"typeVersion": 2.2
},
{
"id": "228f1aad-94f3-4302-b919-557b8a8498b8",
"name": "Format for Publishing Platforms",
"type": "n8n-nodes-base.code",
"position": [
2304,
720
],
"parameters": {
"jsCode": "// Format testimonial for different platforms\nconst items = $input.all();\n\nconst formatted = items.map(item => {\n const d = item.json;\n const testimonials = d.generatedTestimonials.testimonials;\n \n return {\n json: {\n ...d,\n platformFormats: {\n website: {\n html: `<div class=\"testimonial\">\n <div class=\"rating\">${'\u2605'.repeat(d.rating)}${'\u2606'.repeat(5-d.rating)}</div>\n <blockquote>${testimonials.medium.text}</blockquote>\n <cite>\u2014 ${d.customerId}</cite>\n <p class=\"project-type\">${d.projectType}</p>\n</div>`,\n json: {\n rating: d.rating,\n text: testimonials.medium.text,\n author: d.customerId,\n projectType: d.projectType,\n date: d.metadata.submittedAt\n }\n },\n google: {\n rating: d.rating,\n comment: testimonials.long.text\n },\n trustpilot: {\n rating: d.rating,\n title: testimonials.medium.headline,\n content: testimonials.long.text\n },\n socialMedia: {\n twitter: testimonials.short.text + ' \u2b50'.repeat(d.rating),\n linkedin: testimonials.medium.text,\n instagram: d.generatedTestimonials.socialMediaPost\n },\n emailSignature: {\n text: `\"${d.generatedTestimonials.pullQuote}\" - ${d.customerId}`\n }\n },\n publishReady: true\n }\n };\n});\n\nreturn formatted;"
},
"typeVersion": 2
},
{
"id": "94d14c5f-c4da-4f9c-9fd6-a064e8ec678d",
"name": "Publish to Website (WordPress)",
"type": "n8n-nodes-base.httpRequest",
"position": [
2528,
528
],
"parameters": {
"url": "=https://yoursite.com/wp-json/wp/v2/testimonials",
"method": "POST",
"options": {
"timeout": 10000
},
"jsonBody": "={\n \"title\": \"{{ $json.generatedTestimonials.testimonials.medium.headline }}\",\n \"content\": \"{{ $json.platformFormats.website.html }}\",\n \"status\": \"publish\",\n \"meta\": {\n \"rating\": {{ $json.rating }},\n \"customer_id\": \"{{ $json.customerId }}\",\n \"project_type\": \"{{ $json.projectType }}\",\n \"submission_date\": \"{{ $json.metadata.submittedAt }}\"\n }\n}",
"sendBody": true,
"sendHeaders": true,
"specifyBody": "json",
"headerParameters": {
"parameters": [
{
"name": "Authorization",
"value": "Basic YOUR_WORDPRESS_AUTH_TOKEN"
},
{
"name": "Content-Type",
"value": "application/json"
}
]
}
},
"typeVersion": 4.2,
"continueOnFail": true
},
{
"id": "822923ab-bed2-4865-b7b6-28f0850d56c5",
"name": "Submit to Trustpilot",
"type": "n8n-nodes-base.httpRequest",
"position": [
2528,
720
],
"parameters": {
"url": "https://api.trustpilot.com/v1/private/business-units/YOUR_BUSINESS_ID/reviews",
"method": "POST",
"options": {
"timeout": 10000
},
"jsonBody": "={\n \"consumer\": {\n \"email\": \"{{ $('Check Optimal Follow-up Timing').item.json.customerData.email }}\",\n \"name\": \"{{ $('Check Optimal Follow-up Timing').item.json.customerData.name }}\"\n },\n \"rating\": {{ $json.rating }},\n \"title\": \"{{ $json.generatedTestimonials.testimonials.medium.headline }}\",\n \"text\": \"{{ $json.platformFormats.trustpilot.content }}\",\n \"referenceId\": \"{{ $json.submissionId }}\"\n}",
"sendBody": true,
"sendHeaders": true,
"specifyBody": "json",
"headerParameters": {
"parameters": [
{
"name": "Authorization",
"value": "Bearer YOUR_TOKEN_HERE"
},
{
"name": "Content-Type",
"value": "application/json"
}
]
}
},
"typeVersion": 4.2,
"continueOnFail": true
},
{
"id": "8bd2a816-e376-4cb9-85d9-1e4f85dd8115",
"name": "Update CRM with Testimonial Status",
"type": "n8n-nodes-base.httpRequest",
"position": [
2528,
912
],
"parameters": {
"url": "=https://api.hubspot.com/crm/v3/objects/contacts/{{ $json.customerId }}",
"method": "PATCH",
"options": {
"timeout": 10000
},
"jsonBody": "={\n \"properties\": {\n \"testimonial_submitted\": \"true\",\n \"testimonial_rating\": {{ $json.rating }},\n \"testimonial_date\": \"{{ $json.metadata.submittedAt }}\",\n \"testimonial_text\": \"{{ $json.generatedTestimonials.testimonials.short.text }}\",\n \"last_review_score\": {{ $json.sentimentAnalysis.qualityScore }}\n }\n}",
"sendBody": true,
"sendHeaders": true,
"specifyBody": "json",
"headerParameters": {
"parameters": [
{
"name": "Authorization",
"value": "Bearer YOUR_TOKEN_HERE"
},
{
"name": "Content-Type",
"value": "application/json"
}
]
}
},
"typeVersion": 4.2,
"continueOnFail": true
},
{
"id": "011c030b-ab08-47f6-a559-8206d5831d61",
"name": "Send Thank You Email",
"type": "n8n-nodes-base.httpRequest",
"position": [
2752,
624
],
"parameters": {
"url": "https://api.sendgrid.com/v3/mail/send",
"method": "POST",
"options": {
"timeout": 10000
},
"jsonBody": "={\n \"personalizations\": [{\n \"to\": [{\"email\": \"{{ $('Check Optimal Follow-up Timing').item.json.customerData.email }}\"}],\n \"dynamic_template_data\": {\n \"customer_name\": \"{{ $('Check Optimal Follow-up Timing').item.json.customerData.name }}\",\n \"testimonial_used\": true\n }\n }],\n \"from\": {\"email\": \"thanks@yourcompany.com\"},\n \"template_id\": \"YOUR_THANKYOU_TEMPLATE_ID\"\n}",
"sendBody": true,
"sendHeaders": true,
"specifyBody": "json",
"headerParameters": {
"parameters": [
{
"name": "Authorization",
"value": "Bearer YOUR_TOKEN_HERE"
},
{
"name": "Content-Type",
"value": "application/json"
}
]
}
},
"typeVersion": 4.2,
"continueOnFail": true
},
{
"id": "350502d3-086e-42c7-a411-d6a55d4993cc",
"name": "Log to Analytics Dashboard",
"type": "n8n-nodes-base.httpRequest",
"position": [
2080,
912
],
"parameters": {
"url": "https://api.airtable.com/v0/YOUR_BASE_ID/Testimonials",
"method": "POST",
"options": {
"timeout": 10000
},
"jsonBody": "={\n \"fields\": {\n \"Submission ID\": \"{{ $json.submissionId }}\",\n \"Customer ID\": \"{{ $json.customerId }}\",\n \"Rating\": {{ $json.rating }},\n \"Sentiment\": \"{{ $json.sentimentAnalysis.sentiment }}\",\n \"Quality Score\": {{ $json.sentimentAnalysis.qualityScore }},\n \"Published\": {{ $json.publishReady }},\n \"Submitted At\": \"{{ $json.metadata.submittedAt }}\",\n \"Project Type\": \"{{ $json.projectType }}\",\n \"Short Version\": \"{{ $json.generatedTestimonials.testimonials.short.text }}\",\n \"Medium Version\": \"{{ $json.generatedTestimonials.testimonials.medium.text }}\"\n }\n}",
"sendBody": true,
"sendHeaders": true,
"specifyBody": "json",
"headerParameters": {
"parameters": [
{
"name": "Authorization",
"value": "Bearer YOUR_TOKEN_HERE"
},
{
"name": "Content-Type",
"value": "application/json"
}
]
}
},
"typeVersion": 4.2,
"continueOnFail": true
},
{
"id": "7699560e-1aab-4ab2-a3b6-8bd4e12197fb",
"name": "Return Success Response",
"type": "n8n-nodes-base.respondToWebhook",
"position": [
2976,
624
],
"parameters": {
"options": {
"responseHeaders": {
"entries": [
{
"name": "Content-Type",
"value": "application/json"
}
]
}
},
"respondWith": "json",
"responseBody": "={{ JSON.stringify({ success: true, message: 'Testimonial processed and published', submissionId: $json.submissionId }, null, 2) }}"
},
"typeVersion": 1
}
],
"active": false,
"settings": {
"executionOrder": "v1"
},
"versionId": "e1df2522-0633-40ae-aa47-74f7182dc375",
"connections": {
"Claude AI Model": {
"ai_languageModel": [
[
{
"node": "AI Sentiment & Quality Analysis",
"type": "ai_languageModel",
"index": 0
},
{
"node": "Generate Polished Testimonial with Claude",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Daily Batch Check": {
"main": [
[
{
"node": "Prepare Customer Context",
"type": "main",
"index": 0
}
]
]
},
"Send Thank You Email": {
"main": [
[
{
"node": "Return Success Response",
"type": "main",
"index": 0
}
]
]
},
"Submit to Trustpilot": {
"main": [
[
{
"node": "Send Thank You Email",
"type": "main",
"index": 0
}
]
]
},
"Parse Feedback Response": {
"main": [
[
{
"node": "AI Sentiment & Quality Analysis",
"type": "main",
"index": 0
},
{
"node": "Generate Polished Testimonial with Claude",
"type": "main",
"index": 0
}
]
]
},
"Prepare Customer Context": {
"main": [
[
{
"node": "Fetch Full Customer Profile from CRM",
"type": "main",
"index": 0
}
]
]
},
"Filter Ready for Follow-up": {
"main": [
[
{
"node": "Generate Personalized Feedback Form",
"type": "main",
"index": 0
},
{
"node": "Send Feedback Request Email",
"type": "main",
"index": 0
}
]
]
},
"Parse AI Generated Content": {
"main": [
[
{
"node": "Filter High-Quality Testimonials",
"type": "main",
"index": 0
},
{
"node": "Log to Analytics Dashboard",
"type": "main",
"index": 0
}
]
]
},
"Check Optimal Follow-up Timing": {
"main": [
[
{
"node": "Filter Ready for Follow-up",
"type": "main",
"index": 0
}
]
]
},
"Publish to Website (WordPress)": {
"main": [
[
{
"node": "Send Thank You Email",
"type": "main",
"index": 0
}
]
]
},
"AI Sentiment & Quality Analysis": {
"main": [
[
{
"node": "Parse AI Generated Content",
"type": "main",
"index": 0
}
]
]
},
"Format for Publishing Platforms": {
"main": [
[
{
"node": "Publish to Website (WordPress)",
"type": "main",
"index": 0
},
{
"node": "Submit to Trustpilot",
"type": "main",
"index": 0
},
{
"node": "Update CRM with Testimonial Status",
"type": "main",
"index": 0
}
]
]
},
"Filter High-Quality Testimonials": {
"main": [
[
{
"node": "Format for Publishing Platforms",
"type": "main",
"index": 0
}
]
]
},
"Update CRM with Testimonial Status": {
"main": [
[
{
"node": "Send Thank You Email",
"type": "main",
"index": 0
}
]
]
},
"Webhook - Form Submission Received": {
"main": [
[
{
"node": "Parse Feedback Response",
"type": "main",
"index": 0
}
]
]
},
"Fetch Full Customer Profile from CRM": {
"main": [
[
{
"node": "Check Optimal Follow-up Timing",
"type": "main",
"index": 0
}
]
]
},
"Webhook Trigger - Project Completion": {
"main": [
[
{
"node": "Prepare Customer Context",
"type": "main",
"index": 0
}
]
]
},
"Generate Polished Testimonial with Claude": {
"main": [
[
{
"node": "Parse AI Generated Content",
"type": "main",
"index": 0
}
]
]
}
}
}
Credentials you'll need
Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.
anthropicApi
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
This workflow automatically collects, processes, and publishes customer testimonials and reviews after project completion or purchase. It uses AI to generate polished testimonials from raw feedback and distributes them across your marketing channels. Trigger - Detects project…
Source: https://n8n.io/workflows/14916/ — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
⏺ 🚀 How it works
Lead Pipeline v3.0. Uses httpRequest, agent, lmChatAnthropic, toolThink. Webhook trigger; 77 nodes.
What if AI didn't just write content—but actually thought about how to write it? This n8n workflow revolutionizes content creation by deploying multiple specialized AI agents that handle every aspect
Fully automates your service order pipeline from incoming booking to supplier confirmation — with built-in SLA enforcement and automatic escalation if a supplier goes silent. 📥 Receives orders via web
Tired of grinding out YouTube content? This n8n workflow turns AI into your personal video factory—creating engaging, faceless shorts on autopilot. Perfect for creators, marketers, or side-hustlers lo