Skip to content

Instantly share code, notes, and snippets.

@Neel738
Last active December 3, 2025 05:33
Show Gist options
  • Select an option

  • Save Neel738/e377ea0a03420609603a8e6a301a519d to your computer and use it in GitHub Desktop.

Select an option

Save Neel738/e377ea0a03420609603a8e6a301a519d to your computer and use it in GitHub Desktop.
using n8n to auto-categorise incoming emails (read the red sticky note man)
{
"nodes": [
{
"parameters": {
"text": "=# Email Text\n## Subject\n {{ $json.Subject }}\n\n## From\n{{ $json.From }}\n\n## Body\n{{ $json.snippet }}\n\n# Instructions\nPlease reply in JSON. No MD Json, but just json, your response must be EXCLUSIVELY JSON. Please include all categories. If not applicable, score a 0. \n\nALL SCORES ARE BETWEEN 0-1 ( WHERE 0 is not at all , and 1 is extremely so). Beware of scammers trying to 'convince' you its urgent. Really try to score between 0 and 1 , (float) \n\n",
"schemaType": "fromJson",
"jsonSchemaExample": "{\n \"categories\": {\n\n \"Business/Collaboration Inquiries\": {\n \"Paid Partnerships/Endorsements\": 0.95,\n \"Press/Media Requests\": 0.85,\n \"Event Invitations\": 0.70,\n \"Contractual/Legal\": 0.50\n },\n \"Fan Messages\": {\n \"Praise/Appreciation\": 0.90,\n \"Personal Stories\": 0.80,\n \"Requests for Interaction\": 0.60,\n \"Gift/Donation Offers\": 0.40\n },\n \"Support/Assistance Requests\": {\n \"Customer Support\": 0.75,\n \"Charity/Donation Requests\": 0.65,\n \"Constituent/Casework\": 0.55\n },\n \"Personal/Private\": {\n \"Family/Friends\": 0.95,\n \"VIP/Important Contacts\": 0.88\n },\n \"Security/Threat\": {\n \"Harassment/Hate/Threatening\": 0.10,\n \"Suspicious Links or Attachments\": 0.05\n },\n \"Spam/Low Relevance\": {\n \"Promotional/Cold Outreach\": 0.20,\n \"Phishing or Scams\": 0.15\n },\n \"Other\": {\n \"Undefined/Need Review\": 0.50\n }\n },\n\n \"topics\": [\n \"brand\",\n \"sponsorship\",\n \"media\",\n \"event\",\n \"legal\",\n \"fan\",\n \"support\",\n \"charity\",\n \"vip\",\n \"threat\"\n ],\n\n \"spamScore\": 0.2,\n\n \"isUrgent\": false,\n\n \"urgencyScore\": 0.3\n}\n",
"options": {}
},
"type": "@n8n/n8n-nodes-langchain.informationExtractor",
"typeVersion": 1,
"position": [
240,
900
],
"id": "ee9ee65d-0066-4222-a0a6-55b7b0276e63",
"name": "Information Extractor"
},
{
"parameters": {
"model": {
"__rl": true,
"value": "gpt-4o",
"mode": "list",
"cachedResultName": "gpt-4o"
},
"options": {
"temperature": 0
}
},
"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
"typeVersion": 1.2,
"position": [
328,
1120
],
"id": "2d1bc608-7b46-46b7-9b6d-c6baed577b17",
"name": "OpenAI Chat Model",
"credentials": {
"openAiApi": {
"id": "6vic5A0Eh7SAbK6v",
"name": "OpenAi account"
}
}
},
{
"parameters": {
"batchSize": "=1",
"options": {
"reset": false
}
},
"type": "n8n-nodes-base.splitInBatches",
"typeVersion": 3,
"position": [
836,
700
],
"id": "f152e15f-1b6d-445d-a766-09c36e1fceab",
"name": "Loop Over Items"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "1ee7ead4-4932-486a-a9a6-3ea63f67c301",
"leftValue": "={{ $json.value }}",
"rightValue": 0,
"operator": {
"type": "number",
"operation": "gt"
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
1060,
700
],
"id": "58f864ca-8aad-4a09-99a9-6d461e11d21f",
"name": "If"
},
{
"parameters": {
"assignments": {
"assignments": []
},
"includeOtherFields": true,
"include": "except",
"excludeFields": "output.categories",
"options": {}
},
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [
1276,
1000
],
"id": "8538c826-6fa9-4a6d-ac26-049272e936ca",
"name": "Edit Fields"
},
{
"parameters": {
"rules": {
"values": [
{
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"leftValue": "={{ $json.output.isUrgent }}",
"rightValue": "",
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
},
"id": "0a60b17f-0962-447f-9cb6-e8fcd19cb574"
}
],
"combinator": "and"
},
"renameOutput": true,
"outputKey": "Is Urgent"
},
{
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "03e78a72-2b5c-4915-96f4-136df52730fc",
"leftValue": "={{ $json.output.spamScore }}",
"rightValue": 0.3,
"operator": {
"type": "number",
"operation": "gt"
}
}
],
"combinator": "and"
},
"renameOutput": true,
"outputKey": "Is Spam"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.switch",
"typeVersion": 3.2,
"position": [
1500,
1000
],
"id": "40685576-95ab-4493-82c2-62a9fd9dd43c",
"name": "Switch"
},
{
"parameters": {
"operation": "addLabels",
"messageId": "={{ $item(\"0\").$node[\"Find Message By Id\"].json[\"id\"] }}",
"labelIds": "={{ $('Find Corresponding Id').item.json.id }}"
},
"type": "n8n-nodes-base.gmail",
"typeVersion": 2.1,
"position": [
1720,
700
],
"id": "d5d480a2-a118-42f1-adf9-45f3c83d58b1",
"name": "Gmail",
"webhookId": "19c7126a-2eec-4a98-8ef6-82d6bf55be34",
"credentials": {
"gmailOAuth2": {
"id": "NMwVt8LMXRlbkWvB",
"name": "Gmail account"
}
}
},
{
"parameters": {},
"type": "n8n-nodes-base.manualTrigger",
"typeVersion": 1,
"position": [
-420,
180
],
"id": "ab11f22a-b806-4cf9-b643-b00aec2b1db3",
"name": "When clicking ‘Test workflow’"
},
{
"parameters": {
"resource": "label"
},
"type": "n8n-nodes-base.gmail",
"typeVersion": 2.1,
"position": [
-200,
180
],
"id": "1f5d3ede-a176-428e-a3f4-9c1312ab8fed",
"name": "Gmail1",
"webhookId": "238032fc-63bc-446d-bcff-b04e200ed216",
"credentials": {
"gmailOAuth2": {
"id": "NMwVt8LMXRlbkWvB",
"name": "Gmail account"
}
}
},
{
"parameters": {
"jsCode": "// Static reference schema (leaf nodes)\nconst schema = {\n \"Business/Collaboration Inquiries\": {\n \"Paid Partnerships/Endorsements\": 0.95,\n \"Press/Media Requests\": 0.85,\n \"Event Invitations\": 0.70,\n \"Contractual/Legal\": 0.50\n },\n \"Fan Messages\": {\n \"Praise/Appreciation\": 0.90,\n \"Personal Stories\": 0.80,\n \"Requests for Interaction\": 0.60,\n \"Gift/Donation Offers\": 0.40\n },\n \"Support/Assistance Requests\": {\n \"Customer Support\": 0.75,\n \"Charity/Donation Requests\": 0.65,\n \"Constituent/Casework\": 0.55\n },\n \"Personal/Private\": {\n \"Family/Friends\": 0.95,\n \"VIP/Important Contacts\": 0.88\n },\n \"Security/Threat\": {\n \"Harassment/Hate/Threatening\": 0.10,\n \"Suspicious Links or Attachments\": 0.05\n },\n \"Spam/Low Relevance\": {\n \"Promotional/Cold Outreach\": 0.20,\n \"Phishing or Scams\": 0.15\n },\n \"Other\": {\n \"Undefined/Need Review\": 0.50\n },\n \"Urgent\" : {\n \"Really Urgent\" : 0.01\n }\n};\n\n// Step 1: Extract all leaf labels from the schema\nconst allLeafLabels = [];\nfor (const parent in schema) {\n for (const child in schema[parent]) {\n allLeafLabels.push(child);\n }\n}\n\n// Step 2: Flatten all existing labels from input array\nconst incomingItems = $input.all(); // n8n's input\n\nconst foundLabels = new Set();\n\nfor (const item of incomingItems) {\n if (item.json.name) {\n if (allLeafLabels.includes(item.json.name)) {\n foundLabels.add(item.json.name)\n }\n }\n }\n \n\n\n// Step 3: Find missing labels\nconst missingLabels = allLeafLabels.filter(label => !foundLabels.has(label));\n\n// Output\nreturn missingLabels.map(x => ({ label: x, value: false }));\n"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
20,
180
],
"id": "a180bba5-759c-4bfd-9955-b6bde9873511",
"name": "Find missing labels"
},
{
"parameters": {
"options": {}
},
"type": "n8n-nodes-base.splitInBatches",
"typeVersion": 3,
"position": [
240,
180
],
"id": "1d0f4e04-6a8f-4063-924b-942f9484716c",
"name": "Loop Over Items1"
},
{
"parameters": {
"resource": "label",
"operation": "create",
"name": "={{ $json.label }}",
"options": {}
},
"type": "n8n-nodes-base.gmail",
"typeVersion": 2.1,
"position": [
460,
180
],
"id": "e028dfa9-f500-470a-b4d9-d5625284a55f",
"name": "Gmail2",
"webhookId": "806e81f1-bf0a-4671-ba81-0e0f3f2e30b2",
"credentials": {
"gmailOAuth2": {
"id": "NMwVt8LMXRlbkWvB",
"name": "Gmail account"
}
}
},
{
"parameters": {
"resource": "label",
"returnAll": true
},
"type": "n8n-nodes-base.gmail",
"typeVersion": 2.1,
"position": [
1280,
700
],
"id": "79d1cc57-9ac7-4f7e-89ec-f30077bf3522",
"name": "Get All Labels",
"webhookId": "f722e5ee-11d9-46b6-9875-f3ead675e489",
"credentials": {
"gmailOAuth2": {
"id": "NMwVt8LMXRlbkWvB",
"name": "Gmail account"
}
}
},
{
"parameters": {},
"type": "n8n-nodes-base.noOp",
"typeVersion": 1,
"position": [
1716,
1100
],
"id": "7e174b93-458a-45ac-8fee-c24ede9c7478",
"name": "No Operation, do nothing"
},
{
"parameters": {
"from": "+12334556788",
"to": "+12334556788",
"message": "=Yo, important email: {{ $('Find Message By Id').item.json.Subject }}",
"options": {}
},
"type": "n8n-nodes-base.sms77",
"typeVersion": 1,
"position": [
1720,
900
],
"id": "0dcbd3f3-334d-4e60-a72e-c5164bed13b5",
"name": "seven",
"credentials": {
"sms77Api": {
"id": "mEBUumnUwEAaOBKJ",
"name": "seven account"
}
}
},
{
"parameters": {
"jsCode": "function flattenObject(obj, parentKey = '') {\n const result = {};\n\n for (const key in obj) {\n if (!obj.hasOwnProperty(key)) continue;\n const newKey = parentKey ? `${parentKey}.${key}` : key;\n const value = obj[key];\n\n // Recursively handle nested objects\n if (value && typeof value === 'object' && !Array.isArray(value)) {\n Object.assign(result, flattenObject(value, newKey));\n } else if (Array.isArray(value)) {\n // Handle arrays with bracket notation\n value.forEach((item, index) => {\n if (item && typeof item === 'object' && !Array.isArray(item)) {\n Object.assign(result, flattenObject(item, `${newKey}[${index}]`));\n } else {\n result[`${newKey}[${index}]`] = item;\n }\n });\n } else {\n // Base case\n result[newKey] = value;\n }\n }\n\n return result;\n}\n\n// Grab the 'output' object from the first node in n8n\nconst data = $input.first().json.output;\n\n// Flatten the object (or the first object in an array)\nlet flattened;\nif (Array.isArray(data)) {\n flattened = flattenObject(data[0] || {});\n} else {\n flattened = flattenObject(data);\n}\n\n// Filter to include only keys that start with 'categories'\nconst filteredEntries = Object.entries(flattened).filter(([key]) => key.startsWith('categories'));\n\n// Return one n8n item per { key, value } in the filtered object\nconst outputItems = filteredEntries.map(([key, value]) => ({\n json: { key, value },\n}));\n\nreturn outputItems;\n"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
620,
700
],
"id": "1b316d0e-03f8-4a62-86ab-88705bfdd98c",
"name": "Flatten our schema"
},
{
"parameters": {
"jsCode": "function getIdByLabelName(labelList, targetName) {\n const match = labelList.find(label => label.json.name === targetName);\n return match ? match.json.id : -1;\n}\n\nconst allLabels = $(\"Get All Labels\").all()\nconst key = $('If').first().json.key\nconst dots = key.split(\".\")\nconst label = dots[dots.length-1]\nconst id = getIdByLabelName(allLabels, label)\nreturn {\n json : {\n key: label,\n value: key,\n id: id,\n }\n}"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1500,
700
],
"id": "a261c536-04f1-4afd-a13f-5f28b8abb131",
"name": "Find Corresponding Id"
},
{
"parameters": {
"content": "# Step 1: Set up the labels\n\n",
"height": 480,
"width": 1300
},
"type": "n8n-nodes-base.stickyNote",
"position": [
-640,
120
],
"typeVersion": 1,
"id": "3a8d3eb1-a1b1-45af-91b7-7a2b1be2be32",
"name": "Sticky Note"
},
{
"parameters": {
"content": "# Step 2: Enjoy",
"height": 660,
"width": 2880,
"color": 5
},
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
-640,
600
],
"id": "b099139a-8ddb-4846-a28c-7ace30fdba30",
"name": "Sticky Note1"
},
{
"parameters": {
"pollTimes": {
"item": [
{
"mode": "everyMinute"
}
]
},
"filters": {}
},
"type": "n8n-nodes-base.gmailTrigger",
"typeVersion": 1.2,
"position": [
-420,
720
],
"id": "c41745a2-8726-4817-b2f0-e1950331f145",
"name": "Gmail Trigger1",
"credentials": {
"gmailOAuth2": {
"id": "NMwVt8LMXRlbkWvB",
"name": "Gmail account"
}
}
},
{
"parameters": {
"operation": "append",
"documentId": {
"__rl": true,
"value": "1VaV2nX516U-h3kjPKROyERUAVEebccTGhxYWMUFfPm4",
"mode": "list",
"cachedResultName": "email id cache",
"cachedResultUrl": ""
},
"sheetName": {
"__rl": true,
"value": "gid=0",
"mode": "list",
"cachedResultName": "Sheet1",
"cachedResultUrl": ""
},
"columns": {
"mappingMode": "defineBelow",
"value": {
"ID": "={{ $json.id }}",
"Status": "ready"
},
"matchingColumns": [],
"schema": [
{
"id": "ID",
"displayName": "ID",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true,
"removed": false
},
{
"id": "Status",
"displayName": "Status",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true,
"removed": false
}
],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {}
},
"type": "n8n-nodes-base.googleSheets",
"typeVersion": 4.5,
"position": [
-200,
720
],
"id": "e1cf6c8a-e7ba-4be6-9028-c249e56cdb59",
"name": "Google Sheets",
"credentials": {
"googleSheetsOAuth2Api": {
"id": "Afl1JMllufI889aM",
"name": "Google Sheets account"
}
}
},
{
"parameters": {
"rule": {
"interval": [
{
"field": "seconds",
"secondsInterval": 15
}
]
}
},
"type": "n8n-nodes-base.scheduleTrigger",
"typeVersion": 1.2,
"position": [
-420,
900
],
"id": "d58a5ea7-29d4-4bb3-abf4-93c34aa38ccb",
"name": "Schedule Trigger"
},
{
"parameters": {
"documentId": {
"__rl": true,
"value": "1VaV2nX516U-h3kjPKROyERUAVEebccTGhxYWMUFfPm4",
"mode": "list",
"cachedResultName": "email id cache",
"cachedResultUrl": ""
},
"sheetName": {
"__rl": true,
"value": "gid=0",
"mode": "list",
"cachedResultName": "Sheet1",
"cachedResultUrl": ""
},
"filtersUI": {
"values": [
{
"lookupColumn": "Status",
"lookupValue": "ready"
}
]
},
"options": {
"returnFirstMatch": true
}
},
"type": "n8n-nodes-base.googleSheets",
"typeVersion": 4.5,
"position": [
-200,
900
],
"id": "aa1d27bb-6c2a-4c52-95d1-df892561bc43",
"name": "Google Sheets1",
"credentials": {
"googleSheetsOAuth2Api": {
"id": "Afl1JMllufI889aM",
"name": "Google Sheets account"
}
}
},
{
"parameters": {
"operation": "update",
"documentId": {
"__rl": true,
"value": "1VaV2nX516U-h3kjPKROyERUAVEebccTGhxYWMUFfPm4",
"mode": "list",
"cachedResultName": "email id cache",
"cachedResultUrl": ""
},
"sheetName": {
"__rl": true,
"value": "gid=0",
"mode": "list",
"cachedResultName": "Sheet1",
"cachedResultUrl": ""
},
"columns": {
"mappingMode": "defineBelow",
"value": {
"ID": "={{ $json.id }}",
"Status": "done"
},
"matchingColumns": [
"ID"
],
"schema": [
{
"id": "ID",
"displayName": "ID",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true,
"removed": false
},
{
"id": "Status",
"displayName": "Status",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true,
"removed": false
},
{
"id": "row_number",
"displayName": "row_number",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true,
"readOnly": true,
"removed": false
}
],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {}
},
"type": "n8n-nodes-base.googleSheets",
"typeVersion": 4.5,
"position": [
1936,
900
],
"id": "b2237767-b2bd-444d-8d27-ae486ce78a91",
"name": "Google Sheets2",
"credentials": {
"googleSheetsOAuth2Api": {
"id": "Afl1JMllufI889aM",
"name": "Google Sheets account"
}
}
},
{
"parameters": {
"operation": "get",
"messageId": "={{ $json.ID }}"
},
"type": "n8n-nodes-base.gmail",
"typeVersion": 2.1,
"position": [
20,
900
],
"id": "12f396bc-cb7b-4db6-a4f1-ad4bf7f65634",
"name": "Find Message By Id",
"webhookId": "09e4464b-0faa-4888-82a5-3d6fc5260ce3",
"credentials": {
"gmailOAuth2": {
"id": "NMwVt8LMXRlbkWvB",
"name": "Gmail account"
}
}
},
{
"parameters": {
"content": "Please make sure to\n- have proper error handling in place \n- double check the entire flow before running it yourself\n\nTIp:\nAdd a subworkflow to delete (pruge) all the 'done' items from the sheet",
"width": 540,
"color": 3
},
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
-80,
480
],
"id": "063dee35-ac02-481d-bc32-312c96ec8512",
"name": "Sticky Note2"
}
],
"connections": {
"Information Extractor": {
"main": [
[
{
"node": "Flatten our schema",
"type": "main",
"index": 0
},
{
"node": "Edit Fields",
"type": "main",
"index": 0
}
]
]
},
"OpenAI Chat Model": {
"ai_languageModel": [
[
{
"node": "Information Extractor",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Loop Over Items": {
"main": [
[],
[
{
"node": "If",
"type": "main",
"index": 0
}
]
]
},
"If": {
"main": [
[
{
"node": "Get All Labels",
"type": "main",
"index": 0
}
],
[
{
"node": "Loop Over Items",
"type": "main",
"index": 0
}
]
]
},
"Edit Fields": {
"main": [
[
{
"node": "Switch",
"type": "main",
"index": 0
}
]
]
},
"Switch": {
"main": [
[
{
"node": "seven",
"type": "main",
"index": 0
}
],
[
{
"node": "No Operation, do nothing",
"type": "main",
"index": 0
}
]
]
},
"Gmail": {
"main": [
[
{
"node": "Google Sheets2",
"type": "main",
"index": 0
}
]
]
},
"When clicking ‘Test workflow’": {
"main": [
[
{
"node": "Gmail1",
"type": "main",
"index": 0
}
]
]
},
"Gmail1": {
"main": [
[
{
"node": "Find missing labels",
"type": "main",
"index": 0
}
]
]
},
"Find missing labels": {
"main": [
[
{
"node": "Loop Over Items1",
"type": "main",
"index": 0
}
]
]
},
"Loop Over Items1": {
"main": [
[],
[
{
"node": "Gmail2",
"type": "main",
"index": 0
}
]
]
},
"Gmail2": {
"main": [
[
{
"node": "Loop Over Items1",
"type": "main",
"index": 0
}
]
]
},
"Get All Labels": {
"main": [
[
{
"node": "Find Corresponding Id",
"type": "main",
"index": 0
}
]
]
},
"No Operation, do nothing": {
"main": [
[
{
"node": "Google Sheets2",
"type": "main",
"index": 0
}
]
]
},
"seven": {
"main": [
[
{
"node": "Google Sheets2",
"type": "main",
"index": 0
}
]
]
},
"Flatten our schema": {
"main": [
[
{
"node": "Loop Over Items",
"type": "main",
"index": 0
}
]
]
},
"Find Corresponding Id": {
"main": [
[
{
"node": "Gmail",
"type": "main",
"index": 0
}
]
]
},
"Gmail Trigger1": {
"main": [
[
{
"node": "Google Sheets",
"type": "main",
"index": 0
}
]
]
},
"Google Sheets": {
"main": [
[]
]
},
"Schedule Trigger": {
"main": [
[
{
"node": "Google Sheets1",
"type": "main",
"index": 0
}
]
]
},
"Google Sheets1": {
"main": [
[
{
"node": "Find Message By Id",
"type": "main",
"index": 0
}
]
]
},
"Find Message By Id": {
"main": [
[
{
"node": "Information Extractor",
"type": "main",
"index": 0
}
]
]
}
},
"pinData": {},
"meta": {
"templateCredsSetupCompleted": true,
"instanceId": "505aae62d44b5f88506a847e0bdee5f4651305547a27c1f22adb1880821140fb"
}
}
@agentlearningsxm
Copy link

Thank you man, appreciate it. I wish you many successes.

@heypressgo
Copy link

Nice my friend

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment