{
  "name": "LeadFlow — n8n Lead Automation System",
  "nodes": [
    {
      "parameters": {
        "httpMethod": "POST",
        "path": "leadflow",
        "responseMode": "responseNode",
        "options": {}
      },
      "id": "6f1c2a10-0001-4c1e-9a01-1eadf1000001",
      "name": "Lead Form Webhook",
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2,
      "position": [
        0,
        300
      ],
      "webhookId": "3b8d6a52-9c3e-4f6b-8a71-2d4e5f6a7b80"
    },
    {
      "parameters": {
        "mode": "manual",
        "assignments": {
          "assignments": [
            {
              "id": "a1",
              "name": "name",
              "value": "={{ ($json.body.name || '').trim() }}",
              "type": "string"
            },
            {
              "id": "a2",
              "name": "first_name",
              "value": "={{ ($json.body.name || '').trim().split(' ')[0] }}",
              "type": "string"
            },
            {
              "id": "a3",
              "name": "email",
              "value": "={{ ($json.body.email || '').trim().toLowerCase() }}",
              "type": "string"
            },
            {
              "id": "a4",
              "name": "phone",
              "value": "={{ ($json.body.phone || '').trim() }}",
              "type": "string"
            },
            {
              "id": "a5",
              "name": "company_size",
              "value": "={{ $json.body.company_size || '' }}",
              "type": "string"
            },
            {
              "id": "a6",
              "name": "budget",
              "value": "={{ $json.body.budget || '' }}",
              "type": "string"
            },
            {
              "id": "a7",
              "name": "message",
              "value": "={{ ($json.body.message || '').trim() }}",
              "type": "string"
            },
            {
              "id": "a8",
              "name": "source",
              "value": "={{ $json.body.source || 'website' }}",
              "type": "string"
            },
            {
              "id": "a9",
              "name": "domain",
              "value": "={{ (($json.body.email || '').split('@')[1] || '').toLowerCase() }}",
              "type": "string"
            },
            {
              "id": "a10",
              "name": "received_at",
              "value": "={{ $now.toISO() }}",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "id": "6f1c2a10-0002-4c1e-9a01-1eadf1000002",
      "name": "Normalize Lead",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        260,
        300
      ]
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "loose"
          },
          "conditions": [
            {
              "id": "c1",
              "leftValue": "={{ $json.email }}",
              "rightValue": "^[^\\s@]+@[^\\s@]+\\.[^\\s@]{2,}$",
              "operator": {
                "type": "string",
                "operation": "regex"
              }
            },
            {
              "id": "c2",
              "leftValue": "={{ $json.name.length }}",
              "rightValue": 2,
              "operator": {
                "type": "number",
                "operation": "gte"
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "id": "6f1c2a10-0003-4c1e-9a01-1eadf1000003",
      "name": "Validate Lead",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2,
      "position": [
        520,
        300
      ]
    },
    {
      "parameters": {
        "url": "=https://REPLACE-WITH-YOUR-ENRICHMENT-API/v1/company?domain={{ $json.domain }}",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "options": {
          "timeout": 5000
        }
      },
      "id": "6f1c2a10-0004-4c1e-9a01-1eadf1000004",
      "name": "Enrich Company",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        780,
        200
      ],
      "onError": "continueRegularOutput",
      "credentials": {
        "httpHeaderAuth": {
          "id": "",
          "name": "Enrichment API key (add yours)"
        }
      }
    },
    {
      "parameters": {
        "respondWith": "json",
        "responseBody": "={{ { ok: false, error: 'Invalid lead: a valid email and name are required.' } }}",
        "options": {
          "responseCode": 422
        }
      },
      "id": "6f1c2a10-0005-4c1e-9a01-1eadf1000005",
      "name": "Reject Invalid",
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1.1,
      "position": [
        780,
        440
      ]
    },
    {
      "parameters": {
        "modelId": {
          "__rl": true,
          "value": "gpt-4o-mini",
          "mode": "list",
          "cachedResultName": "GPT-4O-MINI"
        },
        "messages": {
          "values": [
            {
              "content": "You are a B2B lead-qualification assistant. Read the lead's message and return ONLY JSON: {\"intent_score\": integer 0-25 (buying intent: timeline, budget signals, specificity), \"urgency\": \"high\"|\"medium\"|\"low\", \"signals\": string[], \"summary\": one sentence}.",
              "role": "system"
            },
            {
              "content": "=Lead message: {{ $('Normalize Lead').item.json.message }}\nCompany size: {{ $('Normalize Lead').item.json.company_size }}\nBudget: {{ $('Normalize Lead').item.json.budget }}"
            }
          ]
        },
        "jsonOutput": true,
        "options": {
          "temperature": 0.2
        }
      },
      "id": "6f1c2a10-0006-4c1e-9a01-1eadf1000006",
      "name": "AI Intent Analysis",
      "type": "@n8n/n8n-nodes-langchain.openAi",
      "typeVersion": 1.8,
      "position": [
        1040,
        200
      ],
      "onError": "continueRegularOutput",
      "credentials": {
        "openAiApi": {
          "id": "",
          "name": "OpenAI account (add yours)"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "// LeadFlow scoring — the exact same transparent rules used by the live demo.\n// Total = budget (max 35) + company size (max 25) + contact quality (max 15) + intent (max 25) = 100\nconst lead = $('Normalize Lead').first().json;\nconst enrich = $('Enrich Company').first().json || {};\nconst ai = ($input.first().json.message || {}).content || {};\n\nconst FREE = ['gmail.com','yahoo.com','hotmail.com','outlook.com','icloud.com','aol.com','live.com','proton.me','protonmail.com'];\nconst BUDGET = { 'under-1k': 5, '1k-5k': 15, '5k-15k': 25, '15k-plus': 35 };\nconst SIZE = { 'solo': 5, '2-10': 10, '11-50': 18, '51-200': 22, '200-plus': 25 };\nconst HIGH = ['asap','urgent','this week','this month','ready','budget approved','start','launch','hire','quote','pricing','proposal','call','deadline','immediately'];\nconst LOW = ['just browsing','just curious','student','someday','maybe later','free','no budget'];\nconst has = (text, word) => new RegExp('\\\\b' + word.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&') + '\\\\b', 'i').test(text);\n\nconst budget = BUDGET[lead.budget] || 0;\nconst size = SIZE[lead.company_size] || 0;\nconst isFree = FREE.includes(lead.domain);\nconst contact = (isFree ? 0 : 10) + ((lead.phone || '').replace(/\\D/g, '').length >= 10 ? 5 : 0);\n\n// Prefer the AI intent score (0-25); fall back to keyword rules if the AI step failed.\nlet intent = Number(ai.intent_score);\nif (!Number.isFinite(intent)) {\n  const msg = lead.message || '';\n  const pos = Math.min(20, HIGH.filter(w => has(msg, w)).length * 5);\n  const neg = LOW.filter(w => has(msg, w)).length * 10;\n  intent = pos + (msg.length >= 80 ? 5 : 0) - neg;\n}\nintent = Math.max(0, Math.min(25, Math.round(intent)));\n\nconst score = budget + size + contact + intent;\nconst tier = score >= 70 ? 'hot' : score >= 40 ? 'warm' : 'cold';\n\nreturn [{ json: {\n  ...lead,\n  company_name: enrich.company_name || null,\n  is_free_email: isFree,\n  ai_summary: ai.summary || '',\n  score, tier,\n  breakdown: { budget, company_size: size, contact, intent }\n} }];"
      },
      "id": "6f1c2a10-0007-4c1e-9a01-1eadf1000007",
      "name": "Score Lead",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1300,
        200
      ]
    },
    {
      "parameters": {
        "rules": {
          "values": [
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict"
                },
                "conditions": [
                  {
                    "id": "r1",
                    "leftValue": "={{ $json.tier }}",
                    "rightValue": "hot",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    }
                  }
                ],
                "combinator": "and"
              },
              "renameOutput": true,
              "outputKey": "Hot"
            },
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict"
                },
                "conditions": [
                  {
                    "id": "r2",
                    "leftValue": "={{ $json.tier }}",
                    "rightValue": "warm",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    }
                  }
                ],
                "combinator": "and"
              },
              "renameOutput": true,
              "outputKey": "Warm"
            },
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict"
                },
                "conditions": [
                  {
                    "id": "r3",
                    "leftValue": "={{ $json.tier }}",
                    "rightValue": "cold",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    }
                  }
                ],
                "combinator": "and"
              },
              "renameOutput": true,
              "outputKey": "Cold"
            }
          ]
        },
        "options": {}
      },
      "id": "6f1c2a10-0008-4c1e-9a01-1eadf1000008",
      "name": "Route by Tier",
      "type": "n8n-nodes-base.switch",
      "typeVersion": 3,
      "position": [
        1560,
        100
      ]
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://graph.facebook.com/v20.0/REPLACE_WITH_PHONE_NUMBER_ID/messages",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={\n  \"messaging_product\": \"whatsapp\",\n  \"to\": \"{{ $json.phone.replace(/\\D/g, '') }}\",\n  \"type\": \"template\",\n  \"template\": {\n    \"name\": \"leadflow_welcome\",\n    \"language\": { \"code\": \"en\" },\n    \"components\": [{ \"type\": \"body\", \"parameters\": [{ \"type\": \"text\", \"text\": \"{{ $json.first_name }}\" }] }]\n  }\n}",
        "options": {}
      },
      "id": "6f1c2a10-0009-4c1e-9a01-1eadf1000009",
      "name": "WhatsApp Reply",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        1820,
        -60
      ],
      "onError": "continueRegularOutput",
      "credentials": {
        "httpHeaderAuth": {
          "id": "",
          "name": "WhatsApp Cloud API token (add yours)"
        }
      }
    },
    {
      "parameters": {
        "authentication": "appToken",
        "operation": "upsert",
        "email": "={{ $json.email }}",
        "additionalFields": {
          "firstName": "={{ $json.first_name }}",
          "phoneNumber": "={{ $json.phone }}",
          "companyName": "={{ $json.company_name || '' }}",
          "leadStatus": "OPEN",
          "lifeCycleStage": "salesqualifiedlead"
        },
        "options": {}
      },
      "id": "6f1c2a10-0010-4c1e-9a01-1eadf1000010",
      "name": "CRM Upsert",
      "type": "n8n-nodes-base.hubspot",
      "typeVersion": 2.1,
      "position": [
        1820,
        30
      ],
      "credentials": {
        "hubspotAppToken": {
          "id": "",
          "name": "HubSpot private app token (add yours)"
        }
      }
    },
    {
      "parameters": {
        "select": "channel",
        "channelId": {
          "__rl": true,
          "value": "#sales-hot-leads",
          "mode": "name"
        },
        "text": "=:fire: *Hot lead* (score {{ $json.score }}/100): {{ $json.name }} — {{ $json.company_name || $json.domain }}\n:email: {{ $json.email }}  :telephone_receiver: {{ $json.phone || 'n/a' }}\n:speech_balloon: {{ $json.message.slice(0, 180) }}",
        "otherOptions": {}
      },
      "id": "6f1c2a10-0011-4c1e-9a01-1eadf1000011",
      "name": "Slack Sales Alert",
      "type": "n8n-nodes-base.slack",
      "typeVersion": 2.2,
      "position": [
        1820,
        120
      ],
      "credentials": {
        "slackApi": {
          "id": "",
          "name": "Slack bot token (add yours)"
        }
      }
    },
    {
      "parameters": {
        "sendTo": "={{ $json.email }}",
        "subject": "={{ $json.first_name }}, here's how teams like yours automate lead follow-up",
        "emailType": "text",
        "message": "=Hi {{ $json.first_name }},\n\nThanks for your enquiry. While we review it, here is a short guide on how growing teams capture, score and route every lead automatically.\n\nIf you'd like to talk it through, just reply to this email and pick a time that suits you.\n\nBest regards,\nThe Sales Team",
        "options": {
          "appendAttribution": false
        }
      },
      "id": "6f1c2a10-0012-4c1e-9a01-1eadf1000012",
      "name": "Nurture Email",
      "type": "n8n-nodes-base.gmail",
      "typeVersion": 2.1,
      "position": [
        1820,
        220
      ],
      "credentials": {
        "gmailOAuth2": {
          "id": "",
          "name": "Gmail account (add yours)"
        }
      }
    },
    {
      "parameters": {
        "list": "REPLACE_WITH_AUDIENCE_ID",
        "email": "={{ $json.email }}",
        "status": "subscribed",
        "options": {
          "tags": "leadflow-cold"
        },
        "mergeFieldsUi": {
          "mergeFieldsValues": [
            {
              "name": "FNAME",
              "value": "={{ $json.first_name }}"
            }
          ]
        }
      },
      "id": "6f1c2a10-0013-4c1e-9a01-1eadf1000013",
      "name": "Add to Newsletter",
      "type": "n8n-nodes-base.mailchimp",
      "typeVersion": 1,
      "position": [
        1820,
        310
      ],
      "credentials": {
        "mailchimpApi": {
          "id": "",
          "name": "Mailchimp API key (add yours)"
        }
      }
    },
    {
      "parameters": {
        "operation": "append",
        "documentId": {
          "__rl": true,
          "value": "REPLACE_WITH_GOOGLE_SHEET_ID",
          "mode": "id"
        },
        "sheetName": {
          "__rl": true,
          "value": "Leads",
          "mode": "name"
        },
        "columns": {
          "mappingMode": "defineBelow",
          "value": {
            "received_at": "={{ $json.received_at }}",
            "name": "={{ $json.name }}",
            "email": "={{ $json.email }}",
            "phone": "={{ $json.phone }}",
            "company_size": "={{ $json.company_size }}",
            "budget": "={{ $json.budget }}",
            "source": "={{ $json.source }}",
            "score": "={{ $json.score }}",
            "tier": "={{ $json.tier }}"
          },
          "matchingColumns": [],
          "schema": []
        },
        "options": {}
      },
      "id": "6f1c2a10-0014-4c1e-9a01-1eadf1000014",
      "name": "Log to Sheets",
      "type": "n8n-nodes-base.googleSheets",
      "typeVersion": 4.5,
      "position": [
        1560,
        430
      ],
      "credentials": {
        "googleSheetsOAuth2Api": {
          "id": "",
          "name": "Google Sheets account (add yours)"
        }
      }
    },
    {
      "parameters": {
        "respondWith": "json",
        "responseBody": "={{ { ok: true, tier: $('Score Lead').item.json.tier, score: $('Score Lead').item.json.score } }}",
        "options": {
          "responseCode": 200
        }
      },
      "id": "6f1c2a10-0015-4c1e-9a01-1eadf1000015",
      "name": "Respond Success",
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1.1,
      "position": [
        1820,
        430
      ]
    },
    {
      "parameters": {},
      "id": "6f1c2a10-0016-4c1e-9a01-1eadf1000016",
      "name": "Error Trigger",
      "type": "n8n-nodes-base.errorTrigger",
      "typeVersion": 1,
      "position": [
        0,
        600
      ]
    },
    {
      "parameters": {
        "sendTo": "ops@REPLACE-WITH-YOUR-DOMAIN.com",
        "subject": "=[LeadFlow] Execution failed at \"{{ $json.execution.lastNodeExecuted }}\"",
        "emailType": "text",
        "message": "=The LeadFlow workflow failed.\n\nNode: {{ $json.execution.lastNodeExecuted }}\nError: {{ $json.execution.error.message }}\nExecution: {{ $json.execution.url }}\n\nThe lead was received but may not have been fully processed — please check it manually.",
        "options": {
          "appendAttribution": false
        }
      },
      "id": "6f1c2a10-0017-4c1e-9a01-1eadf1000017",
      "name": "Gmail Error Alert",
      "type": "n8n-nodes-base.gmail",
      "typeVersion": 2.1,
      "position": [
        260,
        600
      ],
      "credentials": {
        "gmailOAuth2": {
          "id": "",
          "name": "Gmail account (add yours)"
        }
      }
    }
  ],
  "connections": {
    "Lead Form Webhook": {
      "main": [
        [
          {
            "node": "Normalize Lead",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Normalize Lead": {
      "main": [
        [
          {
            "node": "Validate Lead",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Validate Lead": {
      "main": [
        [
          {
            "node": "Enrich Company",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Reject Invalid",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Enrich Company": {
      "main": [
        [
          {
            "node": "AI Intent Analysis",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "AI Intent Analysis": {
      "main": [
        [
          {
            "node": "Score Lead",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Score Lead": {
      "main": [
        [
          {
            "node": "Route by Tier",
            "type": "main",
            "index": 0
          },
          {
            "node": "Log to Sheets",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Route by Tier": {
      "main": [
        [
          {
            "node": "WhatsApp Reply",
            "type": "main",
            "index": 0
          },
          {
            "node": "CRM Upsert",
            "type": "main",
            "index": 0
          },
          {
            "node": "Slack Sales Alert",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Nurture Email",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Add to Newsletter",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Log to Sheets": {
      "main": [
        [
          {
            "node": "Respond Success",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Error Trigger": {
      "main": [
        [
          {
            "node": "Gmail Error Alert",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "active": false,
  "settings": {
    "executionOrder": "v1",
    "saveManualExecutions": true
  },
  "pinData": {},
  "meta": {
    "templateCredsSetupCompleted": false
  },
  "tags": []
}
