This workflow follows the Chainllm → Google Sheets 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 →
{
"updatedAt": "2026-05-22T15:01:05.882Z",
"createdAt": "2026-05-22T11:10:21.340Z",
"id": "WORKFLOW_ID",
"name": "Review Response Automation (Groq)",
"description": null,
"active": false,
"isArchived": false,
"nodes": [
{
"parameters": {
"httpMethod": "POST",
"path": "new-review",
"responseMode": "responseNode",
"options": {}
},
"id": "379e1057-01ce-40ce-9eba-3e05e16247e2",
"name": "New Review Webhook",
"type": "n8n-nodes-base.webhook",
"typeVersion": 2,
"position": [
-880,
128
]
},
{
"parameters": {
"jsCode": "const body = $input.item.json.body || $input.item.json;\nconst reviewText = body.review_text || body.reviewText || body.review || '';\nconst rating = parseInt(body.rating || body.stars || 3);\nconst reviewerName = body.reviewer_name || body.name || 'Customer';\nconst platform = body.platform || 'Google';\n\nlet sentiment = 'neutral';\nif (rating >= 4) sentiment = 'positive';\nif (rating <= 2) sentiment = 'negative';\n\nreturn [{ json: { reviewText, rating, reviewerName, platform, sentiment } }];"
},
"id": "2a5a1fc1-ccc2-46db-ac7c-80da1880cfe3",
"name": "Parse Review Data",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
-656,
128
]
},
{
"parameters": {
"promptType": "define",
"text": "=You are a professional customer relations manager. Write a response to this {{ $json.platform }} review.\n\nReviewer: {{ $json.reviewerName }}\nRating: {{ $json.rating }}/5 stars\nSentiment: {{ $json.sentiment }}\nReview: {{ $json.reviewText }}\n\nGuidelines:\n- For positive reviews (4-5 stars): Be warm, grateful, personal. Mention something specific from their review.\n- For neutral reviews (3 stars): Thank them, acknowledge feedback, show commitment to improvement.\n- For negative reviews (1-2 stars): Be empathetic, apologize sincerely, offer to resolve offline. Never be defensive.\n- Keep response under 100 words\n- Sound human, not corporate\n- End with invitation to return or contact us\n\nRespond with valid JSON only. No markdown, no backticks:\n{\n \"response\": \"the full response text\",\n \"tone\": \"positive|neutral|empathetic\",\n \"needs_followup\": true or false\n}"
},
"id": "d9de1849-e4d5-4afb-9a7a-008310af9f52",
"name": "Basic LLM Chain",
"type": "@n8n/n8n-nodes-langchain.chainLlm",
"typeVersion": 1.4,
"position": [
-496,
128
]
},
{
"parameters": {
"jsCode": "let raw = $input.item.json.text || $input.item.json.output || $input.item.json.response || '';\nraw = raw.replace(/\\\\n/g, '\\n').replace(/\\\\'/g, '\"');\ntry {\n const cleaned = raw.replace(/```json|```/g, '').trim();\n const parsed = JSON.parse(cleaned);\n const review = {\n reviewText: $('Parse Review Data').item.json.reviewText,\n rating: $('Parse Review Data').item.json.rating,\n reviewerName: $('Parse Review Data').item.json.reviewerName,\n platform: $('Parse Review Data').item.json.platform,\n sentiment: $('Parse Review Data').item.json.sentiment\n };\n return [{ json: { ...parsed, ...review } }];\n} catch(e) {\n return [{ json: { error: e.message, raw: raw.substring(0, 200) } }];\n}"
},
"id": "89b7bc05-fed6-4945-bf8c-8c5a3beabaa4",
"name": "Parse Response",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
-224,
128
]
},
{
"parameters": {
"operation": "appendOrUpdate",
"documentId": {
"__rl": true,
"value": "YOUR_GOOGLE_SHEET_ID",
"mode": "list",
"cachedResultName": "Review Response",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/YOUR_GOOGLE_SHEET_ID"
},
"sheetName": {
"__rl": true,
"value": "gid=0",
"mode": "list",
"cachedResultName": "Sheet1",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/YOUR_GOOGLE_SHEET_ID"
},
"columns": {
"mappingMode": "defineBelow",
"value": {
"Reviewer": "={{ $json.reviewerName }}",
"Platform": "={{ $json.platform }}",
"Rating": "={{ $json.rating }}",
"Review": "={{ $json.reviewText }}",
"Drafted Response": "={{ $json.response }}",
"Tone": "={{ $json.tone }}",
"Needs Followup": "={{ $json.needs_followup }}",
"Status": "Pending Approval",
"Date": "={{ $now }}"
},
"matchingColumns": [
"Reviewer"
],
"schema": [
{
"id": "Reviewer",
"displayName": "Reviewer",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true,
"removed": false
},
{
"id": "Platform",
"displayName": "Platform",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "Rating",
"displayName": "Rating",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "Review",
"displayName": "Review",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true,
"removed": false
},
{
"id": "Drafted Response",
"displayName": "Drafted Response",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "Tone",
"displayName": "Tone",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "Needs Followup",
"displayName": "Needs Followup",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "Status",
"displayName": "Status",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "Date",
"displayName": "Date",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
}
],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {}
},
"id": "e4929fd6-cedd-4ad2-9812-0669c2d074f8",
"name": "Save to Reviews Sheet",
"type": "n8n-nodes-base.googleSheets",
"typeVersion": 4.4,
"position": [
0,
0
],
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"select": "channel",
"channelId": {
"__rl": true,
"value": "#all-wara",
"mode": "name"
},
"text": "={{ ($json.rating >= 4 ? '\u2b50\u2b50\u2b50\u2b50\u2b50' : $json.rating === 3 ? '\u2b50\u2b50\u2b50' : '\u2b50') + ' *New ' + $json.platform + ' Review \u2014 ' + $json.rating + '/5 stars*\\n\\n*From:* ' + $json.reviewerName + '\\n*Review:* ' + $json.reviewText + '\\n\\n---\\n*\u270d\ufe0f Drafted Response:*\\n' + $json.response + '\\n\\n' + ($json.needs_followup ? '\u26a0\ufe0f *Needs personal followup*' : '\u2705 Ready to post') + '\\n\\n_Approve and post, or edit in Google Sheets_' }}",
"otherOptions": {}
},
"id": "67370bb3-128d-4562-86f2-965f10355ac0",
"name": "Send to Slack for Approval",
"type": "n8n-nodes-base.slack",
"typeVersion": 2.2,
"position": [
0,
240
],
"credentials": {
"slackApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"respondWith": "json",
"responseBody": "={{ JSON.stringify({ success: true, message: 'Review received and response drafted' }) }}",
"options": {}
},
"id": "8d75574b-4111-489c-8355-797e8b8228f8",
"name": "Webhook Response",
"type": "n8n-nodes-base.respondToWebhook",
"typeVersion": 1,
"position": [
0,
432
]
},
{
"parameters": {
"model": "llama-3.3-70b-versatile",
"options": {}
},
"type": "@n8n/n8n-nodes-langchain.lmChatGroq",
"typeVersion": 1,
"position": [
-496,
336
],
"id": "507e374c-bbb4-48b6-bab7-a40077ee97b0",
"name": "Groq Chat Model",
"credentials": {
"groqApi": {
"name": "<your credential>"
}
}
}
],
"connections": {
"New Review Webhook": {
"main": [
[
{
"node": "Parse Review Data",
"type": "main",
"index": 0
}
]
]
},
"Parse Review Data": {
"main": [
[
{
"node": "Basic LLM Chain",
"type": "main",
"index": 0
}
]
]
},
"Basic LLM Chain": {
"main": [
[
{
"node": "Parse Response",
"type": "main",
"index": 0
}
]
]
},
"Parse Response": {
"main": [
[
{
"node": "Save to Reviews Sheet",
"type": "main",
"index": 0
},
{
"node": "Send to Slack for Approval",
"type": "main",
"index": 0
},
{
"node": "Webhook Response",
"type": "main",
"index": 0
}
]
]
},
"Groq Chat Model": {
"ai_languageModel": [
[
{
"node": "Basic LLM Chain",
"type": "ai_languageModel",
"index": 0
}
]
]
}
},
"settings": {
"executionOrder": "v1",
"binaryMode": "separate"
},
"staticData": null,
"meta": {
"templateCredsSetupCompleted": true
},
"versionId": "a37ef9cd-f571-400a-aae4-34451b2ba1bd",
"activeVersionId": null,
"versionCounter": 22,
"triggerCount": 0,
"tags": [],
"shared": [
{
"updatedAt": "2026-05-22T11:10:21.346Z",
"createdAt": "2026-05-22T11:10:21.346Z",
"role": "workflow:owner",
"workflowId": "WORKFLOW_ID",
"projectId": "Iq1L14HqUAHCPUBu",
"project": {
"updatedAt": "2026-05-22T10:44:17.180Z",
"createdAt": "2026-05-22T10:43:17.263Z",
"id": "Iq1L14HqUAHCPUBu",
"name": "Hashir Wara <hasheralwara@gmail.com>",
"type": "personal",
"icon": null,
"description": null,
"creatorId": "ee0472ac-5224-40b4-a822-f71f776399c1"
}
}
],
"versionMetadata": {
"name": null,
"description": null
}
}
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.
googleSheetsOAuth2ApigroqApislackApi
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
Review Response Automation (Groq). Uses chainLlm, googleSheets, slack, lmChatGroq. Webhook trigger; 8 nodes.
Source: https://github.com/29hashir04/n8n-workflows/blob/main/Review_Response_Automation_Groq/workflow.json — 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.
Content Repurposing Pipeline (Groq). Uses googleSheets, slack, chainLlm, lmChatGroq. Scheduled trigger; 7 nodes.
Get notified when the International Space Station passes over your location - but only when you can actually see it! This workflow combines real-time ISS tracking with weather condition checks to send
This comprehensive N8N automation template revolutionizes content creation by delivering a complete end-to-end solution for AI-powered blog generation. Transform simple ideas into fully SEO-optimized,
Story Generation – Your idea is transformed into a narrative split into scenes using DeepSeek LLM. Visuals – Each scene is illustrated with AI images via Replicate, then animated into cinematic video
Ai Price Tracker. Uses scheduleTrigger, httpRequest, markdown, chainLlm. Scheduled trigger; 42 nodes.