AI triage for support emails
AI labels every support email (billing, bug, question) and routes it to the right place.
How it works
- Receive the new support email.
- Ask an AI model to classify it: billing, bug, how-to, or other, plus urgency.
- Apply the matching Gmail label.
- Post urgent or bug emails to the right Slack channel.
Diagram
Code
JavaScript used in the Code step — already included in the template below.
// Mode: Run Once for Each Item
// Create these labels in Gmail, then paste their IDs here (Gmail node → Label → Get Many).
const LABEL_IDS = {
billing: "Label_BILLING_ID",
bug: "Label_BUG_ID",
howto: "Label_HOWTO_ID",
other: "Label_OTHER_ID",
};
const email = $("New support email").item.json;
const match = $json.text.match(/\{[\s\S]*\}/);
const ai = match ? JSON.parse(match[0]) : { category: "other", urgent: false };
const category = LABEL_IDS[ai.category] ? ai.category : "other";
return {
json: {
id: email.id,
subject: email.subject,
from: email.from?.value?.[0]?.address,
category,
urgent: ai.urgent === true,
labelId: LABEL_IDS[category],
},
};Build it
Pick your tool — same automation, step by step.
Copy and paste straight into an n8n canvas (Ctrl+V), or download and use Import from File. Then connect your own credentials and replace every YOUR_… placeholder. AI steps use a Claude model node — swap it for OpenAI, Gemini or Ollama if you prefer.
Show code (228 lines)
{
"name": "AI triage for support emails (Flowngn)",
"nodes": [
{
"parameters": {
"content": "## AI triage for support emails\nAI labels every support email (billing, bug, question) and routes it to the right place.\n\n**Setup**\n1. Open each node and connect your own credentials.\n2. Replace every YOUR_… placeholder.\n3. Test once, then activate.\n\nFree template from Flowngn",
"height": 260,
"width": 340
},
"id": "292cf932-28a7-4103-a30e-aaa1f075d4b9",
"name": "Setup notes",
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
-420,
-60
]
},
{
"parameters": {
"pollTimes": {
"item": [
{
"mode": "everyMinute"
}
]
},
"simple": false,
"filters": {
"q": "to:support@yourcompany.com"
},
"options": {}
},
"id": "292cf932-28a7-4103-a30e-aaa1f075d4b9",
"name": "New support email",
"type": "n8n-nodes-base.gmailTrigger",
"typeVersion": 1.2,
"position": [
0,
0
]
},
{
"parameters": {
"promptType": "define",
"text": "=Classify this support email.\n\nSubject: {{ $json.subject }}\n\n{{ $json.text }}\n\nReply ONLY with JSON: {\"category\": \"billing\" | \"bug\" | \"howto\" | \"other\", \"urgent\": true | false}"
},
"id": "292cf932-28a7-4103-a30e-aaa1f075d4b9",
"name": "Classify email",
"type": "@n8n/n8n-nodes-langchain.chainLlm",
"typeVersion": 1.5,
"position": [
300,
0
]
},
{
"parameters": {
"model": {
"__rl": true,
"value": "claude-sonnet-5",
"mode": "list"
},
"options": {}
},
"id": "292cf932-28a7-4103-a30e-aaa1f075d4b9",
"name": "Claude model",
"type": "@n8n/n8n-nodes-langchain.lmChatAnthropic",
"typeVersion": 1.3,
"position": [
300,
220
]
},
{
"parameters": {
"jsCode": "// Mode: Run Once for Each Item\n// Create these labels in Gmail, then paste their IDs here (Gmail node → Label → Get Many).\nconst LABEL_IDS = {\n billing: \"Label_BILLING_ID\",\n bug: \"Label_BUG_ID\",\n howto: \"Label_HOWTO_ID\",\n other: \"Label_OTHER_ID\",\n};\n\nconst email = $(\"New support email\").item.json;\nconst match = $json.text.match(/\\{[\\s\\S]*\\}/);\nconst ai = match ? JSON.parse(match[0]) : { category: \"other\", urgent: false };\nconst category = LABEL_IDS[ai.category] ? ai.category : \"other\";\n\nreturn {\n json: {\n id: email.id,\n subject: email.subject,\n from: email.from?.value?.[0]?.address,\n category,\n urgent: ai.urgent === true,\n labelId: LABEL_IDS[category],\n },\n};",
"mode": "runOnceForEachItem"
},
"id": "292cf932-28a7-4103-a30e-aaa1f075d4b9",
"name": "Read category",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
600,
0
]
},
{
"parameters": {
"operation": "addLabels",
"messageId": "={{ $json.id }}",
"labelIds": "={{ [$json.labelId] }}"
},
"id": "292cf932-28a7-4103-a30e-aaa1f075d4b9",
"name": "Add Gmail label",
"type": "n8n-nodes-base.gmail",
"typeVersion": 2.1,
"position": [
900,
0
]
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "loose"
},
"conditions": [
{
"id": "c1",
"leftValue": "={{ $json.urgent || $json.category === 'bug' }}",
"rightValue": "",
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
}
}
],
"combinator": "and"
},
"options": {}
},
"id": "292cf932-28a7-4103-a30e-aaa1f075d4b9",
"name": "Urgent or bug?",
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
900,
220
]
},
{
"parameters": {
"select": "channel",
"channelId": {
"__rl": true,
"value": "#support",
"mode": "name"
},
"text": "=🚨 {{ $json.category.toUpperCase() }}{{ $json.urgent ? ' (urgent)' : '' }}: {{ $json.subject }}\nFrom: {{ $json.from }}",
"otherOptions": {}
},
"id": "292cf932-28a7-4103-a30e-aaa1f075d4b9",
"name": "Alert #support",
"type": "n8n-nodes-base.slack",
"typeVersion": 2.2,
"position": [
1200,
0
]
}
],
"connections": {
"New support email": {
"main": [
[
{
"node": "Classify email",
"type": "main",
"index": 0
}
]
]
},
"Classify email": {
"main": [
[
{
"node": "Read category",
"type": "main",
"index": 0
}
]
]
},
"Read category": {
"main": [
[
{
"node": "Add Gmail label",
"type": "main",
"index": 0
},
{
"node": "Urgent or bug?",
"type": "main",
"index": 0
}
]
]
},
"Urgent or bug?": {
"main": [
[
{
"node": "Alert #support",
"type": "main",
"index": 0
}
]
]
},
"Claude model": {
"ai_languageModel": [
[
{
"node": "Classify email",
"type": "ai_languageModel",
"index": 0
}
]
]
}
},
"pinData": {},
"settings": {
"executionOrder": "v1"
},
"meta": {
"templateCredsSetupCompleted": false
},
"tags": []
}In Make, create a new scenario and add these modules in order:
- Gmail › Watch Emails (search: to:support@yourcompany.com)
- Anthropic Claude › Create a Prompt (or OpenAI › Create a Completion)
- Tools › Set variable / Iterator + Array aggregator (same logic as the Code step)
- Gmail › Modify Email Labels (add)
- Filter on the next route: “Urgent or bug?”
- If yesSlack › Create a Message
- Every module run uses Make operations — the free plan includes a monthly quota.
- Make's built-in functions (map, sum, formatDate…) can replace most Code steps; for complex logic use a code module.
- Module and step names can differ slightly as Make and Zapier update their apps.
In Zapier, create a new Zap and add these steps in order:
- Gmail — New Email Matching Search (to:support@yourcompany.com)
- Anthropic (Claude) — Send Message (or ChatGPT — Conversation)
- Code by Zapier — Run JavaScript (paste the code from the Code section)
- Gmail — Add Label to Email
- Filter by Zapier: “Urgent or bug?”
- If yesSlack — Send Channel Message
- Zaps with more than two steps need a paid Zapier plan.
- Webhooks, Filters/Paths and Code by Zapier are premium features on some Zapier plans.
- Code by Zapier runs JavaScript: reuse the code shown above, reading inputs from inputData instead of $json.
- Module and step names can differ slightly as Make and Zapier update their apps.
Tips
- Start with labels only; let people review before any automatic replies.
Related flows
Translate foreign-language support emails
AI translates non-English support emails and posts the translation to Slack.
Catch unhappy customers from feedback forms
AI reads every feedback response and alerts you instantly when it's negative.
Google reviews → AI reply drafts + bad-review alerts
Every new Google review gets a suggested reply, and 1–3 star reviews alert your team instantly.