This workflow corresponds to n8n.io template #17655 — we link there as the canonical source.
This workflow follows the Chainllm → Gmail 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": "OEsHJOC68AkpHCYh",
"meta": {
"builderVariant": "mcp",
"aiBuilderAssisted": true
},
"name": "Draft support replies with Gemini and approve them in Slack before they send",
"tags": [],
"nodes": [
{
"id": "d2e57422-83e8-4f09-9634-d576353eb699",
"name": "Fetch Support Emails",
"type": "n8n-nodes-base.gmailTrigger",
"position": [
48,
48
],
"parameters": {
"simple": false,
"filters": {
"q": "label:support",
"readStatus": "unread"
},
"options": {},
"pollTimes": {
"item": [
{
"mode": "everyMinute"
}
]
}
},
"credentials": {
"gmailOAuth2": {
"name": "<your credential>"
}
},
"typeVersion": 1.4
},
{
"id": "1adac840-be5a-43d1-af69-dc61d55e8d88",
"name": "Draft Reply with Gemini",
"type": "@n8n/n8n-nodes-langchain.chainLlm",
"onError": "continueRegularOutput",
"position": [
272,
48
],
"parameters": {
"text": "=You are a helpful, friendly customer support agent. Read the email and draft a reply the customer would be happy to receive. Be concise and warm. Return a one-line summary and the full suggested reply.\n\nFrom: {{ $json.from }}\nSubject: {{ $json.subject }}\nBody:\n{{ $json.text }}",
"batching": {},
"promptType": "define",
"hasOutputParser": true
},
"typeVersion": 1.9
},
{
"id": "ee5c22b3-6d92-4e67-804e-1e6b59a18cd7",
"name": "Google Gemini Chat Model",
"type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
"position": [
224,
224
],
"parameters": {
"options": {
"temperature": 0.3
},
"modelName": "models/gemini-3.1-flash-lite"
},
"credentials": {
"googlePalmApi": {
"name": "<your credential>"
}
},
"typeVersion": 1.1
},
{
"id": "5bcd7d01-a925-475d-8509-707e6f07e5f5",
"name": "Draft Parser",
"type": "@n8n/n8n-nodes-langchain.outputParserStructured",
"position": [
448,
224
],
"parameters": {
"jsonSchemaExample": "{\"summary\":\"Customer asks how to get a refund\",\"suggested_reply\":\"Hi, thanks for reaching out. To request a refund...\"}"
},
"typeVersion": 1.3
},
{
"id": "544afb4c-effa-44f0-8db9-c16891db5e82",
"name": "Shape Draft",
"type": "n8n-nodes-base.code",
"position": [
624,
48
],
"parameters": {
"mode": "runOnceForEachItem",
"jsCode": "const e = $('Fetch Support Emails').item.json;\nconst d = $json.output || {};\nreturn { from: e.from, subject: e.subject, threadId: e.threadId, messageId: e.id, summary: d.summary || '', reply: d.suggested_reply || 'Thank you for your message, we will get back to you shortly.' };"
},
"typeVersion": 2
},
{
"id": "1fcb0a2d-bc24-447f-91e8-823a8c390f3a",
"name": "Ask for Approval",
"type": "n8n-nodes-base.slack",
"position": [
848,
48
],
"parameters": {
"select": "channel",
"message": "=*Approve this support reply?*\n\n*To:* {{ $json.from }}\n*Subject:* Re: {{ $json.subject }}\n\n{{ $json.reply }}",
"options": {
"limitWaitTime": {
"values": {
"resumeAmount": 6
}
}
},
"channelId": {
"__rl": true,
"mode": "list",
"value": "",
"cachedResultName": "#support-approvals"
},
"operation": "sendAndWait",
"authentication": "oAuth2",
"approvalOptions": {
"values": {
"approvalType": "double",
"approveLabel": "Send it",
"disapproveLabel": "Discard"
}
}
},
"credentials": {
"slackOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 2.5
},
{
"id": "abd1f540-8a58-4e4a-90e7-44c52c7cc3c8",
"name": "Approved?",
"type": "n8n-nodes-base.if",
"position": [
1104,
48
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 1,
"leftValue": "",
"caseSensitive": false,
"typeValidation": "loose"
},
"combinator": "and",
"conditions": [
{
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
},
"leftValue": "={{ $json.data.approved }}"
}
]
}
},
"typeVersion": 2.2
},
{
"id": "76ceabd0-6d1f-4344-8f62-1c0a73e45f9a",
"name": "Send Approved Reply",
"type": "n8n-nodes-base.gmail",
"position": [
1360,
32
],
"parameters": {
"sendTo": "={{ $(\"Shape Draft\").item.json.from }}",
"message": "={{ $(\"Shape Draft\").item.json.reply }}",
"options": {},
"subject": "={{ \"Re: \" + $(\"Shape Draft\").item.json.subject }}",
"emailType": "text"
},
"credentials": {
"gmailOAuth2": {
"name": "<your credential>"
}
},
"typeVersion": 2.2
},
{
"id": "288d6270-da50-46c9-8394-6bbf5f1475ce",
"name": "Log Sent",
"type": "n8n-nodes-base.googleSheets",
"position": [
1584,
32
],
"parameters": {
"operation": "append",
"sheetName": {
"__rl": true,
"mode": "list",
"value": "",
"cachedResultName": "Replies"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "",
"cachedResultName": "Select your spreadsheet"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.7
},
{
"id": "f3a9f2de-48ca-445e-a2b6-20aefd0bfa96",
"name": "Log Declined",
"type": "n8n-nodes-base.googleSheets",
"position": [
1360,
208
],
"parameters": {
"operation": "append",
"sheetName": {
"__rl": true,
"mode": "list",
"value": "",
"cachedResultName": "Replies"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "",
"cachedResultName": "Select your spreadsheet"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.7
},
{
"id": "a153509f-9cad-4ab2-9717-49c75c59afe0",
"name": "Overview Sticky",
"type": "n8n-nodes-base.stickyNote",
"position": [
-544,
-112
],
"parameters": {
"width": 520,
"height": 716,
"content": "## Draft support replies with Gemini and approve them in Slack before they send\n\n### How it works\nThis is a human-in-the-loop workflow: the AI drafts, but a person always approves before anything leaves your outbox. When a new support email arrives, a Basic LLM Chain with Google Gemini drafts a warm, on-brand reply. Instead of sending it, the Slack node posts the draft with Send it / Discard buttons and pauses the workflow until someone clicks. If approved, the reply is sent from Gmail in the original thread and logged as Sent; if discarded, nothing is sent and it is logged as Discarded. The wait times out after a few hours so nothing hangs forever.\n\n### Setup\n1. Connect Gmail, Google Gemini (PaLM) API, Google Sheets and Slack.\n2. Choose the Slack channel that should receive approval requests.\n3. Point the log node at your spreadsheet (tab: Replies).\n\n### Customization tips\nSwap Slack approval for email approval, or auto-send low-risk replies and only ask for approval on refunds."
},
"typeVersion": 1
},
{
"id": "d84f0957-4a36-49a0-b552-994e3a62a6ab",
"name": "S1",
"type": "n8n-nodes-base.stickyNote",
"position": [
0,
-112
],
"parameters": {
"color": 7,
"width": 740,
"height": 524,
"content": "## 1. Draft (Basic LLM Chain)\nGemini drafts a reply to each new support email but does not send it."
},
"typeVersion": 1
},
{
"id": "f0abbb05-18d4-46fa-b30f-ecfd98ae682d",
"name": "S2",
"type": "n8n-nodes-base.stickyNote",
"position": [
768,
-112
],
"parameters": {
"color": 7,
"width": 464,
"height": 524,
"content": "## 2. Human approval in Slack\nThe draft is posted to Slack with Send it / Discard buttons. The workflow pauses until someone clicks."
},
"typeVersion": 1
},
{
"id": "c12d360c-55cf-448a-aa15-e0588de35c81",
"name": "S3",
"type": "n8n-nodes-base.stickyNote",
"position": [
1248,
-112
],
"parameters": {
"color": 7,
"width": 640,
"height": 516,
"content": "## 3. Send or discard\nApproved replies are sent in the original Gmail thread and logged as Sent; discarded ones are logged and never sent."
},
"typeVersion": 1
}
],
"active": false,
"settings": {
"binaryMode": "separate",
"availableInMCP": true,
"executionOrder": "v1"
},
"versionId": "e6a45f6d-b141-4a85-b117-edafaf04496d",
"nodeGroups": [],
"connections": {
"Approved?": {
"main": [
[
{
"node": "Send Approved Reply",
"type": "main",
"index": 0
}
],
[
{
"node": "Log Declined",
"type": "main",
"index": 0
}
]
]
},
"Shape Draft": {
"main": [
[
{
"node": "Ask for Approval",
"type": "main",
"index": 0
}
]
]
},
"Draft Parser": {
"ai_outputParser": [
[
{
"node": "Draft Reply with Gemini",
"type": "ai_outputParser",
"index": 0
}
]
]
},
"Ask for Approval": {
"main": [
[
{
"node": "Approved?",
"type": "main",
"index": 0
}
]
]
},
"Send Approved Reply": {
"main": [
[
{
"node": "Log Sent",
"type": "main",
"index": 0
}
]
]
},
"Fetch Support Emails": {
"main": [
[
{
"node": "Draft Reply with Gemini",
"type": "main",
"index": 0
}
]
]
},
"Draft Reply with Gemini": {
"main": [
[
{
"node": "Shape Draft",
"type": "main",
"index": 0
}
]
]
},
"Google Gemini Chat Model": {
"ai_languageModel": [
[
{
"node": "Draft Reply with Gemini",
"type": "ai_languageModel",
"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.
gmailOAuth2googlePalmApigoogleSheetsOAuth2ApislackOAuth2Api
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
This workflow polls Gmail for unread emails labeled “support”, uses Google Gemini to draft a concise reply, and posts it to Slack for human approval; approved drafts are sent via Gmail and logged to Google Sheets, while discarded drafts are logged without sending. Checks Gmail…
Source: https://n8n.io/workflows/17655/ — 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 workflow runs daily to send Gemini-generated cold emails from leads stored in Google Sheets via Gmail, schedules two follow-ups based on time since sending, and continuously monitors Gmail for re
Automate your lead intake, scoring, and outreach pipeline. This workflow collects leads from forms, enriches and scores them using Relevance AI, routes them by quality, and triggers the right follow-u
This workflow creates a sophisticated, self-improving customer support system that automatically handles incoming emails. It's designed to answer common questions using an AI-powered knowledge base an
Perfect for use cases such as: 💼 Finance teams managing vendor invoices 📊 Bookkeeping workflows 🔄 Automating monthly reconciliation
This workflow monitors Gmail for unread invoice emails with PDF attachments, extracts invoice details with Google Gemini, verifies Japanese qualified invoice registration numbers against the National