{
  "name": "Cold Email Reply Sentiment Router",
  "nodes": [
    {
      "parameters": {
        "content": "## Setup\n1. Point your sending platform's reply webhook (Instantly, Smartlead, etc.) at this workflow's Webhook URL.\n2. Paste your HubSpot private app token into both HubSpot nodes.\n3. Paste a Slack incoming webhook URL into \"Notify Positive Reply\".\n\nFrom Chapter 3: any reply, even a decline, ends the follow-up sequence. This workflow makes that automatic instead of relying on someone remembering to stop.",
        "height": 300,
        "width": 400
      },
      "id": "c2d3e4f5-2222-4a2b-9c3a-000000000001",
      "name": "Setup Notes",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [-200, 60]
    },
    {
      "parameters": {
        "httpMethod": "POST",
        "path": "reply-sentiment-router",
        "responseMode": "onReceived",
        "options": {}
      },
      "id": "c2d3e4f5-2222-4a2b-9c3a-000000000002",
      "name": "Reply Received Webhook",
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2,
      "position": [-200, 420]
    },
    {
      "parameters": {
        "jsCode": "const text = ($input.first().json.reply_text || '').toLowerCase();\nconst negative = ['unsubscribe', 'stop', 'not interested', 'remove me'];\nconst positive = ['interested', 'sounds good', 'let\\'s talk', 'yes', 'sure', 'book a', 'schedule'];\n\nlet sentiment = 'neutral';\nif (negative.some(w => text.includes(w))) sentiment = 'negative';\nelse if (positive.some(w => text.includes(w))) sentiment = 'positive';\n\nreturn [{ json: { ...$input.first().json, sentiment } }];"
      },
      "id": "c2d3e4f5-2222-4a2b-9c3a-000000000003",
      "name": "Classify Sentiment",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [40, 420]
    },
    {
      "parameters": {
        "conditions": {
          "options": { "caseSensitive": true, "leftValue": "", "typeValidation": "strict" },
          "conditions": [
            { "leftValue": "={{ $json.sentiment }}", "rightValue": "positive", "operator": { "type": "string", "operation": "equals" } }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "id": "c2d3e4f5-2222-4a2b-9c3a-000000000004",
      "name": "Is Positive?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [280, 320]
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://api.hubapi.com/crm/v3/objects/deals",
        "sendHeaders": true,
        "headerParameters": { "parameters": [{ "name": "Content-Type", "value": "application/json" }, { "name": "Authorization", "value": "Bearer YOUR_HUBSPOT_PRIVATE_APP_TOKEN" }] },
        "sendBody": true,
        "bodyParameters": { "parameters": [{ "name": "properties.dealname", "value": "={{ $json.from_name }} — replied positively" }, { "name": "properties.dealstage", "value": "discoveryscheduled" }] },
        "options": {}
      },
      "id": "c2d3e4f5-2222-4a2b-9c3a-000000000005",
      "name": "Create Deal in HubSpot",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [520, 220]
    },
    {
      "parameters": {
        "method": "POST",
        "url": "YOUR_SLACK_INCOMING_WEBHOOK_URL",
        "sendBody": true,
        "bodyParameters": { "parameters": [{ "name": "text", "value": "=Positive reply from {{ $json.from_name }}, deal created. Respond personally, don't let this sit." }] },
        "options": {}
      },
      "id": "c2d3e4f5-2222-4a2b-9c3a-000000000006",
      "name": "Notify Positive Reply",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [760, 220]
    },
    {
      "parameters": {
        "method": "PATCH",
        "url": "=https://api.hubapi.com/crm/v3/objects/contacts/{{ $json.contact_id }}",
        "sendHeaders": true,
        "headerParameters": { "parameters": [{ "name": "Content-Type", "value": "application/json" }, { "name": "Authorization", "value": "Bearer YOUR_HUBSPOT_PRIVATE_APP_TOKEN" }] },
        "sendBody": true,
        "bodyParameters": { "parameters": [{ "name": "properties.sequence_status", "value": "={{ $json.sentiment === 'negative' ? 'disqualified' : 'needs_review' }}" }] },
        "options": {}
      },
      "id": "c2d3e4f5-2222-4a2b-9c3a-000000000007",
      "name": "Update Contact Status",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [520, 520]
    }
  ],
  "connections": {
    "Reply Received Webhook": { "main": [[{ "node": "Classify Sentiment", "type": "main", "index": 0 }]] },
    "Classify Sentiment": { "main": [[{ "node": "Is Positive?", "type": "main", "index": 0 }]] },
    "Is Positive?": { "main": [[{ "node": "Create Deal in HubSpot", "type": "main", "index": 0 }], [{ "node": "Update Contact Status", "type": "main", "index": 0 }]] },
    "Create Deal in HubSpot": { "main": [[{ "node": "Notify Positive Reply", "type": "main", "index": 0 }]] }
  },
  "active": false,
  "settings": { "executionOrder": "v1" },
  "pinData": {}
}
