{
  "id": "mk5csy0c4YoizKko",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "Qualify property leads from WhatsApp using Gemini and Supabase",
  "tags": [],
  "nodes": [
    {
      "id": "7da27994-75da-4d12-b54b-bc9712e07fc4",
      "name": "Template Overview",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -944,
        -64
      ],
      "parameters": {
        "color": 4,
        "width": 620,
        "height": 1052,
        "content": "## \ud83c\udfe0 Qualify Property Leads from WhatsApp using Gemini and Supabase\n\n### Who's it for\nReal estate agents and small brokerages who receive property inquiries over WhatsApp and want to automatically qualify leads by budget, intent, and urgency without manually reading every message.\n\n### How it works\nWhen a new WhatsApp message arrives, Gemini extracts structured details (budget, property type, location, timeline, intent score) from the message. Leads are saved to Supabase for tracking, then routed by intent score high-intent leads trigger an instant WhatsApp alert to the agent, while medium/low leads are simply logged for later follow-up.\n\n### How to set up\n1. Connect your WhatsApp Business Cloud credentials to the trigger and send nodes.\n2. Connect your Google Gemini (PaLM) API credentials to the Chat Model node.\n3. Connect your Supabase credentials and create a `leads` table (see the sticky note near the Supabase node for the schema).\n4. Open the **Set Configuration** node and enter your agent's WhatsApp number and score thresholds.\n5. Activate the workflow.\n\n### Requirements\n- WhatsApp Business Cloud API access\n- Google Gemini API key\n- Supabase project\n\n### How to customize\nEdit the Gemini prompt in **Classify Lead Intent** to capture fields specific to your listings (e.g. commercial vs. residential). Adjust thresholds in **Set Configuration** to change how aggressively leads get filtered before an agent is alerted.\n\n\u26a0\ufe0f Known n8n bug: if the Structured Output Parser throws a schema error, downgrade the Basic LLM Chain node to typeVersion 1.8."
      },
      "typeVersion": 1
    },
    {
      "id": "7abfe99d-034e-496d-bb52-429df1632902",
      "name": "Trigger Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -240,
        288
      ],
      "parameters": {
        "color": 7,
        "width": 452,
        "height": 212,
        "content": "### 1\ufe0f\u20e3 Trigger\nFires on every incoming WhatsApp message. Connect your WhatsApp Business Cloud number here. Verify the payload field names match your account (some WhatsApp Business accounts nest fields slightly differently)."
      },
      "typeVersion": 1
    },
    {
      "id": "a0622862-82f0-4d9c-a803-2116a200677a",
      "name": "AI Classification Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        368,
        304
      ],
      "parameters": {
        "color": 7,
        "width": 420,
        "height": 196,
        "content": "### 2\ufe0f\u20e3 AI Classification\nGemini reads the WhatsApp message and extracts structured lead data (budget, property type, timeline, intent score 1\u201310). Edit the prompt below to match your listing categories or add fields."
      },
      "typeVersion": 1
    },
    {
      "id": "4d14dbc2-21b1-4352-9e78-67e91fb69d06",
      "name": "Supabase Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        864,
        288
      ],
      "parameters": {
        "color": 7,
        "width": 420,
        "height": 216,
        "content": "### 3\ufe0f\u20e3 Save to Supabase\nCreate a `leads` table before running, with columns:\n`name` (text), `phone` (text), `budget_range` (text), `property_type` (text), `location_preference` (text), `timeline` (text), `intent_score` (int4), `status` (text), `created_at` (timestamptz, default now())."
      },
      "typeVersion": 1
    },
    {
      "id": "0f7230cf-fcfb-4a81-810e-2e8742e05ca7",
      "name": "Save Lead to Supabase",
      "type": "n8n-nodes-base.supabase",
      "position": [
        992,
        528
      ],
      "parameters": {
        "operation": "insert"
      },
      "credentials": {
        "supabaseApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "9bd60be1-da24-41cf-b231-31828c2683bc",
      "name": "New WhatsApp Message",
      "type": "n8n-nodes-base.whatsAppTrigger",
      "position": [
        -80,
        528
      ],
      "parameters": {
        "options": {},
        "updates": [
          "messages"
        ]
      },
      "credentials": {
        "whatsAppTriggerApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "94694b26-1f02-4619-9b11-ccbf84bb2aa4",
      "name": "Set Configuration",
      "type": "n8n-nodes-base.set",
      "position": [
        224,
        528
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "5de7e0a1-9852-4379-9168-3513c8d5ad9d",
              "name": "agent_whatsapp_number",
              "type": "string",
              "value": "REPLACE_WITH_AGENT_WHATSAPP_NUMBER"
            },
            {
              "id": "59b2aa9f-cb02-4bd3-a9e0-cd8b20622602",
              "name": "high_score_threshold",
              "type": "string",
              "value": "7"
            },
            {
              "id": "50aec146-6547-4d1b-b9a1-e723565bcf3a",
              "name": "medium_score_threshold",
              "type": "string",
              "value": "4"
            },
            {
              "id": "f2165ff6-1658-4ccb-a782-5d0ec4a1a762",
              "name": "supabase_table_name",
              "type": "string",
              "value": "leads"
            },
            {
              "id": "4881dc5b-a0cb-4728-b708-3a0bf03bdb88",
              "name": "lead_message",
              "type": "string",
              "value": "={{ $json.messages[0].text.body }}"
            },
            {
              "id": "f45d52f1-6e59-4bdd-9bbe-5b2a99036c40",
              "name": "lead_phone",
              "type": "string",
              "value": "={{ $json.messages[0].from }}"
            },
            {
              "id": "a7da3813-67bf-4003-8aee-5681be119a1f",
              "name": "lead_contact_name",
              "type": "string",
              "value": "={{ $json.contacts[0].profile.name }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "2fdfce87-5e41-4bae-be70-9adacc08623d",
      "name": "Classify Lead Intent",
      "type": "@n8n/n8n-nodes-langchain.chainLlm",
      "position": [
        480,
        528
      ],
      "parameters": {
        "text": "=You are a real estate lead qualification assistant. Read the WhatsApp message below and extract structured lead information.\n\nSender name: {{ $json.lead_contact_name }}\nMessage: {{ $json.lead_message }}\n\nExtract: budget range, property type (residential/commercial/land), preferred location, purchase timeline, and an intent_score from 1-10 (10 = ready to buy now, 1 = just browsing). If a field isn't mentioned, use \"not specified\".",
        "batching": {},
        "promptType": "define",
        "hasOutputParser": true
      },
      "typeVersion": 1.8
    },
    {
      "id": "2c749399-2232-4bf6-b605-51d06a9bfa89",
      "name": "Gemini Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
      "position": [
        432,
        752
      ],
      "parameters": {
        "options": {},
        "modelName": "models/gemini-2.5-flash"
      },
      "credentials": {
        "googlePalmApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.1
    },
    {
      "id": "dc085e35-1490-4a88-b362-4d382feecf9d",
      "name": "Lead Data Parser",
      "type": "@n8n/n8n-nodes-langchain.outputParserStructured",
      "position": [
        656,
        752
      ],
      "parameters": {
        "jsonSchemaExample": "{\n  \"type\": \"object\",\n  \"properties\": {\n    \"budget_range\": { \"type\": \"string\" },\n    \"property_type\": { \"type\": \"string\" },\n    \"location_preference\": { \"type\": \"string\" },\n    \"timeline\": { \"type\": \"string\" },\n    \"intent_score\": { \"type\": \"number\" }\n  },\n  \"required\": [\"budget_range\", \"property_type\", \"location_preference\", \"timeline\", \"intent_score\"]\n}"
      },
      "typeVersion": 1.3
    },
    {
      "id": "b1dea3c5-b8a0-444f-84db-10709ccab51e",
      "name": "Route By Intent Score",
      "type": "n8n-nodes-base.switch",
      "position": [
        1344,
        512
      ],
      "parameters": {
        "rules": {
          "values": [
            {
              "conditions": {
                "options": {
                  "version": 3,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "3a7d812a-627e-4d2f-8322-c9e32d4bc18d",
                    "operator": {
                      "type": "number",
                      "operation": "gte"
                    },
                    "leftValue": "={{ $json.output.intent_score }}",
                    "rightValue": "={{ $('Set Configuration').item.json.high_score_threshold }}"
                  }
                ]
              }
            },
            {
              "conditions": {
                "options": {
                  "version": 3,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "a46bd294-c7ba-4896-ac77-0fb0e64c736b",
                    "operator": {
                      "type": "number",
                      "operation": "gte"
                    },
                    "leftValue": "={{ $json.output.intent_score }}",
                    "rightValue": "={{ $('Set Configuration').item.json.medium_score_threshold }}"
                  }
                ]
              }
            }
          ]
        },
        "options": {
          "fallbackOutput": "extra"
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "79b415b6-7ac0-45f1-b427-fea2e5c1307b",
      "name": "Log Only (No Alert)",
      "type": "n8n-nodes-base.noOp",
      "position": [
        1760,
        752
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "97fd06bc-c47b-4ccf-8f0e-c0958f3ffc58",
      "name": "Alert Agent via WhatsApp",
      "type": "n8n-nodes-base.whatsApp",
      "position": [
        1744,
        528
      ],
      "parameters": {
        "textBody": "=\ud83d\udd25 High-intent lead: {{ $('Set Configuration').item.json.lead_contact_name }} ({{ $('Set Configuration').item.json.lead_phone }})\nBudget: {{ $json.output.budget_range }}\nProperty type: {{ $json.output.property_type }}\nLocation: {{ $json.output.location_preference }}\nTimeline: {{ $json.output.timeline }}\nIntent score: {{ $json.output.intent_score }}/10",
        "operation": "send",
        "phoneNumberId": "REPLACE_WITH_WHATSAPP_PHONE_NUMBER_ID",
        "additionalFields": {},
        "recipientPhoneNumber": "={{ $('Set Configuration').item.json.agent_whatsapp_number }}"
      },
      "credentials": {
        "whatsAppApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "435ce0fb-73f8-4071-a039-c1db27f28c34",
      "name": "Switch Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1424,
        272
      ],
      "parameters": {
        "color": 7,
        "width": 420,
        "height": 216,
        "content": "### 4\ufe0f\u20e3 Route by Score\nAdjust the thresholds in **Set Configuration** to change how aggressively leads are filtered before alerting the agent."
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "binaryMode": "separate",
    "executionOrder": "v1"
  },
  "versionId": "b90924a7-96d4-4591-b162-160a7846a281",
  "nodeGroups": [],
  "connections": {
    "Lead Data Parser": {
      "ai_outputParser": [
        [
          {
            "node": "Classify Lead Intent",
            "type": "ai_outputParser",
            "index": 0
          }
        ]
      ]
    },
    "Gemini Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "Classify Lead Intent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Set Configuration": {
      "main": [
        [
          {
            "node": "Classify Lead Intent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Classify Lead Intent": {
      "main": [
        [
          {
            "node": "Save Lead to Supabase",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "New WhatsApp Message": {
      "main": [
        [
          {
            "node": "Set Configuration",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Route By Intent Score": {
      "main": [
        [
          {
            "node": "Alert Agent via WhatsApp",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Log Only (No Alert)",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Log Only (No Alert)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Save Lead to Supabase": {
      "main": [
        [
          {
            "node": "Route By Intent Score",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}