This workflow corresponds to n8n.io template #17591 — 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": "d9auSJk4V0QC94pD",
"meta": {
"builderVariant": "mcp",
"aiBuilderAssisted": true
},
"name": "Draft AI replies to incoming emails in Gmail",
"tags": [],
"nodes": [
{
"id": "af88a191-b8ee-41ad-b593-3179ecee1732",
"name": "Watch inbox for new emails",
"type": "n8n-nodes-base.gmailTrigger",
"position": [
-16,
176
],
"parameters": {
"simple": false,
"filters": {
"q": "-from:me -category:promotions -category:social"
},
"options": {},
"pollTimes": {
"item": [
{
"mode": "everyMinute"
}
]
}
},
"credentials": {
"gmailOAuth2": {
"name": "<your credential>"
}
},
"typeVersion": 1.4
},
{
"id": "2439e2e8-3449-405d-b8fd-a9c4a1c016f5",
"name": "Configuration",
"type": "n8n-nodes-base.set",
"position": [
224,
176
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "cfg-1",
"name": "classify_model",
"type": "string",
"value": "gpt-5-mini"
},
{
"id": "cfg-2",
"name": "generate_model",
"type": "string",
"value": "gpt-5.4"
},
{
"id": "cfg-3",
"name": "excluded_senders",
"type": "string",
"value": "noreply,no-reply,newsletter,notifications@,notification@"
},
{
"id": "cfg-4",
"name": "reply_greeting",
"type": "string",
"value": "Hello,"
},
{
"id": "cfg-5",
"name": "reply_signature",
"type": "string",
"value": "Best,"
},
{
"id": "cfg-6",
"name": "reply_tone",
"type": "string",
"value": "professional, warm and concise, business casual"
}
]
},
"includeOtherFields": true
},
"typeVersion": 3.4
},
{
"id": "78e66c3f-353d-4597-9d92-c86f1f6d640e",
"name": "Skip excluded senders",
"type": "n8n-nodes-base.if",
"position": [
448,
176
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 1,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "cond-excluded",
"operator": {
"type": "boolean",
"operation": "true"
},
"leftValue": "={{ ($json.excluded_senders || \"\").split(\",\").map(s => s.trim().toLowerCase()).filter(Boolean).some(e => (($json.headers && $json.headers.from) || \"\").toLowerCase().includes(e)) }}",
"rightValue": true
}
]
}
},
"typeVersion": 2.3
},
{
"id": "914f7518-b7c2-498c-9d3a-80389f6e496e",
"name": "Sender excluded - do nothing",
"type": "n8n-nodes-base.noOp",
"position": [
736,
0
],
"parameters": {},
"typeVersion": 1
},
{
"id": "13ec818b-95ca-48f9-9459-98e06aef33aa",
"name": "Classify if reply is needed",
"type": "@n8n/n8n-nodes-langchain.textClassifier",
"position": [
672,
304
],
"parameters": {
"options": {
"fallback": "other",
"enableAutoFixing": true
},
"inputText": "=Subject: {{ $('Watch inbox for new emails').item.json.subject }}\nFrom: {{ $('Watch inbox for new emails').item.json.headers.from }}\nMessage:\n{{ $('Watch inbox for new emails').item.json.textAsHtml }}",
"categories": {
"categories": [
{
"category": "needs_reply",
"description": "A genuine message from a person that requires a thoughtful, personalized reply: a question, a request, a business inquiry, or a personal message."
},
{
"category": "no_reply_needed",
"description": "An automated notification, a newsletter, a marketing email, or any message that does not require a personal response."
}
]
}
},
"typeVersion": 1.1
},
{
"id": "09afd1f9-e731-4d4d-b32c-6b60a1a12504",
"name": "Classification Model",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
"position": [
672,
512
],
"parameters": {
"model": {
"__rl": true,
"mode": "id",
"value": "={{ $('Configuration').item.json.classify_model }}"
},
"options": {},
"builtInTools": {}
},
"credentials": {
"openAiApi": {
"name": "<your credential>"
}
},
"typeVersion": 1.3
},
{
"id": "c32f2e68-9d09-479a-9ccc-5b460c66fdb8",
"name": "Generate email reply",
"type": "@n8n/n8n-nodes-langchain.chainLlm",
"position": [
1024,
48
],
"parameters": {
"text": "=Subject: {{ $('Watch inbox for new emails').item.json.subject }}\nFrom: {{ $('Watch inbox for new emails').item.json.headers.from }}\nMessage: {{ $('Watch inbox for new emails').item.json.textAsHtml }}",
"batching": {},
"messages": {
"messageValues": [
{
"message": "=You're a helpful personal assistant and your task is to draft replies on my behalf to my incoming emails. Whenever I provide text from an email, return an appropriate draft reply for it and nothing else.\nEnsure the reply is suitable for a professional setting and addresses the topic in a clear, structured way. Do not make things up.\n\nTone: {{ $('Configuration').item.json.reply_tone }}\n\nDetailed instructions:\n- Start with \"{{ $('Configuration').item.json.reply_greeting }}\", and end with \"{{ $('Configuration').item.json.reply_signature }}\"\n- When replying to yes-no questions, draft 2 responses: one affirmative and one negative, separated by \" - - - - - - - OR - - - - - - - \"\n- If you don't know an answer, you can leave placeholders like \"[YOUR_ANSWER_HERE]\".\n- Don't use any special formatting, only plain text.\n- Reply in the same language as the inbound email."
}
]
},
"promptType": "define"
},
"typeVersion": 1.9
},
{
"id": "bc810e6c-e705-4ccc-b7fb-1a16c5503892",
"name": "Reply Model",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
"position": [
1104,
272
],
"parameters": {
"model": {
"__rl": true,
"mode": "id",
"value": "={{ $('Configuration').item.json.generate_model }}"
},
"options": {},
"builtInTools": {}
},
"credentials": {
"openAiApi": {
"name": "<your credential>"
}
},
"typeVersion": 1.3
},
{
"id": "c18d079e-a9e6-48b0-847a-fe06014ca370",
"name": "Create Gmail draft reply",
"type": "n8n-nodes-base.gmail",
"position": [
1376,
144
],
"parameters": {
"message": "={{ $json.text.replace(/\\n/g, \"<br />\\n\") }}",
"options": {
"sendTo": "={{ $('Watch inbox for new emails').item.json.headers.from }}",
"threadId": "={{ $('Watch inbox for new emails').item.json.threadId }}"
},
"subject": "=Re: {{ $('Watch inbox for new emails').item.json.headers.subject }}",
"resource": "draft",
"emailType": "html"
},
"credentials": {
"gmailOAuth2": {
"name": "<your credential>"
}
},
"typeVersion": 2.2
},
{
"id": "99cb480f-ecae-4d14-af72-164d8da09db1",
"name": "No reply needed - do nothing",
"type": "n8n-nodes-base.noOp",
"position": [
1088,
448
],
"parameters": {},
"typeVersion": 1
},
{
"id": "a2a80b08-2422-4796-84b2-b7fc9c80c57b",
"name": "Sticky Note eaacec59",
"type": "n8n-nodes-base.stickyNote",
"position": [
-608,
-160
],
"parameters": {
"color": 4,
"width": 520,
"height": 1764,
"content": "# Draft AI replies to incoming emails in Gmail\n# \ud83d\udce5 [Open full documentation on Notion](https://automatisation.notion.site/Course-Draft-AI-replies-to-incoming-emails-in-Gmail-39e3d6550fd98101a034c6c1f305d24c)\n\n## How it works\nThis workflow watches your Gmail inbox, uses OpenAI to decide whether an incoming email actually needs a reply, and \u2014 only when it does \u2014 drafts a full response and saves it directly into the Gmail thread. You always review and send it yourself; nothing goes out automatically.\n\n1. Gmail Trigger polls your inbox for new messages.\n2. A Configuration node lets you set the OpenAI models, an excluded-senders list, and the tone/greeting/signature used in replies \u2014 no need to touch any other node.\n3. An IF node skips senders you've excluded (newsletters, no-reply addresses, etc.).\n4. A Text Classifier (OpenAI) decides needs_reply vs no_reply_needed.\n5. If a reply is needed, a Basic LLM Chain drafts the reply text, which is converted to HTML and saved as a Gmail draft, threaded under the original message.\n\n## Setup\n1. Connect your Gmail account (OAuth2) \u2014 see Requirements.\n2. Connect your OpenAI account.\n3. Open the Configuration node and adjust: classify_model, generate_model, excluded_senders, reply_greeting, reply_signature, reply_tone.\n4. Optionally edit the Gmail Trigger's search query (filters.q) directly on that node to narrow which emails trigger the workflow (this can't be centralized in Configuration since the trigger runs first).\n5. Activate the workflow.\n\n## Requirements\n- A Gmail account connected via OAuth2 (Gmail API, modify scope).\n- An OpenAI API key with access to GPT-5 family models.\n\n## Customization\n- Add more categories to the Text Classifier (e.g. urgent) and route them differently.\n- Add a Gmail label step after drafting to mark processed threads.\n- Tune excluded_senders to silence marketing/no-reply addresses.\n- Change reply_tone for a more casual or more formal voice.\n\nNeed help customizing?\nContact me for consulting and support : [Linkedin](https://www.linkedin.com/in/doctor-firass/)\n\n# MY NEW YOUTUBE CHANNEL\n\ud83d\udc49 [Subscribe to my new YouTube channel](https://www.youtube.com/@DrFiras_AI). Here I'll share videos and Shorts with practical tutorials and FREE templates for n8n.\n\n[](https://www.youtube.com/@DrFiras_AI)"
},
"typeVersion": 1
},
{
"id": "b1f7cbe2-94eb-4572-8336-5e8ed0fb368c",
"name": "Sticky Note 3da10442",
"type": "n8n-nodes-base.stickyNote",
"position": [
0,
496
],
"parameters": {
"color": 7,
"width": 300,
"height": 200,
"content": "### 1. Trigger\nWatches the inbox for new incoming emails."
},
"typeVersion": 1
},
{
"id": "a1a680d2-a58b-491e-9e75-0b337c347dc2",
"name": "Sticky Note 80157fd2",
"type": "n8n-nodes-base.stickyNote",
"position": [
112,
784
],
"parameters": {
"color": 7,
"width": 300,
"height": 200,
"content": "### 2. Configuration\nSingle place to set models, excluded senders, greeting/signature and tone."
},
"typeVersion": 1
},
{
"id": "da99628a-bbaf-4655-80f3-70f741f0a5c9",
"name": "Sticky Note af191ba8",
"type": "n8n-nodes-base.stickyNote",
"position": [
448,
784
],
"parameters": {
"color": 7,
"width": 300,
"height": 200,
"content": "### 3. Filter\nSkips senders you excluded (newsletters, no-reply, etc.)."
},
"typeVersion": 1
},
{
"id": "1e61bc7d-2d07-484b-8aea-9bd023593090",
"name": "Sticky Note 371595ef",
"type": "n8n-nodes-base.stickyNote",
"position": [
768,
784
],
"parameters": {
"color": 7,
"width": 300,
"height": 200,
"content": "### 4. Classify\nDecides with AI whether the email actually needs a reply."
},
"typeVersion": 1
},
{
"id": "a96f6197-c409-4c90-a2cc-eabd76e7a107",
"name": "Sticky Note 8fed7929",
"type": "n8n-nodes-base.stickyNote",
"position": [
1120,
784
],
"parameters": {
"color": 7,
"width": 300,
"height": 200,
"content": "### 5. Generate & draft\nWrites the reply and saves it as a Gmail draft in the original thread."
},
"typeVersion": 1
}
],
"active": true,
"settings": {
"binaryMode": "separate",
"availableInMCP": true,
"executionOrder": "v1"
},
"versionId": "af121715-f8d9-47f4-b551-e8676a39a805",
"nodeGroups": [],
"connections": {
"Reply Model": {
"ai_languageModel": [
[
{
"node": "Generate email reply",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Configuration": {
"main": [
[
{
"node": "Skip excluded senders",
"type": "main",
"index": 0
}
]
]
},
"Classification Model": {
"ai_languageModel": [
[
{
"node": "Classify if reply is needed",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Generate email reply": {
"main": [
[
{
"node": "Create Gmail draft reply",
"type": "main",
"index": 0
}
]
]
},
"Skip excluded senders": {
"main": [
[
{
"node": "Sender excluded - do nothing",
"type": "main",
"index": 0
}
],
[
{
"node": "Classify if reply is needed",
"type": "main",
"index": 0
}
]
]
},
"Watch inbox for new emails": {
"main": [
[
{
"node": "Configuration",
"type": "main",
"index": 0
}
]
]
},
"Classify if reply is needed": {
"main": [
[
{
"node": "Generate email reply",
"type": "main",
"index": 0
}
],
[
{
"node": "No reply needed - do nothing",
"type": "main",
"index": 0
}
],
[
{
"node": "No reply needed - do nothing",
"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.
gmailOAuth2openAiApi
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
This workflow monitors a Gmail inbox for new messages, filters out excluded senders, uses OpenAI to decide whether a reply is needed, and drafts a suggested response in the original Gmail thread for you to review and send. Triggers every minute by polling your Gmail inbox for…
Source: https://n8n.io/workflows/17591/ — 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.
AI Agents Vs AI Workflow. Uses lmChatOpenAi, gmailTrigger, gmail, gmailTool. Event-driven trigger; 30 nodes.
Template Nodes Example. Uses CUSTOM, formTrigger, executeWorkflowTrigger, chatTrigger. Event-driven trigger; 70 nodes.
Inbox Guardian. Uses gmailTrigger, lmChatOpenAi, agent, textClassifier. Event-driven trigger; 66 nodes.
This workflow automates document processing using LlamaParse to extract and analyze text from various file formats. It intelligently processes documents, extracts structured data, and delivers actiona
Email-Automation-Template. Uses lmChatAnthropic, microsoftOutlookTrigger, gmail, chainLlm. Event-driven trigger; 38 nodes.