This workflow corresponds to n8n.io template #15955 — 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": "yUxR8qHi03y6NCZH",
"name": "AI Support Ticket Classifier and Auto-Reply Agent using Claude and Gmail",
"tags": [],
"nodes": [
{
"id": "a6187e62-8b16-4547-8c46-da66e4edfde6",
"name": "Overview",
"type": "n8n-nodes-base.stickyNote",
"position": [
0,
0
],
"parameters": {
"color": 0,
"width": 400,
"height": 964,
"content": "## AI Support Ticket Classifier and Auto-Reply Agent\n\nAutomates first-response to customer support emails. Claude classifies every ticket, drafts a reply, and routes based on urgency.\n\n### How it works\n\n1. Gmail Trigger polls your inbox every minute for new unread emails.\n2. Configure Settings holds all user-editable values in one place.\n3. Build Prompt formats the email subject, sender, and body into a structured Claude instruction.\n4. Classify with Claude returns category, priority, sentiment, a summary, a draft reply, and an internal note.\n5. Parse Output extracts those fields and adds a timestamp.\n6. Route by Priority branches urgent tickets to a Gmail draft and Slack alert, sends auto-replies to normal tickets, and logs low tickets without replying.\n7. Every branch ends with a Google Sheets log row for full reporting.\n\n### Setup steps\n\n- [x] **Gmail credentials** - Connect your Google account in the Gmail Trigger and both Gmail action nodes.\n- [ ] **Anthropic credentials** - Add your Anthropic API key to the Claude Sonnet Model node.\n- [ ] **Slack credentials** - Connect your Slack workspace in the Alert Support Team node.\n- [ ] **Google Sheets credentials** - Connect your Google account in all three log nodes.\n- [ ] **Sheet ID** - Replace YOUR_GOOGLE_SHEET_ID in Configure Settings.\n- [ ] **Slack channel** - Replace YOUR_SLACK_CHANNEL_ID in Configure Settings.\n- [ ] **Support email** - Replace YOUR_SUPPORT_EMAIL in Configure Settings.\n- [ ] **Activate** - Turn the workflow on when all credentials are saved.\n\n### Customization\n\nEdit the categories list in Build Prompt to match your industry. Adjust MAX_EMAIL_CHARS in Configure Settings to control how much of the email body Claude reads."
},
"typeVersion": 1
},
{
"id": "cc0905a4-a234-475d-8ddf-4793f7d56592",
"name": "Trigger Section",
"type": "n8n-nodes-base.stickyNote",
"position": [
448,
112
],
"parameters": {
"color": 7,
"width": 476,
"height": 280,
"content": "## Inbox trigger and settings\n\nGmail polls for new unread emails once per minute. Configure Settings holds every value the user needs to edit so no other node requires changes."
},
"typeVersion": 1
},
{
"id": "f4e2c7df-224c-400f-8167-052adda5a84f",
"name": "Gmail Trigger",
"type": "n8n-nodes-base.gmailTrigger",
"position": [
480,
240
],
"parameters": {
"simple": false,
"filters": {
"q": "is:unread",
"labelIds": [
"INBOX"
]
},
"options": {},
"pollTimes": {
"item": [
{
"mode": "everyMinute"
}
]
}
},
"typeVersion": 1
},
{
"id": "0db7829f-b16a-47b6-b150-95799f12668d",
"name": "Configure Settings",
"type": "n8n-nodes-base.code",
"position": [
720,
240
],
"parameters": {
"jsCode": "// Edit all user settings here. Do not edit any other node.\nconst settings = {\n SLACK_CHANNEL_ID: 'YOUR_SLACK_CHANNEL_ID',\n GOOGLE_SHEET_ID: 'YOUR_GOOGLE_SHEET_ID',\n SUPPORT_EMAIL: 'YOUR_SUPPORT_EMAIL',\n SHEET_NAME: 'Support Tickets',\n MAX_EMAIL_CHARS: 2000\n};\n\nreturn items.map(function(item) {\n return { json: Object.assign({}, item.json, { settings: settings }) };\n});"
},
"typeVersion": 2
},
{
"id": "d310566a-2f59-4b34-9fb2-11c92a9d960c",
"name": "AI Analysis Section",
"type": "n8n-nodes-base.stickyNote",
"position": [
960,
112
],
"parameters": {
"color": 7,
"width": 640,
"height": 472,
"content": "## Claude AI analysis\n\nBuild Prompt assembles the email into a structured instruction. Claude returns a JSON object with category, priority, sentiment, summary, draft reply, and internal note. Parse Output extracts those fields for routing."
},
"typeVersion": 1
},
{
"id": "93de7cd9-d817-4ebc-a886-153222af6b05",
"name": "Build Prompt",
"type": "n8n-nodes-base.code",
"position": [
992,
240
],
"parameters": {
"jsCode": "var item = items[0].json;\nvar settings = item.settings;\nvar subject = item.subject || 'No subject';\nvar fromVal = item.from;\nvar fromEmail = '';\nif (fromVal && fromVal.value && fromVal.value.length > 0) {\n fromEmail = fromVal.value[0].address || '';\n} else if (typeof fromVal === 'string') {\n fromEmail = fromVal;\n}\nvar rawBody = item.text || item.snippet || '';\nvar bodyTruncated = rawBody.length > settings.MAX_EMAIL_CHARS ? rawBody.slice(0, settings.MAX_EMAIL_CHARS) : rawBody;\n\nvar prompt = 'You are a customer support AI agent. Read the email below and respond ONLY with a valid JSON object, no other text before or after it.\\n\\n' +\n 'FROM: ' + fromEmail + '\\n' +\n 'SUBJECT: ' + subject + '\\n' +\n 'BODY:\\n' + bodyTruncated + '\\n\\n' +\n 'Return exactly this JSON structure:\\n' +\n '{\"category\":\"one of billing, technical, general, refund, or complaint\",' +\n '\"priority\":\"one of urgent, normal, or low\",' +\n '\"sentiment\":\"one of frustrated, neutral, or positive\",' +\n '\"summary\":\"one sentence describing the issue\",' +\n '\"draft_reply\":\"professional plain text reply to send to the customer, no HTML, no greetings with first name placeholders\",' +\n '\"internal_note\":\"brief plain text note for the support team on how to handle this\"}';\n\nreturn [{ json: Object.assign({}, item, {\n prompt: prompt,\n fromEmail: fromEmail,\n emailSubject: subject\n}) }];"
},
"typeVersion": 2
},
{
"id": "4a6a6821-530f-468f-8be5-21ccb2b60686",
"name": "Classify with Claude",
"type": "@n8n/n8n-nodes-langchain.chainLlm",
"position": [
1232,
240
],
"parameters": {},
"typeVersion": 1.4
},
{
"id": "bd22479b-c6ae-4368-bdc5-43d01935f44c",
"name": "Claude Sonnet Model",
"type": "@n8n/n8n-nodes-langchain.lmChatAnthropic",
"position": [
1232,
448
],
"parameters": {
"model": "claude-sonnet-4-6",
"options": {
"temperature": 0.2
}
},
"typeVersion": 1.2
},
{
"id": "890c58b0-70fb-4d40-b189-c7b76638a8d5",
"name": "Parse Output",
"type": "n8n-nodes-base.code",
"position": [
1472,
240
],
"parameters": {
"jsCode": "var item = items[0].json;\nvar rawText = item.text || '';\nvar parsed = {};\n\ntry {\n var match = rawText.match(/\\{[\\s\\S]*\\}/);\n if (match) {\n parsed = JSON.parse(match[0]);\n }\n} catch (e) {\n parsed = {\n category: 'general',\n priority: 'normal',\n sentiment: 'neutral',\n summary: 'Could not parse AI response. Manual review needed.',\n draft_reply: 'Thank you for contacting us. A member of our team will be in touch shortly.',\n internal_note: 'AI parsing failed on this ticket. Please review manually.'\n };\n}\n\nvar now = new Date();\nvar processedAt = now.toISOString();\n\nreturn [{ json: Object.assign({}, item, {\n priority: parsed.priority || 'normal',\n category: parsed.category || 'general',\n sentiment: parsed.sentiment || 'neutral',\n summary: parsed.summary || '',\n draft_reply: parsed.draft_reply || '',\n internal_note: parsed.internal_note || '',\n processedAt: processedAt,\n replySubject: 'Re: ' + (item.emailSubject || 'Your support request')\n}) }];"
},
"typeVersion": 2
},
{
"id": "469c35ce-5e1a-4dd5-aa2e-0ad6bdd2205c",
"name": "Routing Section",
"type": "n8n-nodes-base.stickyNote",
"position": [
1632,
48
],
"parameters": {
"color": 7,
"width": 1196,
"height": 584,
"content": "## Priority routing\n\nUrgent tickets create a Gmail draft and fire a Slack alert so your team can review and send. Normal tickets get an auto-reply immediately. Low-priority tickets are logged only. All three branches end at Google Sheets."
},
"typeVersion": 1
},
{
"id": "7e39d4c8-6924-4f3a-a127-8e2a64b133f5",
"name": "Route by Priority",
"type": "n8n-nodes-base.switch",
"position": [
1680,
240
],
"parameters": {
"rules": {
"values": [
{
"conditions": {
"options": {
"version": 1,
"leftValue": "",
"caseSensitive": false,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "cond-urgent-01",
"operator": {
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.priority }}",
"rightValue": "urgent"
}
]
}
},
{
"conditions": {
"options": {
"version": 1,
"leftValue": "",
"caseSensitive": false,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "cond-normal-01",
"operator": {
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.priority }}",
"rightValue": "normal"
}
]
}
}
]
},
"options": {}
},
"typeVersion": 3
},
{
"id": "86071f81-5546-48df-b302-b9042e6ca392",
"name": "Create Gmail Draft",
"type": "n8n-nodes-base.gmail",
"position": [
1920,
144
],
"parameters": {
"message": "={{ $json.draft_reply }}",
"options": {},
"subject": "={{ $json.replySubject }}",
"resource": "draft"
},
"typeVersion": 2.1
},
{
"id": "1bc4f6ec-792b-4e03-a9f6-d2a348d85408",
"name": "Prepare Slack Alert",
"type": "n8n-nodes-base.code",
"position": [
2144,
144
],
"parameters": {
"jsCode": "var item = items[0].json;\nvar msg = 'URGENT support ticket received\\n' +\n 'From: ' + (item.fromEmail || 'unknown') + '\\n' +\n 'Subject: ' + (item.emailSubject || 'n/a') + '\\n' +\n 'Category: ' + (item.category || 'n/a') + '\\n' +\n 'Sentiment: ' + (item.sentiment || 'n/a') + '\\n' +\n 'Summary: ' + (item.summary || 'n/a') + '\\n' +\n 'Internal note: ' + (item.internal_note || 'n/a') + '\\n' +\n 'A draft reply has been created in Gmail. Review and send.';\nreturn [{ json: Object.assign({}, item, { slackMessage: msg }) }];"
},
"typeVersion": 2
},
{
"id": "431f55e7-b294-4956-a167-8b51c4ba128d",
"name": "Alert Support Team",
"type": "n8n-nodes-base.slack",
"position": [
2368,
144
],
"parameters": {
"text": "={{ $json.slackMessage }}",
"select": "channel",
"channelId": {
"__rl": true,
"mode": "id",
"value": "={{ $json.settings.SLACK_CHANNEL_ID }}"
},
"otherOptions": {}
},
"typeVersion": 2.2
},
{
"id": "4256cfe5-742e-4e6c-b292-0cc533d819fb",
"name": "Log Urgent Ticket",
"type": "n8n-nodes-base.googleSheets",
"position": [
2592,
144
],
"parameters": {
"columns": {
"value": {
"From": "={{ $json.fromEmail }}",
"Status": "Draft Created - Slack Sent",
"Subject": "={{ $json.emailSubject }}",
"Summary": "={{ $json.summary }}",
"Category": "={{ $json.category }}",
"Priority": "={{ $json.priority }}",
"Sentiment": "={{ $json.sentiment }}",
"Timestamp": "={{ $json.processedAt }}",
"Internal Note": "={{ $json.internal_note }}"
},
"mappingMode": "defineBelow"
},
"options": {},
"operation": "append",
"sheetName": {
"__rl": true,
"mode": "name",
"value": "={{ $json.settings.SHEET_NAME }}"
},
"documentId": {
"__rl": true,
"mode": "id",
"value": "={{ $json.settings.GOOGLE_SHEET_ID }}"
}
},
"typeVersion": 4.4
},
{
"id": "89539b8c-8073-48af-88e1-b7272c38d38b",
"name": "Send Auto-Reply",
"type": "n8n-nodes-base.gmail",
"position": [
1920,
304
],
"parameters": {
"message": "={{ $json.draft_reply }}",
"options": {},
"subject": "={{ $json.replySubject }}",
"emailType": "text"
},
"typeVersion": 2.1
},
{
"id": "c2c9d2af-295f-425c-a173-11ed6a0eccd6",
"name": "Log Normal Ticket",
"type": "n8n-nodes-base.googleSheets",
"position": [
2144,
304
],
"parameters": {
"columns": {
"value": {
"From": "={{ $json.fromEmail }}",
"Status": "Auto-Reply Sent",
"Subject": "={{ $json.emailSubject }}",
"Summary": "={{ $json.summary }}",
"Category": "={{ $json.category }}",
"Priority": "={{ $json.priority }}",
"Sentiment": "={{ $json.sentiment }}",
"Timestamp": "={{ $json.processedAt }}",
"Internal Note": "={{ $json.internal_note }}"
},
"mappingMode": "defineBelow"
},
"options": {},
"operation": "append",
"sheetName": {
"__rl": true,
"mode": "name",
"value": "={{ $json.settings.SHEET_NAME }}"
},
"documentId": {
"__rl": true,
"mode": "id",
"value": "={{ $json.settings.GOOGLE_SHEET_ID }}"
}
},
"typeVersion": 4.4
},
{
"id": "6ef3aa7d-d115-43a4-8e2b-cc56ac633e0f",
"name": "Log Low Priority Ticket",
"type": "n8n-nodes-base.googleSheets",
"position": [
1920,
464
],
"parameters": {
"columns": {
"value": {
"From": "={{ $json.fromEmail }}",
"Status": "Logged - No Reply",
"Subject": "={{ $json.emailSubject }}",
"Summary": "={{ $json.summary }}",
"Category": "={{ $json.category }}",
"Priority": "={{ $json.priority }}",
"Sentiment": "={{ $json.sentiment }}",
"Timestamp": "={{ $json.processedAt }}",
"Internal Note": "={{ $json.internal_note }}"
},
"mappingMode": "defineBelow"
},
"options": {},
"operation": "append",
"sheetName": {
"__rl": true,
"mode": "name",
"value": "={{ $json.settings.SHEET_NAME }}"
},
"documentId": {
"__rl": true,
"mode": "id",
"value": "={{ $json.settings.GOOGLE_SHEET_ID }}"
}
},
"typeVersion": 4.4
}
],
"active": false,
"settings": {
"binaryMode": "separate",
"executionOrder": "v1"
},
"versionId": "c76a3b46-b630-4a7a-9f6c-5947a158c1ca",
"connections": {
"Build Prompt": {
"main": [
[
{
"node": "Classify with Claude",
"type": "main",
"index": 0
}
]
]
},
"Parse Output": {
"main": [
[
{
"node": "Route by Priority",
"type": "main",
"index": 0
}
]
]
},
"Gmail Trigger": {
"main": [
[
{
"node": "Configure Settings",
"type": "main",
"index": 0
}
]
]
},
"Send Auto-Reply": {
"main": [
[
{
"node": "Log Normal Ticket",
"type": "main",
"index": 0
}
]
]
},
"Route by Priority": {
"main": [
[
{
"node": "Create Gmail Draft",
"type": "main",
"index": 0
}
],
[
{
"node": "Send Auto-Reply",
"type": "main",
"index": 0
}
]
]
},
"Alert Support Team": {
"main": [
[
{
"node": "Log Urgent Ticket",
"type": "main",
"index": 0
}
]
]
},
"Configure Settings": {
"main": [
[
{
"node": "Build Prompt",
"type": "main",
"index": 0
}
]
]
},
"Create Gmail Draft": {
"main": [
[
{
"node": "Prepare Slack Alert",
"type": "main",
"index": 0
}
]
]
},
"Claude Sonnet Model": {
"ai_languageModel": [
[
{
"node": "Classify with Claude",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Prepare Slack Alert": {
"main": [
[
{
"node": "Alert Support Team",
"type": "main",
"index": 0
}
]
]
},
"Classify with Claude": {
"main": [
[
{
"node": "Parse Output",
"type": "main",
"index": 0
}
]
]
}
}
}
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 unread support emails, uses Anthropic Claude to classify and draft replies, routes urgent tickets to Slack and a Gmail draft, auto-replies to normal tickets, and logs all tickets to Google Sheets for reporting. Triggers every minute when…
Source: https://n8n.io/workflows/15955/ — 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.
Your inbox shouldn't run your day. This workflow checks Gmail every 15 minutes, uses Claude AI to classify every new email into Urgent, Needs Reply, FYI Only, Automated, or Spam — then takes the right
Stop spending 20 minutes writing each Upwork proposal from scratch. This workflow reads your Vollna job alert emails, scores every job against your skills and budget preferences, and uses Claude to wr
This workflow polls Gmail every 15 minutes for unread invoice or receipt emails, uses Anthropic Claude (Sonnet) to extract key financial fields, logs new documents to Google Sheets, sends optional Sla
Stop wasting time on leads that will never convert. This workflow scores every inbound form submission 1-10 using Claude AI, then automatically replies and routes based on fit — hot leads get an insta
This workflow monitors a Google Sheets patient intake log, uses Anthropic Claude to decide the right follow-up action and draft an email, sends the message via Gmail, optionally notifies a clinic mana