AutomationFlowsAI & RAG › Cold Email Warm-up + Reply Detector

Cold Email Warm-up + Reply Detector

03 - Cold Email Warm-up + Reply Detector. Uses emailReadImap, anthropic, slack, googleSheets. Scheduled trigger; 7 nodes.

Cron / scheduled trigger★★★★☆ complexityAI-powered7 nodesEmail Read ImapAnthropicSlackGoogle Sheets
AI & RAG Trigger: Cron / scheduled Nodes: 7 Complexity: ★★★★☆ AI nodes: yes Added:

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 →

Download .json
{
  "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.

Pro

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 →

More AI & RAG workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

AI & RAG

06 - AEO Citation Monitor (4 LLMs). Uses googleSheets, anthropic, httpRequest, slack. Scheduled trigger; 11 nodes.

Google Sheets, Anthropic, HTTP Request +1
AI & RAG

15 - Async Standup Bot. Uses googleSheets, slack, anthropic. Scheduled trigger; 10 nodes.

Google Sheets, Slack, Anthropic
AI & RAG

01 - LinkedIn DM ICP Scorer. Uses httpRequest, anthropic, slack, googleSheets. Scheduled trigger; 9 nodes.

HTTP Request, Anthropic, Slack +1
AI & RAG

09 - GSC anomaly bot. Uses httpRequest, anthropic, slack, googleSheets. Scheduled trigger; 8 nodes.

HTTP Request, Anthropic, Slack +1
AI & RAG

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

HTTP Request, Google Sheets, OpenAI +3