This workflow corresponds to n8n.io template #10034 — we link there as the canonical source.
This workflow follows the Agent → 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 →
{
"id": "CCpAUiVj1gyJZJUw",
"meta": {
"templateCredsSetupCompleted": true
},
"name": "Code Review with Red-Marked Corrections in Spreadsheet",
"tags": [],
"nodes": [
{
"id": "4af3c4b2-b7ad-407f-8ead-8509bde98b71",
"name": "\u30b3\u30fc\u30c9\u5165\u529b\u30b7\u30fc\u30c8\u76e3\u8996",
"type": "n8n-nodes-base.googleSheetsTrigger",
"position": [
-624,
0
],
"parameters": {
"options": {},
"pollTimes": {
"item": [
{
"mode": "everyMinute"
}
]
},
"sheetName": {
"__rl": true,
"mode": "list",
"value": "<YOUR_SHEET_GID_OR_NAME>",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1ABYuKFtVf1qgXa8S8yDNOKu7yCuDQzKPZQ-oufhsTJY/edit#gid=0",
"cachedResultName": "\u5bfe\u8c61\u30b3\u30fc\u30c9"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "<YOUR_SPREADSHEET_ID>",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1ABYuKFtVf1qgXa8S8yDNOKu7yCuDQzKPZQ-oufhsTJY/edit?usp=drivesdk",
"cachedResultName": "\u30b3\u30fc\u30c9\u30ec\u30d3\u30e5\u30fc"
}
},
"typeVersion": 1
},
{
"id": "47c973ae-f613-4a3c-ba53-0166e9a617a0",
"name": "\u30ec\u30d3\u30e5\u30fc\u7d50\u679c\u6574\u5f62",
"type": "n8n-nodes-base.set",
"position": [
464,
0
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "id-1",
"name": "reviewedCode",
"type": "string",
"value": "={{ $json.output }}"
},
{
"id": "id-2",
"name": "originalCode",
"type": "string",
"value": "={{ $('\u30b3\u30fc\u30c9\u5165\u529b\u30b7\u30fc\u30c8\u76e3\u8996').item.json.code }}"
},
{
"id": "id-3",
"name": "timestamp",
"type": "string",
"value": "={{ $now.toISO() }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "2bab7e4b-daab-4a05-83bd-2b60465077e9",
"name": "\u30ec\u30d3\u30e5\u30fc\u7d50\u679c\u66f8\u304d\u8fbc\u307f",
"type": "n8n-nodes-base.googleSheets",
"position": [
608,
0
],
"parameters": {
"columns": {
"value": {},
"schema": [],
"mappingMode": "defineBelow",
"matchingColumns": [],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {},
"operation": "appendOrUpdate",
"sheetName": {
"__rl": true,
"mode": "list",
"value": "<YOUR_SHEET_GID_OR_NAME>",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1ABYuKFtVf1qgXa8S8yDNOKu7yCuDQzKPZQ-oufhsTJY/edit#gid=1115979776",
"cachedResultName": "\u30ec\u30d3\u30e5\u30fc\u7d50\u679c"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "<YOUR_SPREADSHEET_ID>",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1ABYuKFtVf1qgXa8S8yDNOKu7yCuDQzKPZQ-oufhsTJY/edit?usp=drivesdk",
"cachedResultName": "\u30b3\u30fc\u30c9\u30ec\u30d3\u30e5\u30fc"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.7
},
{
"id": "b6dda288-7b1b-41a0-9e88-f8cadc6499b6",
"name": "AI Agent",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
-176,
0
],
"parameters": {
"text": "=Lint summary (consider in review):\n{{ JSON.stringify($('Lint Check').first().json.lintErrors) }}\n\nLint score: {{ $('Lint Check').first().json.lintScore }} / 10\n\n=\u3042\u306a\u305f\u306f\u30b3\u30fc\u30c9\u30ec\u30d3\u30e5\u30fc\u306e\u5c02\u9580\u5bb6\u3067\u3059\u3002\u4ee5\u4e0b\u306e\u30b3\u30fc\u30c9\u3092\u30ec\u30d3\u30e5\u30fc\u3057\u3001\u4fee\u6b63\u304c\u5fc5\u8981\u306a\u7b87\u6240\u3092\u8d64\u5b57\u3067\u793a\u3057\u3066\u304f\u3060\u3055\u3044\u3002\u5143\u306e\u30b3\u30fc\u30c9\u306b\u5bfe\u3057\u3066\u3001\u4fee\u6b63\u6848\u3092\u8d64\u5b57\uff08HTML\u306e<span style=\"color:red\">\u30bf\u30b0\uff09\u3067\u8ffd\u8a18\u3057\u305f\u5f62\u5f0f\u3067\u51fa\u529b\u3057\u3066\u304f\u3060\u3055\u3044\u3002\n\n{{ $json.reviewPrompt }}\n\n\u30b3\u30fc\u30c9:\n{{ $('\u30b3\u30fc\u30c9\u5165\u529b\u30b7\u30fc\u30c8\u76e3\u8996').item.json.code }}\n\n\u3010Review Rules\u3011\n- Classify issues as Critical / Major / Minor\n- Use <span style=\"color:red\">red</span> for critical fixes; <span style=\"color:orange\">orange</span> for minor suggestions\n- Append JSON at end: {\"overall_score\": <0-10 number>}\n",
"options": {},
"promptType": "define"
},
"typeVersion": 2.2
},
{
"id": "05ee83db-4b56-43ee-b153-3ba224393f88",
"name": "Google Gemini Chat Model",
"type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
"position": [
-176,
224
],
"parameters": {
"options": {}
},
"typeVersion": 1
},
{
"id": "a4fd65ae-4f56-4b3a-be8c-29d2a0b171f8",
"name": "Get row(s) in sheet in Google Sheets",
"type": "n8n-nodes-base.googleSheetsTool",
"position": [
-32,
224
],
"parameters": {
"options": {},
"sheetName": {
"__rl": true,
"mode": "list",
"value": "<YOUR_SHEET_GID_OR_NAME>",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1ABYuKFtVf1qgXa8S8yDNOKu7yCuDQzKPZQ-oufhsTJY/edit#gid=2003594084",
"cachedResultName": "\u30b3\u30fc\u30c9\u898f\u7d04"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "<YOUR_SPREADSHEET_ID>",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1ABYuKFtVf1qgXa8S8yDNOKu7yCuDQzKPZQ-oufhsTJY/edit?usp=drivesdk",
"cachedResultName": "\u30b3\u30fc\u30c9\u30ec\u30d3\u30e5\u30fc"
},
"authentication": "serviceAccount",
"descriptionType": "manual",
"toolDescription": "\u8a18\u8f09\u3055\u308c\u308b\u5185\u5bb9\u3092\u3082\u3068\u306b\u30ec\u30d3\u30e5\u30fc"
},
"typeVersion": 4.7
},
{
"id": "27a24123-0992-4af0-98f4-d37148cb6b5d",
"name": "Sheet Trigger Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
-688,
-128
],
"parameters": {
"content": "Monitors the 'Input Code' sheet for new or edited rows to start the review process automatically."
},
"typeVersion": 1
},
{
"id": "11e67e60-aaf1-49f0-a53c-93c9efde194d",
"name": "AI Review Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
-448,
-128
],
"parameters": {
"content": "Sends the submitted code to the connected AI model (e.g., Gemini or GPT) for detailed review and feedback."
},
"typeVersion": 1
},
{
"id": "e81e15e9-55fa-46c4-b4d1-4304b6bb975c",
"name": "Formatting Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
-192,
-128
],
"parameters": {
"content": "Formats AI\u2019s review response \u2014 adds red-colored text for corrections and clear comments for improvements."
},
"typeVersion": 1
},
{
"id": "d2569a9f-fa2c-4979-9137-a4182b425528",
"name": "Write Output Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
176,
-128
],
"parameters": {
"width": 528,
"content": "Writes the reviewed and corrected code output into the 'Review Results' sheet for easy comparison."
},
"typeVersion": 1
},
{
"id": "6cb8265d-a2a8-4542-80b6-358181a239ee",
"name": "Lint Check",
"type": "n8n-nodes-base.function",
"position": [
-400,
0
],
"parameters": {
"functionCode": "const code = $('\u30b3\u30fc\u30c9\u5165\u529b\u30b7\u30fc\u30c8\u76e3\u8996').item.json.code || '';\nconst errors = [];\nif (code.includes('var ')) errors.push({type:'Major', msg:'Avoid var; use let/const.'});\nif (code.includes('console.log')) errors.push({type:'Minor', msg:'Remove console.log in production.'});\nconst open = (code.match(/\\{/g)||[]).length;\nconst close = (code.match(/\\}/g)||[]).length;\nif (open !== close) errors.push({type:'Critical', msg:`Brace imbalance: {=${open}} }=${close}`});\nconst score = Math.max(0, 10 - errors.length * 2);\nreturn [{ json: { code, lintErrors: errors, lintScore: score }}];\n"
},
"typeVersion": 1
},
{
"id": "8850c4ee-5296-4a3c-aaca-d6bd9d4bdde2",
"name": "Format Review Output",
"type": "n8n-nodes-base.function",
"position": [
176,
0
],
"parameters": {
"functionCode": "const out = $json.output || '';\nconst lint = $('Lint Check').first().json || {};\nconst errors = lint.lintErrors || [];\nconst counts = { Critical:0, Major:0, Minor:0 };\nerrors.forEach(e=>{ if (counts[e.type]!==undefined) counts[e.type]++; });\nlet overall = Number((lint.lintScore || 0));\nconst m = out.match(/\\{\\\"overall_score\\\"\\s*:\\s*([0-9.]+)\\}/);\nif (m) overall = (overall + Number(m[1]))/2;\nreturn [{ json: { reviewed: out, lintSummary: counts, lintScore: lint.lintScore||0, overallScore: Number(overall.toFixed(2)) } }];\n"
},
"typeVersion": 1
},
{
"id": "a04d8968-8941-440f-bce7-21f42eca1771",
"name": "Aggregate Review Stats",
"type": "n8n-nodes-base.function",
"position": [
320,
0
],
"parameters": {
"functionCode": "const s = $json.lintSummary || {Critical:0, Major:0, Minor:0};\nconst overall = $json.overallScore || 0;\nreturn [{ json: { summary: s, overall, summaryText: `Critical:${s.Critical} Major:${s.Major} Minor:${s.Minor} / Score:${overall}` } }];\n"
},
"typeVersion": 1
},
{
"id": "80ece42d-3536-4880-9a12-b745204e40b0",
"name": "Post Review Summary",
"type": "n8n-nodes-base.slack",
"position": [
832,
0
],
"parameters": {
"text": "={{ `\u2705 Code Review Completed\\n${$json.summaryText}` }}",
"select": "channel",
"channelId": {
"__rl": true,
"mode": "list",
"value": "<YOUR_SLACK_CHANNEL_ID>",
"cachedResultName": "code-reviews"
},
"otherOptions": {},
"authentication": "oAuth2"
},
"typeVersion": 2.3
},
{
"id": "9eb4292c-e03e-4e00-bbf5-8d6b19fb78e2",
"name": "Template Overview (Advanced)",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1264,
-368
],
"parameters": {
"width": 520,
"height": 1120,
"content": "## Advanced Code Review Automation (AI + Lint + Slack)\n\n### Who\u2019s it for\nFor software engineers, QA teams, and tech leads who want to **automate intelligent code reviews** with both AI-driven suggestions and rule-based linting \u2014 all managed in Google Sheets with instant Slack summaries.\n\n### How it works\nThis workflow performs a two-layer review system:\n1. **Lint Check**: Runs a lightweight static analysis to find common issues (e.g., use of `var`, `console.log`, unbalanced braces).\n2. **AI Review**: Sends valid code to Gemini AI, which provides human-like review feedback with severity classification (`Critical`, `Major`, `Minor`) and visual highlights (red/orange tags).\n3. **Formatter**: Combines lint and AI results, calculating an overall score (0\u201310).\n4. **Aggregator**: Summarizes results for quick comparison.\n5. **Google Sheets Writer**: Appends results to your review log.\n6. **Slack Notification**: Posts a concise summary (e.g., number of issues and average score) to your team\u2019s channel.\n\n### How to set up\n1. Connect **Google Sheets** and **Slack** credentials in n8n.\n2. Replace placeholders (`<YOUR_SPREADSHEET_ID>`, `<YOUR_SHEET_GID_OR_NAME>`, `<YOUR_SLACK_CHANNEL_ID>`).\n3. Adjust the AI review prompt or lint rules as needed.\n4. Activate the workflow \u2014 reviews will start automatically whenever new code is added to the sheet.\n\n### Requirements\n- Google Sheets and Slack integrations enabled\n- A configured AI node (Gemini, OpenAI, or compatible)\n- Proper permissions to write to your target Google Sheet\n\n### How to customize\n- Add more linting rules (naming conventions, spacing, forbidden APIs)\n- Extend the AI prompt for project-specific guidelines\n- Customize the Slack message formatting\n- Export analytics to a dashboard (e.g., Notion or Data Studio)\n\n### Why it\u2019s valuable\nThis workflow brings **realistic, team-oriented AI-assisted code review** to n8n \u2014 combining the speed of automated linting with the nuance of human-style feedback. It saves time, improves code quality, and keeps your team\u2019s review history transparent and centralized."
},
"typeVersion": 1
},
{
"id": "3198d5f4-06c1-43a4-8e88-a76c9c67eff9",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
96,
176
],
"parameters": {
"content": "Add coding conventions and design documents as tools."
},
"typeVersion": 1
}
],
"active": false,
"settings": {
"executionOrder": "v1"
},
"versionId": "64769cf0-2122-4615-a487-6ea7fc3dc2b1",
"connections": {
"AI Agent": {
"main": [
[
{
"node": "Format Review Output",
"type": "main",
"index": 0
}
]
]
},
"Lint Check": {
"main": [
[
{
"node": "AI Agent",
"type": "main",
"index": 0
}
]
]
},
"Format Review Output": {
"main": [
[
{
"node": "Aggregate Review Stats",
"type": "main",
"index": 0
}
]
]
},
"Aggregate Review Stats": {
"main": [
[
{
"node": "\u30ec\u30d3\u30e5\u30fc\u7d50\u679c\u6574\u5f62",
"type": "main",
"index": 0
}
]
]
},
"Google Gemini Chat Model": {
"ai_languageModel": [
[
{
"node": "AI Agent",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"\u30ec\u30d3\u30e5\u30fc\u7d50\u679c\u6574\u5f62": {
"main": [
[
{
"node": "\u30ec\u30d3\u30e5\u30fc\u7d50\u679c\u66f8\u304d\u8fbc\u307f",
"type": "main",
"index": 0
}
]
]
},
"\u30b3\u30fc\u30c9\u5165\u529b\u30b7\u30fc\u30c8\u76e3\u8996": {
"main": [
[
{
"node": "Lint Check",
"type": "main",
"index": 0
}
]
]
},
"\u30ec\u30d3\u30e5\u30fc\u7d50\u679c\u66f8\u304d\u8fbc\u307f": {
"main": [
[
{
"node": "Post Review Summary",
"type": "main",
"index": 0
}
]
]
},
"Get row(s) in sheet in Google Sheets": {
"ai_tool": [
[
{
"node": "AI Agent",
"type": "ai_tool",
"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.
googleSheetsOAuth2Api
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
For software engineers, QA teams, and tech leads who want to automate intelligent code reviews with both AI-driven suggestions and rule-based linting — all managed in Google Sheets with instant Slack summaries.
Source: https://n8n.io/workflows/10034/ — 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.
This automation is designed to help you generate AI-powered music tracks, cover art, and fully rendered music videos — all triggered from a simple Telegram chat and managed via Google Sheets.
WhatsApp AI Assistant for Clinic Appointment Booking Automate your entire appointment lifecycle with an intelligent AI assistant that lives on WhatsApp. This workflow empowers any clinic or independen
How it works:
Customer support agent. Uses httpRequest, googleSheets, memoryBufferWindow, googleSheetsTool. Event-driven trigger; 19 nodes.
This n8n workflow automates the transition from raw financial trade data to professional client communication. It monitors a Google Sheet for portfolio changes, uses Gemini AI to draft a personalized,