{
  "name": "Lead Research & Enrichment Pipeline",
  "nodes": [
    {
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "cronExpression",
              "expression": "30 8 * * *"
            }
          ]
        }
      },
      "id": "node-schedule",
      "name": "Schedule Trigger",
      "type": "n8n-nodes-base.scheduleTrigger",
      "typeVersion": 1.3,
      "position": [
        80,
        176
      ]
    },
    {
      "parameters": {
        "httpMethod": "POST",
        "path": "lead-scraper-done",
        "options": {}
      },
      "id": "scraper-webhook-trigger",
      "name": "Scraper Webhook",
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2.1,
      "position": [
        80,
        -16
      ]
    },
    {
      "parameters": {
        "documentId": {
          "__rl": true,
          "value": "YOUR_SHEET_ID",
          "mode": "id"
        },
        "sheetName": {
          "__rl": true,
          "value": "gid=0",
          "mode": "list",
          "cachedResultName": "Leads"
        },
        "options": {}
      },
      "id": "node-read-phones",
      "name": "Read Existing Phones",
      "type": "n8n-nodes-base.googleSheets",
      "typeVersion": 4.7,
      "position": [
        304,
        128
      ],
      "alwaysOutputData": true
    },
    {
      "parameters": {
        "fileSelector": "/home/node/.n8n-files/leads-latest.csv",
        "options": {}
      },
      "id": "node-readfile",
      "name": "Read CSV File",
      "type": "n8n-nodes-base.readWriteFile",
      "typeVersion": 1.1,
      "position": [
        528,
        128
      ]
    },
    {
      "parameters": {
        "options": {}
      },
      "id": "node-extract-csv",
      "name": "Extract from File",
      "type": "n8n-nodes-base.extractFromFile",
      "typeVersion": 1,
      "position": [
        752,
        128
      ]
    },
    {
      "parameters": {
        "jsCode": "function normalizePhone(raw) {\n  const digits = (raw || '').toString().replace(/\\D/g, '').trim();\n  if (!digits || digits.length < 7) return null;\n  if ((digits.startsWith('91') || digits.startsWith('0')) && digits.length >= 11)\n    return digits.slice(-10);\n  return digits;\n}\n\nconst existingItems = $('Read Existing Phones').all();\nconst existingPhones = new Set();\nfor (const item of existingItems) {\n  const p = normalizePhone(item.json.phone || item.json.E || '');\n  if (p) existingPhones.add(p);\n}\n\nconst staticData = $getWorkflowStaticData('global');\nconst runPhones = staticData.runPhones || [];\nfor (const p of runPhones) existingPhones.add(p);\n\nconst allItems = $input.all();\nconst result = [];\nconst newPhones = [];\n\nfor (let i = 0; i < allItems.length; i++) {\n  const item = allItems[i];\n  const p = normalizePhone(item.json.phone || '');\n  if (!p) continue;\n  if (existingPhones.has(p)) continue;\n  existingPhones.add(p);\n  newPhones.push(p);\n  result.push({ json: item.json, pairedItem: { item: i } });\n}\n\nstaticData.runPhones = [...runPhones, ...newPhones];\nreturn result;"
      },
      "id": "node-filter-dedup",
      "name": "Filter Duplicates",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        976,
        128
      ]
    },
    {
      "parameters": {
        "jsCode": "const allItems = $input.all();\nconst result = [];\n\nfor (let i = 0; i < allItems.length; i++) {\n  const row = allItems[i].json;\n\n  const rawPhone = (row.phone || '').toString().replace(/\\D/g, '');\n  const phone = rawPhone.startsWith('91') && rawPhone.length > 10 ? rawPhone.slice(2) : rawPhone;\n\n  const email = row.emails || '';\n  const outreach_channel = email ? 'email' : (phone ? 'whatsapp' : 'instagram');\n\n  const city = row.city || '';\n\n  const now = new Date(new Date().toLocaleString('en-US', { timeZone: 'Asia/Kolkata' }));\n  const dd = String(now.getDate()).padStart(2, '0');\n  const mm = String(now.getMonth() + 1).padStart(2, '0');\n  const yyyy = now.getFullYear();\n  const scraped_date = `${yyyy}-${mm}-${dd}`;\n\n  result.push({\n    json: {\n      business_name: row.title || '',\n      owner_name: '',\n      city,\n      vertical: row.category || '',\n      phone: phone || '',\n      whatsapp_valid: 'pending',\n      email,\n      website: row.website || '',\n      instagram_handle: '',\n      linkedin_url: '',\n      rating: row.review_rating || '',\n      review_count: row.review_count || '',\n      lead_score: '',\n      outreach_status: 'new',\n      outreach_channel,\n      scraped_date,\n      first_contacted_date: '',\n      first_message_sent: '',\n      first_reply: '',\n      followup_1_date: '',\n      followup_1_message: '',\n      followup_1_reply: '',\n      followup_2_date: '',\n      followup_2_message: '',\n      followup_2_reply: '',\n      interested: '',\n      demo_booked: '',\n      demo_date: '',\n      notes: row.address || ''\n    },\n    pairedItem: { item: i }\n  });\n}\n\nconst staticData = $getWorkflowStaticData('global');\nstaticData.leadsAddedCount = (staticData.leadsAddedCount || 0) + result.length;\n\nreturn result;"
      },
      "id": "node-prepare-leads",
      "name": "Prepare Leads",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1200,
        128
      ]
    },
    {
      "parameters": {
        "batchSize": 10,
        "options": {}
      },
      "id": "node-batches",
      "name": "Split In Batches",
      "type": "n8n-nodes-base.splitInBatches",
      "typeVersion": 3,
      "position": [
        1424,
        112
      ],
      "onError": "continueErrorOutput"
    },
    {
      "parameters": {
        "operation": "append",
        "documentId": {
          "__rl": true,
          "value": "YOUR_SHEET_ID",
          "mode": "id"
        },
        "sheetName": {
          "__rl": true,
          "value": "gid=0",
          "mode": "list",
          "cachedResultName": "Leads"
        },
        "columns": {
          "mappingMode": "defineBelow",
          "value": {
            "business_name": "={{ $json.business_name }}",
            "city": "={{ $json.city }}",
            "vertical": "={{ $json.vertical }}",
            "phone": "={{ $json.phone }}",
            "email": "={{ $json.email }}",
            "website": "={{ $json.website }}",
            "rating": "={{ $json.rating }}",
            "review_count": "={{ $json.review_count }}",
            "scraped_date": "={{ $json.scraped_date }}",
            "outreach_status": "={{ $json.outreach_status }}",
            "outreach_channel": "={{ $json.outreach_channel }}",
            "notes": "={{ $json.notes }}"
          },
          "matchingColumns": [],
          "schema": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false,
          "valueInputOption": "USER_ENTERED"
        },
        "options": {}
      },
      "id": "node-sheets",
      "name": "Save to Google Sheets",
      "type": "n8n-nodes-base.googleSheets",
      "typeVersion": 4.7,
      "position": [
        1648,
        176
      ],
      "onError": "continueRegularOutput"
    },
    {
      "parameters": {
        "jsCode": "const staticData = $getWorkflowStaticData('global');\nconst count = staticData.leadsAddedCount || 0;\n\nstaticData.leadsAddedCount = 0;\nstaticData.runPhones = [];\n\nconst now = new Date();\nconst dateStr = now.toLocaleDateString('en-IN', {\n  timeZone: 'Asia/Kolkata',\n  weekday: 'long', year: 'numeric', month: 'long', day: 'numeric'\n});\nconst timeStr = now.toLocaleTimeString('en-IN', {\n  timeZone: 'Asia/Kolkata', hour: '2-digit', minute: '2-digit', hour12: true\n});\n\nconst message = `Lead Research Complete!\\n\\nDate: ${dateStr}\\nRun at: ${timeStr} IST\\n\\nNew leads added: ${count}`;\n\nreturn [{ json: { message } }];"
      },
      "id": "node-wa-summary-body",
      "name": "Build WA Summary",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1648,
        -16
      ]
    },
    {
      "parameters": {
        "operation": "send",
        "phoneNumberId": "={{$env.WHATSAPP_PHONE_NUMBER_ID}}",
        "recipientPhoneNumber": "={{$env.ALERT_PHONE_NUMBER}}",
        "textBody": "={{ $json.message }}",
        "additionalFields": {}
      },
      "type": "n8n-nodes-base.whatsApp",
      "typeVersion": 1.1,
      "position": [
        1872,
        -16
      ],
      "id": "node-send-summary",
      "name": "Send WhatsApp Summary"
    }
  ],
  "connections": {
    "Schedule Trigger": {
      "main": [
        [
          {
            "node": "Read Existing Phones",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Scraper Webhook": {
      "main": [
        [
          {
            "node": "Read Existing Phones",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Read Existing Phones": {
      "main": [
        [
          {
            "node": "Read CSV File",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Read CSV File": {
      "main": [
        [
          {
            "node": "Extract from File",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract from File": {
      "main": [
        [
          {
            "node": "Filter Duplicates",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Filter Duplicates": {
      "main": [
        [
          {
            "node": "Prepare Leads",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prepare Leads": {
      "main": [
        [
          {
            "node": "Split In Batches",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Split In Batches": {
      "main": [
        [
          {
            "node": "Build WA Summary",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Save to Google Sheets",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Save to Google Sheets": {
      "main": [
        [
          {
            "node": "Split In Batches",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Build WA Summary": {
      "main": [
        [
          {
            "node": "Send WhatsApp Summary",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "settings": {
    "executionOrder": "v1",
    "timezone": "Asia/Kolkata",
    "saveDataErrorExecution": "all",
    "saveDataSuccessExecution": "all",
    "saveManualExecutions": true
  }
}