This workflow corresponds to n8n.io template #skynetlabs-03 — we link there as the canonical source.
This workflow follows the Google Sheets → Slack 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 →
{
"name": "03 - Cold Email Warm-up + Reply Detector",
"nodes": [
{
"parameters": {
"rule": {
"interval": [
{
"field": "minutes",
"minutesInterval": 15
}
]
}
},
"id": "trigger-cron",
"name": "Every 15 min",
"type": "n8n-nodes-base.scheduleTrigger",
"typeVersion": 1.1,
"position": [
200,
300
]
},
{
"parameters": {
"format": "simple",
"options": {
"customEmailConfig": "[\"UNSEEN\"]"
}
},
"id": "imap-fetch",
"name": "Fetch new replies (IMAP)",
"type": "n8n-nodes-base.emailReadImap",
"typeVersion": 2,
"position": [
420,
300
],
"credentials": {
"imap": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"modelId": {
"__rl": true,
"value": "claude-sonnet-4-6",
"mode": "list"
},
"messages": {
"values": [
{
"content": "=You classify replies to cold email outreach for SkynetLabs.\n\nMY OFFER: Automation + AEO retainers and one-off Fiverr builds ($297-997 builds, $1.5K-5K retainers).\n\nClassify the reply into ONE category:\n- HOT: positive intent, asking for call/pricing/next step\n- WARM: 'maybe later', 'send more info', 'not now but Q3'\n- COLD: polite no\n- OOO: out-of-office auto-reply\n- BOUNCE: mail server bounce / undeliverable\n- UNSUB: asked to be removed\n- HOSTILE: complaint, spam threat, legal\n- OTHER: not interpretable\n\nReply subject:\n{{ $json.subject }}\n\nReply body (first 1500 chars):\n{{ $json.text?.substring(0, 1500) || $json.textHtml?.substring(0, 1500) || '' }}\n\nFrom:\n{{ $json.from }}\n\nReturn ONLY valid JSON:\n{\n \"classification\": \"HOT|WARM|COLD|OOO|BOUNCE|UNSUB|HOSTILE|OTHER\",\n \"intent_score\": 0-100,\n \"reason\": \"one-sentence why\",\n \"suggested_reply\": \"60-word reply OR 'PAUSE_SEQUENCE' if HOT/UNSUB/HOSTILE, or 'SKIP' otherwise\",\n \"resume_in_days\": null\n}",
"role": "user"
}
]
},
"options": {
"temperature": 0.2,
"maxTokens": 600
}
},
"id": "claude-classify",
"name": "Claude classify",
"type": "@n8n/n8n-nodes-langchain.anthropic",
"typeVersion": 1.2,
"position": [
640,
300
],
"credentials": {
"anthropicApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"jsCode": "const raw = $input.first().json.content?.[0]?.text || $input.first().json.text || '';\nconst match = raw.match(/\\{[\\s\\S]*\\}/);\nif (!match) throw new Error('No JSON in Claude reply');\nconst parsed = JSON.parse(match[0]);\nconst email = $('Fetch new replies (IMAP)').first().json;\nreturn [{\n json: {\n ...parsed,\n from: email.from,\n subject: email.subject,\n received_at: email.date || new Date().toISOString(),\n snippet: (email.text || email.textHtml || '').substring(0, 300)\n }\n}];"
},
"id": "parse",
"name": "Parse + merge",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
860,
300
]
},
{
"parameters": {
"rules": {
"values": [
{
"conditions": {
"options": {
"caseSensitive": true
},
"conditions": [
{
"leftValue": "={{ $json.classification }}",
"rightValue": "HOT",
"operator": {
"type": "string",
"operation": "equals"
}
}
]
},
"outputKey": "hot"
},
{
"conditions": {
"options": {
"caseSensitive": true
},
"conditions": [
{
"leftValue": "={{ $json.classification }}",
"rightValue": "WARM",
"operator": {
"type": "string",
"operation": "equals"
}
}
]
},
"outputKey": "warm"
},
{
"conditions": {
"options": {
"caseSensitive": true
},
"conditions": [
{
"leftValue": "={{ $json.classification }}",
"rightValue": "BOUNCE",
"operator": {
"type": "string",
"operation": "equals"
}
}
]
},
"outputKey": "bounce_or_unsub"
},
{
"conditions": {
"options": {
"caseSensitive": true
},
"conditions": [
{
"leftValue": "={{ $json.classification }}",
"rightValue": "UNSUB",
"operator": {
"type": "string",
"operation": "equals"
}
}
]
},
"outputKey": "bounce_or_unsub"
}
]
},
"options": {
"fallbackOutput": "extra"
}
},
"id": "switch-class",
"name": "Route by class",
"type": "n8n-nodes-base.switch",
"typeVersion": 3.2,
"position": [
1080,
300
]
},
{
"parameters": {
"channel": "#cold-email-hot",
"text": "=\ud83d\udd25 *HOT REPLY* \u2014 intent {{ $json.intent_score }}/100\n\n*From:* {{ $json.from }}\n*Subject:* {{ $json.subject }}\n\n*Snippet:*\n> {{ $json.snippet }}\n\n*Why:* {{ $json.reason }}\n\n*Suggested reply:*\n```\n{{ $json.suggested_reply }}\n```\n\n\u26a0\ufe0f Sequence has been flagged to pause for this contact in the Sheet.",
"otherOptions": {}
},
"id": "slack-hot",
"name": "Slack hot ping",
"type": "n8n-nodes-base.slack",
"typeVersion": 2.2,
"position": [
1300,
100
],
"credentials": {
"slackApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"operation": "append",
"documentId": {
"__rl": true,
"value": "REPLACE_ME_SHEET_ID",
"mode": "id"
},
"sheetName": {
"__rl": true,
"value": "reply-log",
"mode": "name"
},
"columns": {
"mappingMode": "defineBelow",
"value": {
"received_at": "={{ $json.received_at }}",
"from": "={{ $json.from }}",
"subject": "={{ $json.subject }}",
"classification": "={{ $json.classification }}",
"intent_score": "={{ $json.intent_score }}",
"reason": "={{ $json.reason }}",
"suggested_reply": "={{ $json.suggested_reply }}",
"snippet": "={{ $json.snippet }}",
"next_action": "={{ $json.classification === 'HOT' ? 'pause_seq + reply' : $json.classification === 'UNSUB' ? 'remove_from_list' : 'log_only' }}"
}
},
"options": {}
},
"id": "sheets-log",
"name": "Log every reply",
"type": "n8n-nodes-base.googleSheets",
"typeVersion": 4.5,
"position": [
1300,
500
],
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
}
}
],
"connections": {
"Every 15 min": {
"main": [
[
{
"node": "Fetch new replies (IMAP)",
"type": "main",
"index": 0
}
]
]
},
"Fetch new replies (IMAP)": {
"main": [
[
{
"node": "Claude classify",
"type": "main",
"index": 0
}
]
]
},
"Claude classify": {
"main": [
[
{
"node": "Parse + merge",
"type": "main",
"index": 0
}
]
]
},
"Parse + merge": {
"main": [
[
{
"node": "Route by class",
"type": "main",
"index": 0
}
]
]
},
"Route by class": {
"main": [
[
{
"node": "Slack hot ping",
"type": "main",
"index": 0
},
{
"node": "Log every reply",
"type": "main",
"index": 0
}
],
[
{
"node": "Log every reply",
"type": "main",
"index": 0
}
],
[
{
"node": "Log every reply",
"type": "main",
"index": 0
}
],
[
{
"node": "Log every reply",
"type": "main",
"index": 0
}
]
]
}
},
"settings": {
"executionOrder": "v1"
},
"meta": {
"templateId": "skynetlabs-03"
},
"tags": [
{
"name": "skynetlabs-pack"
},
{
"name": "cold-email"
},
{
"name": "reply-classifier"
}
]
}
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.
anthropicApigoogleSheetsOAuth2ApiimapslackApi
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
03 - Cold Email Warm-up + Reply Detector. Uses emailReadImap, anthropic, slack, googleSheets. Scheduled trigger; 7 nodes.
Source: https://github.com/waseemnasir2k26/skynet-automation-pack/blob/main/n8n/03-cold-email-warmup-reply-detector.json — 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.
06 - AEO Citation Monitor (4 LLMs). Uses googleSheets, anthropic, httpRequest, slack. Scheduled trigger; 11 nodes.
15 - Async Standup Bot. Uses googleSheets, slack, anthropic. Scheduled trigger; 10 nodes.
01 - LinkedIn DM ICP Scorer. Uses httpRequest, anthropic, slack, googleSheets. Scheduled trigger; 9 nodes.
09 - GSC anomaly bot. Uses httpRequest, anthropic, slack, googleSheets. Scheduled trigger; 8 nodes.
Imagine a dedicated financial expert tirelessly working behind the scenes, sifting through every transaction, every investment move, and every accounting entry. That's exactly what this automated syst