{
  "id": "mGR2MeapjAda5oGFf0A-S",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "Automate real estate lead capture, smart routing, and reporting using n8n",
  "tags": [
    {
      "id": "s9fvJ4dcQhStsrSi",
      "name": "Real Estate",
      "createdAt": "2026-01-26T11:32:35.060Z",
      "updatedAt": "2026-01-26T11:32:35.060Z"
    },
    {
      "id": "viwlOeYf5G0hr2UB",
      "name": "Airtable",
      "createdAt": "2026-01-26T11:32:35.001Z",
      "updatedAt": "2026-01-26T11:32:35.001Z"
    }
  ],
  "nodes": [
    {
      "id": "b4075f28-c730-4a73-abda-0ca8c401ccf4",
      "name": "Combine All Lead Sources",
      "type": "n8n-nodes-base.merge",
      "position": [
        1184,
        1376
      ],
      "parameters": {},
      "typeVersion": 3.2
    },
    {
      "id": "1d5d54af-9434-485f-9511-1ab38c99f02f",
      "name": "Check for Duplicates in CRM",
      "type": "n8n-nodes-base.compareDatasets",
      "position": [
        1856,
        1344
      ],
      "parameters": {
        "options": {},
        "mergeByFields": {
          "values": [
            {
              "field1": "Email",
              "field2": "Email"
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "521165ee-988b-4c5e-a156-0e7a4ce2d22b",
      "name": "Remove Duplicate Leads",
      "type": "n8n-nodes-base.removeDuplicates",
      "position": [
        1408,
        1376
      ],
      "parameters": {
        "compare": "selectedFields",
        "options": {},
        "fieldsToCompare": "Email, Phone number"
      },
      "typeVersion": 2
    },
    {
      "id": "5e2be9bd-30d3-4f77-9584-abd223ccb0f4",
      "name": "Weekly Report Schedule",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        480,
        2384
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "weeks",
              "triggerAtDay": [
                1
              ],
              "triggerAtHour": 9
            }
          ]
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "64b54ec9-b55d-47cb-baf6-9a4a8fa01066",
      "name": "Aggregate Report Data",
      "type": "n8n-nodes-base.aggregate",
      "position": [
        1216,
        2224
      ],
      "parameters": {
        "options": {},
        "fieldsToAggregate": {
          "fieldToAggregate": [
            {
              "renameField": true,
              "outputFieldName": "total_leads",
              "fieldToAggregate": "id"
            },
            {
              "renameField": true,
              "outputFieldName": "leads_by_source",
              "fieldToAggregate": "Source"
            },
            {
              "renameField": true,
              "outputFieldName": "leads_by_status",
              "fieldToAggregate": "Lead Status"
            },
            {
              "renameField": true,
              "outputFieldName": "leads_qualified?",
              "fieldToAggregate": "Qualified"
            }
          ]
        }
      },
      "typeVersion": 1
    },
    {
      "id": "0fd5f029-5589-4a1f-8523-e5c9d766f096",
      "name": "Format Weekly Report",
      "type": "n8n-nodes-base.set",
      "position": [
        1744,
        2336
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "id-1",
              "name": "report_title",
              "type": "string",
              "value": "Weekly Lead Report"
            },
            {
              "id": "id-2",
              "name": "report_period",
              "type": "string",
              "value": "={{ $now.minus({days: 7}).toFormat('MMM dd') + ' - ' + $now.toFormat('MMM dd, yyyy') }}"
            },
            {
              "id": "id-3",
              "name": "total_leads",
              "type": "number",
              "value": "={{ $json.total_leads.length }}"
            },
            {
              "id": "id-4",
              "name": "website_form_leads_source",
              "type": "string",
              "value": "={{ $json.leads_by_source.filter(status => status === 'Website Form').length }}"
            },
            {
              "id": "bfc1006a-58a5-4e36-9e67-2307abe72ed6",
              "name": "facebook_ads_leads_source",
              "type": "string",
              "value": "={{ $json.leads_by_source.filter(status => status === 'WhatsApp Form').length }}"
            },
            {
              "id": "id-5",
              "name": "leads_contacted",
              "type": "number",
              "value": "={{ $json.leads_by_status.filter(status => status && status !== 'New').length }}\n"
            },
            {
              "id": "id-6",
              "name": "leads_not_contacted",
              "type": "number",
              "value": "={{ $json.leads_by_status.filter(status => !status || status === 'New').length }}\n"
            },
            {
              "id": "id-7",
              "name": "total_duplicates_leads",
              "type": "number",
              "value": "={{ $json.count }}"
            },
            {
              "id": "id-8",
              "name": "contact_rate",
              "type": "string",
              "value": "={{ \n(() => {\n  const contacted = $json.leads_by_status.filter(s => s === 'Contacted').length;\n  const total = $json.total_leads.length;\n  const value = (contacted / total) * 100;\n\n  return Number.isFinite(value)\n    ? value.toFixed(1) + '%'\n    : '';\n})()\n}}\n"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "e18393cf-a30d-4844-bc95-bc65d5e83f37",
      "name": "Send Weekly Report",
      "type": "n8n-nodes-base.gmail",
      "position": [
        1984,
        2336
      ],
      "parameters": {
        "sendTo": "user@example.com",
        "message": "=<html>\n<head>\n  <style>\n    body { font-family: Arial, sans-serif; color: #333; }\n    h1 { color: #2c3e50; }\n    .metric { background: #f8f9fa; padding: 15px; margin: 10px 0; border-left: 4px solid #3498db; }\n    .metric-title { font-weight: bold; color: #2c3e50; }\n    .metric-value { font-size: 24px; color: #3498db; margin: 5px 0; }\n    table { width: 100%; border-collapse: collapse; margin: 20px 0; }\n    th, td { padding: 12px; text-align: left; border-bottom: 1px solid #ddd; }\n    th { background-color: #3498db; color: white; }\n    tr:hover { background-color: #f5f5f5; }\n  </style>\n</head>\n<body>\n  <h1>Weekly Lead Report</h1>\n  <p><strong>Period:</strong> {{ $json.report_period }}</p>\n  \n  <div class=\"metric\">\n    <div class=\"metric-title\">Total Leads</div>\n    <div class=\"metric-value\">{{ $json.total_leads }}</div>\n  </div>\n  \n  <div class=\"metric\">\n    <div class=\"metric-title\">Duplicates Detected</div>\n    <div class=\"metric-value\">{{ $json.total_duplicates_leads }}</div>\n  </div>\n  \n  <div class=\"metric\">\n    <div class=\"metric-title\">Contact Rate</div>\n    <div class=\"metric-value\">{{ $json.contact_rate }}</div>\n  </div>\n  \n  <h2>Leads by Source</h2>\n  <table>\n    <tr>\n      <th>Source</th>\n      <th>Count</th>\n    </tr>\n    <tr>\n      <td>Website Forms</td>\n      <td>{{ $json.website_form_leads_source }}</td>\n    </tr>\n    <tr>\n      <td>Facebook Ads</td>\n      <td>{{ $json.facebook_ads_leads_source }}</td>\n    </tr>\n  \n  <h2>Contact Status</h2>\n  <table>\n    <tr>\n      <th>Status</th>\n      <th>Count</th>\n    </tr>\n    <tr>\n      <td>Contacted</td>\n      <td>{{ $json.leads_contacted }}</td>\n    </tr>\n    <tr>\n      <td>Not Contacted</td>\n      <td>{{ $json.leads_not_contacted }}</td>\n    </tr>\n  </table>\n</body>\n</html>",
        "options": {
          "appendAttribution": false
        },
        "subject": "={{ 'Weekly Lead Report: ' + $json.report_period }}"
      },
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "91738356-a921-47e7-90a0-96bdb6cb9232",
      "name": "Typeform Trigger",
      "type": "n8n-nodes-base.typeformTrigger",
      "position": [
        112,
        1632
      ],
      "parameters": {
        "formId": "QPCD9YG4"
      },
      "credentials": {
        "typeformApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.1
    },
    {
      "id": "c35fd8b6-15b5-43de-8ed5-22f78dc6343f",
      "name": "WhatsApp Trigger",
      "type": "n8n-nodes-base.whatsAppTrigger",
      "position": [
        0,
        144
      ],
      "parameters": {
        "options": {},
        "updates": [
          "messages"
        ]
      },
      "credentials": {
        "whatsAppTriggerApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "c1366bee-f0ec-429f-829c-4b2086d36cd2",
      "name": "Route by Location/Property Type1",
      "type": "n8n-nodes-base.switch",
      "position": [
        2080,
        1184
      ],
      "parameters": {
        "rules": {
          "values": [
            {
              "outputKey": "Single-Family",
              "conditions": {
                "options": {
                  "version": 3,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "1a78f7da-a53a-4816-bc37-1cb6795a15d2",
                    "operator": {
                      "name": "filter.operator.equals",
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json['What type of property are you interested in?'].toLowerCase() }}",
                    "rightValue": "single-family"
                  }
                ]
              },
              "renameOutput": true
            },
            {
              "outputKey": "Multi-Family",
              "conditions": {
                "options": {
                  "version": 3,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "0b19ddfc-d1ec-4c07-894c-5e702051a7f3",
                    "operator": {
                      "name": "filter.operator.equals",
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json['What type of property are you interested in?'].toLowerCase() }}",
                    "rightValue": "multi-family"
                  }
                ]
              },
              "renameOutput": true
            },
            {
              "outputKey": "Condo",
              "conditions": {
                "options": {
                  "version": 3,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "e6e46194-9fac-40a2-8a97-bfdef76cb6c3",
                    "operator": {
                      "name": "filter.operator.equals",
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json['What type of property are you interested in?'].toLowerCase() }}",
                    "rightValue": "condo"
                  }
                ]
              },
              "renameOutput": true
            },
            {
              "outputKey": "Investment-Property",
              "conditions": {
                "options": {
                  "version": 3,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "afc8bb08-1b73-4c2c-88f6-7322287d44b6",
                    "operator": {
                      "name": "filter.operator.equals",
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json['What type of property are you interested in?'].toLowerCase() }}",
                    "rightValue": "investment property"
                  }
                ]
              },
              "renameOutput": true
            }
          ]
        },
        "options": {
          "fallbackOutput": "extra"
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "45702fe8-c152-49e2-b035-f8ea0d1f68c3",
      "name": "Send a message",
      "type": "n8n-nodes-base.gmail",
      "position": [
        3488,
        1360
      ],
      "parameters": {
        "sendTo": "={{ $('Round-Robin Agent Assignment1').item.json.assigned_agent }}",
        "message": "=<html>\n<head>\n  <style>\n    body { font-family: Arial, sans-serif; line-height: 1.6; color: #333; }\n    .container { max-width: 600px; margin: 0 auto; padding: 20px; }\n    .header { background-color: #0066cc; color: white; padding: 20px; text-align: center; }\n    .content { background-color: #f9f9f9; padding: 20px; margin-top: 20px; }\n    .field { margin-bottom: 15px; }\n    .label { font-weight: bold; color: #0066cc; }\n    .value { margin-left: 10px; }\n    .action { background-color: #fff3cd; border-left: 4px solid #ffc107; padding: 15px; margin-top: 20px; }\n    .footer { text-align: center; margin-top: 20px; font-size: 12px; color: #666; }\n  </style>\n</head>\n<body>\n  <div class=\"container\">\n    <div class=\"header\">\n      <h1>New Lead Assigned</h1>\n    </div>\n    <div class=\"content\">\n      <div class=\"field\">\n        <span class=\"label\">Name:</span>\n        <span class=\"value\">{{ $json.fields['First name'] }} {{ $json.fields['Last name'] }}</span>\n      </div>\n      <div class=\"field\">\n        <span class=\"label\">Email:</span>\n        <span class=\"value\">{{ $json.fields.Email }}</span>\n      </div>\n      <div class=\"field\">\n        <span class=\"label\">Phone:</span>\n        <span class=\"value\">{{ $json.fields['Phone number'] }}</span>\n      </div>\n      <div class=\"field\">\n        <span class=\"label\">Property Type:</span>\n        <span class=\"value\">{{ $json.fields['Property Type'] }}</span>\n      </div>\n      <div class=\"field\">\n        <span class=\"label\">Source:</span>\n        <span class=\"value\">{{ $json.fields.Source }}</span>\n      </div>\n      <div class=\"field\">\n        <span class=\"label\">Location:</span>\n        <span class=\"value\">{{ $json.fields.Location }}</span>\n      </div>\n      <div class=\"action\">\n        <strong>Recommended Next Action:</strong>\n        <p>{{ $json.fields[\"Qualified\"] === \"Yes\" ? \"Contact Now\" : \"Don't Contact\" }}\n</p>\n      </div>\n    </div>\n    <div class=\"footer\">\n      <p>This lead was automatically assigned to you based on your expertise and availability.</p>\n    </div>\n  </div>\n</body>\n</html>",
        "options": {
          "appendAttribution": false
        },
        "subject": "={{ 'New Lead Assigned: ' + $('Round-Robin Agent Assignment1').item.json['First name'] }} {{ $('Round-Robin Agent Assignment1').item.json['Last name'] }}"
      },
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "00677f1e-e630-4f25-adee-8e156817a2ca",
      "name": "Aggregate",
      "type": "n8n-nodes-base.aggregate",
      "position": [
        2528,
        1264
      ],
      "parameters": {
        "options": {},
        "aggregate": "aggregateAllItemData"
      },
      "typeVersion": 1
    },
    {
      "id": "b30f5c3b-228a-4fa8-9ae8-ac1673dce6e9",
      "name": "Basic LLM Chain",
      "type": "@n8n/n8n-nodes-langchain.chainLlm",
      "position": [
        2752,
        1264
      ],
      "parameters": {
        "text": "=You are a lead qualifier expert. Your task is to qualify real estate leads depending on their answers in the pre-qualifier form.\n\n## Criteria for qualification\n- Budget must be $600,000 or more\n- Must be in one of the target markets: Texas, Florida, or Arizona\n- Must select: Multi-family, Condo or Investment property\n- Must buy within less than 6 months\n- Must be \u201cYes\u201d or \u201cNo\u201d but willing to get pre-approved, or paid with cash\n- Must not already be working with another agent\n\nOnly output the result: Yes / No\n\nThe responses from the form: {{ JSON.stringify($json.data) }}",
        "batching": {},
        "promptType": "define"
      },
      "typeVersion": 1.9
    },
    {
      "id": "8d8e6447-88e6-40ed-a14e-f178f8863cc3",
      "name": "OpenAI Chat Model2",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        2832,
        1488
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4.1-mini"
        },
        "options": {},
        "builtInTools": {}
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "5c6fb3be-79a6-45a7-a4b8-53cb442907b5",
      "name": "Search records",
      "type": "n8n-nodes-base.airtable",
      "position": [
        1632,
        1312
      ],
      "parameters": {
        "base": {
          "__rl": true,
          "mode": "list",
          "value": "appBnug5XIRAWl5sK",
          "cachedResultUrl": "https://airtable.com/appBnug5XIRAWl5sK",
          "cachedResultName": "N8n"
        },
        "table": {
          "__rl": true,
          "mode": "list",
          "value": "tblaHgYnpXzZl0zRH",
          "cachedResultUrl": "https://airtable.com/appBnug5XIRAWl5sK/tblaHgYnpXzZl0zRH",
          "cachedResultName": "Real Estate Qualifier"
        },
        "options": {},
        "operation": "search"
      },
      "credentials": {
        "airtableTokenApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "e85e52ae-22b0-499c-9ec0-ad35f56d9cd1",
      "name": "Get Records",
      "type": "n8n-nodes-base.airtable",
      "position": [
        720,
        2224
      ],
      "parameters": {
        "base": {
          "__rl": true,
          "mode": "list",
          "value": "appBnug5XIRAWl5sK",
          "cachedResultUrl": "https://airtable.com/appBnug5XIRAWl5sK",
          "cachedResultName": "N8n"
        },
        "table": {
          "__rl": true,
          "mode": "list",
          "value": "tblaHgYnpXzZl0zRH",
          "cachedResultUrl": "https://airtable.com/appBnug5XIRAWl5sK/tblaHgYnpXzZl0zRH",
          "cachedResultName": "Real Estate Qualifier"
        },
        "options": {},
        "operation": "search"
      },
      "credentials": {
        "airtableTokenApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "c5100352-5b20-409f-b74c-1df97e479f9f",
      "name": "No Operation, do nothing",
      "type": "n8n-nodes-base.noOp",
      "position": [
        528,
        192
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "b44f8962-6509-4703-abc3-22e84125d0fa",
      "name": "Lead Collection Agent",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        272,
        416
      ],
      "parameters": {
        "text": "={{ $json.messages[0].text.body }}",
        "options": {
          "systemMessage": "=You are a professional real estate lead qualification assistant collecting information via WhatsApp. Your job is to ask questions in a specific order and collect all required information.\n\nQUESTION ORDER (ask ONE question at a time):\n\nFirst name (required)\n\nLast name (optional - if they skip, move on)\n\nPhone number (required)\n\nEmail (required)\n\nBudget range (required) - Options:\nA. $500,000-$600,000\nB. $600,001-$700,000\nC. $700,001-$1,000,000\nD. $1,000,001-$2,000,000\nE. Other\n\nHow do you plan to purchase the property? (required) - Options:\nA. Finance the property with a mortgage\nB. Pay with cash\n\nCONDITIONAL: If they chose Finance (A) in question 6, ask:\nAre you pre-approved for a mortgage, or currently working with a lender?\nOptions:\nA. Yes I'm pre-approved\nB. Yes I'm working with a lender but not yet pre-approved\nC. No I'm not working with a lender\nIf they chose Cash (B), SKIP this question.\nWhat type of property are you interested in? (required) - Options:\nA. Single-Family\nB. Multi-family\nC. Condo\nD. Investment Property\nE. Other\n\nWhere are you looking to purchase a property? (required) - Options:\nA. New York\nB. Chicago\nC. Texas\nD. Florida\nE. Other\n\nWhen do you plan to purchase a property? (required) - Options:\nA. Immediately\nB. 1-3 months\nC. 4-6 months\nD. Other\n\nAre you currently working with a real estate agent? (required) - Options:\nA. No\nB. Yes\n\n\n\u2705 ADDITIONAL LOGIC REQUIREMENTS (NEW)\n- Maintain a collectionComplete flag at all times.\n- If ANY required information is missing or unanswered, set collectionComplete to false.\n- Only set collectionComplete to true after all required questions have been successfully answered and validated, including conditional question 7 when applicable.\n- When collectionComplete becomes true, send a final WhatsApp message that:\n  - Thanks the lead\n  - Displays ALL collected information in a clear, structured summary\n\n\n\u2705 FINAL MESSAGE FORMAT WHEN collectionComplete = true (NEW)\nWhen all required information is collected, send a message in this format:\n\nThanks {{first_name}}! \ud83c\udf89 Here\u2019s a summary of what I\u2019ve got:\n\n\u2022 First Name: {{first_name}}\n\u2022 Last Name: {{last_name || \"Not provided\"}}\n\u2022 Phone Number: {{phone}}\n\u2022 Email: {{email}}\n\u2022 Budget Range: {{budget}}\n\u2022 Purchase Method: {{purchase_method}}\n\u2022 Mortgage Status: {{mortgage_status || \"N/A (Cash purchase)\"}}\n\u2022 Property Type: {{property_type}}\n\u2022 Location: {{location}}\n\u2022 Purchase Timeline: {{timeline}}\n\u2022 Working with an Agent: {{agent_status}}\n\nWe\u2019ll be in touch shortly with next steps!"
        },
        "promptType": "define"
      },
      "typeVersion": 3.1
    },
    {
      "id": "ffe4bc87-e32d-4d10-979e-4df66053b9d1",
      "name": "OpenAI Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        544,
        784
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4.1-mini"
        },
        "options": {},
        "builtInTools": {}
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "54bf7bbf-d58d-4e9a-9188-46045b2c71be",
      "name": "Simple Memory",
      "type": "@n8n/n8n-nodes-langchain.memoryBufferWindow",
      "position": [
        368,
        608
      ],
      "parameters": {
        "sessionKey": "={{ $(\"WhatsApp Trigger\").item.json.messages[0].from }}",
        "sessionIdType": "customKey",
        "contextWindowLength": 20
      },
      "typeVersion": 1.3
    },
    {
      "id": "abd5534e-ddce-49d3-a422-1a9629c72a65",
      "name": "Extract Lead Info",
      "type": "@n8n/n8n-nodes-langchain.chainLlm",
      "position": [
        240,
        1120
      ],
      "parameters": {
        "text": "={{ $('Lead Collection Agent').item.json.output }}",
        "batching": {},
        "messages": {
          "messageValues": [
            {
              "message": "You are a data extraction assistant.\n\nYour task is to extract structured real estate lead information from the provided input and return it in a format that STRICTLY matches the required structured output schema.\n\nINPUT CONTEXT:\n- The input contains lead information that has already been collected and validated.\n\nEXTRACTION RULES:\n- Populate each field using the collected lead data.\n- Do NOT invent or infer information.\n- If an optional field is missing, return an empty string.\n- If purchaseMethod is \"Pay with cash\", set preApprovalStatus to an empty string.\n- If purchaseMethod is \"Finance the property with a mortgage\", populate preApprovalStatus with the collected mortgage status.\n- Normalize values to clear, human-readable strings (no option letters like \"A\", \"B\", etc.).\n\nFIELD MAPPING GUIDELINES:\n- firstName \u2192 lead\u2019s first name\n- lastName \u2192 lead\u2019s last name (or empty string if not provided)\n- phoneNumber \u2192 lead\u2019s phone number\n- email \u2192 lead\u2019s email address\n- budgetRange \u2192 selected budget range text\n- purchaseMethod \u2192 \"Pay with cash\" or \"Finance the property with a mortgage\"\n- preApprovalStatus \u2192 mortgage/pre-approval status (conditional)\n- propertyType \u2192 selected property type\n- location \u2192 selected location\n- timeline \u2192 selected purchase timeline\n- hasAgent \u2192 \"Yes\" or \"No\"\n- collectionComplete \u2192 true\n\nVALIDATION RULES:\n- Required fields must NOT be empty.\n- Optional fields may be empty strings.\n- collectionComplete MUST be true.\n\nOUTPUT RULES:\n- Output MUST be valid JSON.\n- Output MUST strictly conform to the structured output parser schema.\n- Do NOT include any explanatory text, comments, or formatting outside the JSON object.\n- Do NOT wrap the JSON in markdown.\n\nReturn ONLY the JSON object."
            }
          ]
        },
        "promptType": "define",
        "hasOutputParser": true
      },
      "typeVersion": 1.9
    },
    {
      "id": "33cf1b46-e9c3-412b-8755-83bd3490a6cd",
      "name": "Structured Output Parser",
      "type": "@n8n/n8n-nodes-langchain.outputParserStructured",
      "position": [
        480,
        1296
      ],
      "parameters": {
        "schemaType": "manual",
        "inputSchema": "{\n  \"type\": \"object\",\n  \"properties\": {\n    \"First name\": {\n      \"type\": \"string\",\n      \"description\": \"Lead first name (required)\"\n    },\n    \"Last name\": {\n      \"type\": \"string\",\n      \"description\": \"Lead last name (optional)\"\n    },\n    \"Phone number\": {\n      \"type\": \"string\",\n      \"description\": \"Lead phone number (required)\"\n    },\n    \"Email\": {\n      \"type\": \"string\",\n      \"description\": \"Lead email address (required)\"\n    },\n    \"What is your budget range?\": {\n      \"type\": \"string\",\n      \"description\": \"Budget range selected from options (required)\"\n    },\n    \"How do you plan to purchase the property?\": {\n      \"type\": \"string\",\n      \"description\": \"How they plan to purchase: Finance or Cash (required)\"\n    },\n    \"Are you pre-approved for a mortgage, or currently working with a lender?\": {\n      \"type\": \"string\",\n      \"description\": \"Pre-approval status - only if financing (conditional)\"\n    },\n    \"What type of property are you interested in?\": {\n      \"type\": \"string\",\n      \"description\": \"Type of property interested in (required)\"\n    },\n    \"Where are you looking to purchase a property?\": {\n      \"type\": \"string\",\n      \"description\": \"Where they want to purchase (required)\"\n    },\n    \"When do you plan to purchase a property?\": {\n      \"type\": \"string\",\n      \"description\": \"When they plan to purchase (required)\"\n    },\n    \"Are you currently working with a real estate agent?\": {\n      \"type\": \"string\",\n      \"description\": \"Whether working with an agent (required)\"\n    },\n    \"collectionComplete\": {\n      \"type\": \"boolean\",\n      \"description\": \"Whether all required information has been collected\"\n    }\n  },\n  \"required\": [\"First name\", \"Phone number\", \"Email\", \"What is your budget range?\", \"How do you plan to purchase the property?\", \"What type of property are you interested in?\", \"Where are you looking to purchase a property?\", \"When do you plan to purchase a property?\", \"Are you currently working with a real estate agent?\", \"collectionComplete\"]\n}"
      },
      "typeVersion": 1.3
    },
    {
      "id": "c16d9f6f-05b1-4673-80b7-3176ecceb905",
      "name": "No Operation, do nothing1",
      "type": "n8n-nodes-base.noOp",
      "position": [
        320,
        1360
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "acfe3b63-6637-443b-aa54-2edd1c2bc6ff",
      "name": "Round-Robin Agent Assignment1",
      "type": "n8n-nodes-base.code",
      "position": [
        2304,
        1264
      ],
      "parameters": {
        "jsCode": "// Round-Robin Agent Assignment Logic\n// Assigns agents based on property type from AI agent output\n\nconst agentPools = {\n  'single-family': [\n    'user@example.com',\n    'user@example.com'\n  ],\n  'multi-family': [\n    'user@example.com',\n    'user@example.com',\n    'user@example.com'\n  ],\n  'condo': [\n    'user@example.com',\n    'user@example.com',\n    'user@example.com'\n  ],\n  'investment property': [\n    'user@example.com',\n    'user@example.com',\n    'user@example.com'\n  ],\n  'others': [\n    'user@example.com',\n    'user@example.com'\n  ],\n  'default-unassigned': [\n    'user@example.com'\n  ]\n};\n\n// Get incoming item\nconst item = $input.item.json;\n\n// Read property type (exact field name)\nconst rawCategory =\n  item[\"What type of property are you interested in?\"] ||\n  'default-unassigned';\n\nconst category = rawCategory\n  .trim()\n  .toLowerCase()\n  .replace(/\\s+/g, '-');\n\n// Select agent pool\nconst agents = agentPools[category] || agentPools['default-unassigned'];\n\n// \u2705 Correct way to access static data\nconst staticData = $getWorkflowStaticData('node');\n\nif (!staticData.agentIndexes) {\n  staticData.agentIndexes = {};\n}\n\nif (staticData.agentIndexes[category] === undefined) {\n  staticData.agentIndexes[category] = 0;\n}\n\n// Assign agent\nconst currentIndex = staticData.agentIndexes[category];\nconst assignedAgent = agents[currentIndex];\n\n// Advance round-robin\nstaticData.agentIndexes[category] =\n  (currentIndex + 1) % agents.length;\n\n// Return result\nreturn {\n  ...item,\n  lead_status: \"New\",\n  assigned_agent: assignedAgent,\n  assignment_category: category,\n  assignment_timestamp: new Date().toISOString()\n};\n"
      },
      "typeVersion": 2
    },
    {
      "id": "0c6207bb-9299-4d75-ac8d-efdc616159cf",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1184,
        928
      ],
      "parameters": {
        "color": 3,
        "width": 928,
        "height": 1392,
        "content": "# Automate real estate lead capture, smart routing, and reporting using n8n\n\n\n## How it works\n### This workflow automates the full lifecycle of real estate leads, from intake to reporting.\n\n- Collects leads from WhatsApp and website forms\n- Can be extended to Facebook and Google Ads\n- Validates and structures lead information using AI\n- Checks and removes duplicate leads\n- Qualifies, routes, and assigns leads automatically\n- Generates weekly lead and duplicate reports\n\n\n\n## \ud83d\udee0 Setup steps\n\nImport the .json file into your n8n instance.\n\n### 1. Connect the required credentials:\n- WhatsApp Trigger  (**Auth Connection**)\n- WhatsApp Business Cloud (**Access Token**) \n- OpenAI API Key\n- Airtable API Key (Access Token)\n- Gmail\n- Slack API Key (Access Token)\n\n\n### 2. Configure your data sources:\n- Update the Airtable base and table names to match your CRM structure\n- Ensure required fields (Email, First name, What is your budget range?, etc.) exist\n\n\n### 3. Customize business logic:\n- Update agent pools and routing rules\n- Adjust AI prompts if needed\n- Review deduplication and reporting settings\n\n\n### 4. Activate the workflow:\n- Click **Publish** to activate the workflow\n- Send a test lead via WhatsApp or website form to confirm everything works\n\n\n\n\n## Optional\n- ### This workflow is designed to be easily extended with additional lead sources such as Facebook and Google Ads.\n- ### Weekly reporting can be extracted into a standalone workflow\n   ### Useful if you want to manage reporting separately from lead processing\n\n\n\n### \ud83d\udcec Contact \n#### For Enquiries: buzanalytics@gmail.com\nThank you for exploring this workflow!"
      },
      "typeVersion": 1
    },
    {
      "id": "e8a87170-0b1e-4e8f-89d0-5bef5f9a4f96",
      "name": "Info Completeness Check",
      "type": "@n8n/n8n-nodes-langchain.chainLlm",
      "position": [
        208,
        800
      ],
      "parameters": {
        "text": "={{ $('Lead Collection Agent').item.json.output }}",
        "batching": {},
        "messages": {
          "messageValues": [
            {
              "message": "You are a form completion validation assistant.  Your only task is to determine whether all REQUIRED real estate lead information has been collected.  You will receive an object containing the collected lead data.  REQUIRED FIELDS: - first_name - phone - email - budget - purchase_method - property_type - location - timeline - agent_status  CONDITIONAL REQUIRED FIELD: - mortgage_status is REQUIRED ONLY if purchase_method = \"Finance the property with a mortgage\" - mortgage_status is NOT required if purchase_method = \"Pay with cash\"  OPTIONAL FIELD: - last_name (may be missing or empty without affecting completion)  VALIDATION RULES: - A field is considered missing if it is null, undefined, empty, or an empty string - Budget, purchase_method, and other fields must contain a valid value (not just text like \"other\" without a value) - If ANY required field is missing or invalid, the form is NOT complete  OUTPUT RULES: - If ALL required fields (including conditional ones) are present and valid, output \"Yes\", otherwise, output \"No\"  OUTPUT FORMAT (STRICT): Return ONLY one of the following, with no additional text: - Yes - No"
            }
          ]
        },
        "promptType": "define"
      },
      "typeVersion": 1.9
    },
    {
      "id": "c16b021d-1183-4f39-8ee1-59355e1bd1eb",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1376,
        960
      ],
      "parameters": {
        "color": 4,
        "width": 608,
        "height": 656,
        "content": "## Deduplication Logic\n\nPrevents the same lead from being processed twice.\n\n- Removes duplicates within the same workflow run\n- Handles retries and rapid re-submissions\n-  Searches the CRM using email address\n- Compares incoming leads with existing records\n- Flags new vs existing leads\n- Prevents double assignment and notifications\n"
      },
      "typeVersion": 1
    },
    {
      "id": "bfe44d71-f6c7-479d-a7f3-747de1bf829d",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2032,
        1504
      ],
      "parameters": {
        "color": 7,
        "width": 208,
        "height": 288,
        "content": "## Store Duplicates in CRM"
      },
      "typeVersion": 1
    },
    {
      "id": "317b4f32-c166-4038-8f35-38d6e6010f81",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2032,
        960
      ],
      "parameters": {
        "color": 4,
        "width": 400,
        "height": 512,
        "content": "## Agent Assignment (Round-Robin)\n\nAutomatically assigns agents:\n- Based on property category\n- Uses round-robin rotation\n- Ensures fair lead distribution within categories"
      },
      "typeVersion": 1
    },
    {
      "id": "a0d45e94-5980-4646-a9dd-3fb3e20ada9f",
      "name": "Sticky Note6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2464,
        960
      ],
      "parameters": {
        "color": 4,
        "width": 544,
        "height": 672,
        "content": "## Lead Qualification\n\nEvaluates lead quality using AI:\n-  Budget\n- Location\n- Category\n- Timeline\n-  Buyer intent\n\nOutputs: Qualified / Not Qualified\n"
      },
      "typeVersion": 1
    },
    {
      "id": "86b9e12f-2c8c-4c2f-913f-f2a5bfa8d667",
      "name": "Sticky Note7",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3056,
        960
      ],
      "parameters": {
        "color": 7,
        "width": 320,
        "height": 480,
        "content": "## CRM Storage (Airtable)\n\nStores lead data:\n- Main CRM table (new leads)\n- Assignment metadata\n"
      },
      "typeVersion": 1
    },
    {
      "id": "9e8771d5-5def-445a-a9b1-09f9e863d92e",
      "name": "Sticky Note8",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3408,
        960
      ],
      "parameters": {
        "color": 7,
        "width": 304,
        "height": 576,
        "content": "## Notifications & Alerts\n\nNotifies stakeholders:\n- Email to assigned agent\n- Slack alerts\n- Internal follow-ups\n"
      },
      "typeVersion": 1
    },
    {
      "id": "537abe8a-20dd-4545-86e5-8114ca7fd5a9",
      "name": "Get Duplicates Records",
      "type": "n8n-nodes-base.airtable",
      "position": [
        880,
        2496
      ],
      "parameters": {
        "base": {
          "__rl": true,
          "mode": "list",
          "value": "appBnug5XIRAWl5sK",
          "cachedResultUrl": "https://airtable.com/appBnug5XIRAWl5sK",
          "cachedResultName": "N8n"
        },
        "table": {
          "__rl": true,
          "mode": "list",
          "value": "tblrmNx8MIvJvUHNz",
          "cachedResultUrl": "https://airtable.com/appBnug5XIRAWl5sK/tblrmNx8MIvJvUHNz",
          "cachedResultName": "Real Estate Qualifier Duplicate"
        },
        "options": {},
        "operation": "search",
        "filterByFormula": "="
      },
      "credentials": {
        "airtableTokenApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "540efe59-8416-48e0-85f1-a7b0772d6253",
      "name": "7-Day Duplicate Count",
      "type": "n8n-nodes-base.code",
      "position": [
        1232,
        2496
      ],
      "parameters": {
        "jsCode": "// Get the current date and time\nconst now = new Date();\n\n// Create a new Date object to represent \"7 days ago\"\nconst sevenDaysAgo = new Date();\n\n// Subtract 7 days from today's date\nsevenDaysAgo.setDate(now.getDate() - 7);\n\n// Filter all incoming items to keep only those\n// whose createdTime is within the last 7 days\nconst recentRecords = items.filter(item => {\n  // Parse the Airtable createdTime string into a Date object\n  const createdTime = new Date(item.json.createdTime);\n\n  // Keep the record if it was created on or after 7 days ago\n  return createdTime >= sevenDaysAgo;\n});\n\n// Return a single item containing the count\n// of records created within the last 7 days\nreturn [\n  {\n    json: {\n      count: recentRecords.length\n    }\n  }\n];\n"
      },
      "typeVersion": 2
    },
    {
      "id": "d556b761-105f-40a5-9c7f-88769b563069",
      "name": "Weekly Fetch",
      "type": "n8n-nodes-base.code",
      "position": [
        976,
        2224
      ],
      "parameters": {
        "jsCode": "// Get the current date and time\nconst now = new Date();\n\n// Create a Date object representing 7 days ago\nconst sevenDaysAgo = new Date();\nsevenDaysAgo.setDate(now.getDate() - 7);\n\n// Filter incoming Airtable records\nconst recentRecords = items.filter(item => {\n  // Convert Airtable createdTime (ISO string) to a Date object\n  const createdTime = new Date(item.json.createdTime);\n\n  // Keep the record only if it was created within the last 7 days\n  return createdTime >= sevenDaysAgo;\n});\n\n// Return the filtered records\nreturn recentRecords;\n"
      },
      "typeVersion": 2
    },
    {
      "id": "67f40805-e205-499c-b6a9-4077a8ba9bac",
      "name": "Sticky Note9",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        352,
        2128
      ],
      "parameters": {
        "color": 4,
        "width": 1824,
        "height": 528,
        "content": "## Reporting & Analytics\n\nScheduled reporting:\n- Weekly lead summary\n- Duplicate analysis\n- Performance insights\n"
      },
      "typeVersion": 1
    },
    {
      "id": "088361a0-e332-40c3-90fd-54eea97db02d",
      "name": "WhatsApp Texts Only",
      "type": "n8n-nodes-base.switch",
      "position": [
        256,
        144
      ],
      "parameters": {
        "rules": {
          "values": [
            {
              "outputKey": "Text",
              "conditions": {
                "options": {
                  "version": 3,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "6a662a44-caab-442c-a687-2e1fcfa951c8",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.messages[0].type }}",
                    "rightValue": "text"
                  }
                ]
              },
              "renameOutput": true
            }
          ]
        },
        "options": {
          "fallbackOutput": "extra"
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "1f1c904d-b9cf-4b0b-b92f-a2211305c89f",
      "name": "Send message",
      "type": "n8n-nodes-base.whatsApp",
      "position": [
        64,
        800
      ],
      "parameters": {
        "textBody": "={{ $json.output }}",
        "operation": "send",
        "phoneNumberId": "874689602398158",
        "additionalFields": {},
        "recipientPhoneNumber": "={{ $('WhatsApp Trigger').item.json.messages[0].from }}"
      },
      "credentials": {
        "whatsAppApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.1
    },
    {
      "id": "927e6bea-510b-4cd4-a5d2-eb6eb77428a1",
      "name": "Create Duplicate record",
      "type": "n8n-nodes-base.airtable",
      "position": [
        2080,
        1632
      ],
      "parameters": {
        "base": {
          "__rl": true,
          "mode": "list",
          "value": "appBnug5XIRAWl5sK",
          "cachedResultUrl": "https://airtable.com/appBnug5XIRAWl5sK",
          "cachedResultName": "N8n"
        },
        "table": {
          "__rl": true,
          "mode": "list",
          "value": "tblrmNx8MIvJvUHNz",
          "cachedResultUrl": "https://airtable.com/appBnug5XIRAWl5sK/tblrmNx8MIvJvUHNz",
          "cachedResultName": "Real Estate Qualifier Duplicate"
        },
        "columns": {
          "value": {
            "Email": "={{ $('Combine All Lead Sources').item.json.Email }}",
            "Source": "={{ $('Combine All Lead Sources').item.json.Source }}",
            "Location": "={{ $('Combine All Lead Sources').item.json['Where are you looking to purchase a property?'] }}",
            "Has Agent": "={{ $('Combine All Lead Sources').item.json['Are you currently working with a real estate agent?'] }}",
            "Last name": "={{ $('Combine All Lead Sources').item.json['Last name'] }}",
            "Timeframe": "={{ $('Combine All Lead Sources').item.json['When do you plan to purchase a property?'] }}",
            "First name": "={{ $('Combine All Lead Sources').item.json['First name'] }}",
            "Phone number": "={{ $('Combine All Lead Sources').item.json['Phone number'] }}",
            "Pre Approved": "={{ $('Combine All Lead Sources').item.json['Are you pre-approved for a mortgage, or currently working with a lender?'] }}",
            "Property Type": "={{ $('Combine All Lead Sources').item.json['What type of property are you interested in?'] }}",
            "Payment Source": "={{ $('Combine All Lead Sources').item.json['How do you plan to purchase the property?'] }}"
          },
          "schema": [
            {
              "id": "First name",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "First name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Last name",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "Last name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Phone number",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "Phone number",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Email",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "Email",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Budget",
              "type": "string",
              "display": true,
              "removed": true,
              "readOnly": false,
              "required": false,
              "displayName": "Budget",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Location",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "Location",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Property Type",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "Property Type",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Timeframe",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "Timeframe",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Payment Source",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "Payment Source",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Pre Approved",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "Pre Approved",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Has Agent",
              "type": "options",
              "display": true,
              "options": [
                {
                  "name": "Yes",
                  "value": "Yes"
                },
                {
                  "name": "No",
                  "value": "No"
                }
              ],
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "Has Agent",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Source",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "Source",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "create"
      },
      "credentials": {
        "airtableTokenApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "9b9a5e2d-a6b2-4c1c-ac3b-d2e3c53a03cc",
      "name": "Create A Record",
      "type": "n8n-nodes-base.airtable",
      "position": [
        3168,
        1264
      ],
      "parameters": {
        "base": {
          "__rl": true,
          "mode": "list",
          "value": "appBnug5XIRAWl5sK",
          "cachedResultUrl": "https://airtable.com/appBnug5XIRAWl5sK",
          "cachedResultName": "N8n"
        },
        "table": {
          "__rl": true,
          "mode": "list",
          "value": "tblaHgYnpXzZl0zRH",
          "cachedResultUrl": "https://airtable.com/appBnug5XIRAWl5sK/tblaHgYnpXzZl0zRH",
          "cachedResultName": "Real Estate Qualifier"
        },
        "columns": {
          "value": {
            "Email": "={{ $('Round-Robin Agent Assignment1').item.json.Email }}",
            "Source": "={{ $('Round-Robin Agent Assignment1').item.json.Source }}",
            "Location": "={{ $('Round-Robin Agent Assignment1').item.json['Where are you looking to purchase a property?'] }}",
            "Has Agent": "={{ $('Round-Robin Agent Assignment1').item.json['Are you currently working with a real estate agent?'] }}",
            "Last name": "={{ $('Round-Robin Agent Assignment1').item.json['Last name'] }}",
            "Qualified": "={{ $json.text }}",
            "Timeframe": "={{ $('Round-Robin Agent Assignment1').item.json['When do you plan to purchase a property?'] }}",
            "First name": "={{ $('Round-Robin Agent Assignment1').item.json['First name'] }}",
            "Lead Status": "={{ $('Round-Robin Agent Assignment1').item.json.lead_status }}",
            "Phone number": "={{ $('Round-Robin Agent Assignment1').item.json['Phone number'] }}",
            "Pre Approved": "={{ $('Round-Robin Agent Assignment1').item.json['Are you pre-approved for a mortgage, or currently working with a lender?'] }}",
            "Assigned Time": "={{ $('Round-Robin Agent Assignment1').item.json.assignment_timestamp }}",
            "Property Type": "={{ $('Round-Robin Agent Assignment1').item.json['What type of property are you interested in?'] }}",
            "Assigned Agent": "={{ $('Round-Robin Agent Assignment1').item.json.assigned_agent }}",
            "Payment Source": "={{ $('Round-Robin Agent Assignment1').item.json['How do you plan to purchase the property?'] }}"
          },
          "schema": [
            {
              "id": "First name",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "First name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Last name",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "Last name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Phone number",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "Phone number",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Email",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "Email",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Budget",
              "type": "string",
              "display": true,
              "removed": true,
              "readOnly": false,
              "required": false,
              "displayName": "Budget",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Location",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "Location",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Property Type",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "Property Type",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Timeframe",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "Timeframe",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Payment Source",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "Payment Source",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Pre Approved",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "Pre Approved",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Has Agent",
              "type": "options",
              "display": true,
              "options": [
                {
                  "name": "Yes",
                  "value": "Yes"
                },
                {
                  "name": "No",
                  "value": "No"
                }
              ],
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "Has Agent",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Lead Status",
              "type": "options",
              "display": true,
              "options": [
                {
                  "name": "New",
                  "value": "New"
                },
                {
                  "name": "Contacted",
                  "value": "Contacted"
                },
                {
                  "name": "Follow-up",
                  "value": "Follow-up"
                },
                {
                  "name": "Converted",
                  "value": "Converted"
                },
                {
                  "name": "Couldn\u2019t Convert",
                  "value": "Couldn\u2019t Convert"
                }
              ],
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "Lead Status",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Source",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "Source",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Assigned Agent",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "Assigned Agent",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Assigned Time",
              "type": "dateTime",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "Assigned Time",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Qualified",
              "type": "options",
              "display": true,
              "options": [
                {
                  "name": "Yes",
                  "value": "Yes"
                },
                {
                  "name": "No",
                  "value": "No"
                }
              ],
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "Qualified",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Transcript",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "Transcript",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Summary",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "Summary",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "create"
      },
      "credentials": {
        "airtableTokenApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "df6fed44-a457-4832-8233-743764c082a3",
      "name": "Combine both duplicate and non-duplicate records",
      "type": "n8n-nodes-base.merge",
      "position": [
        1504,
        2336
      ],
      "parameters": {
        "mode": "combine",
        "options": {},
        "combineBy": "combineByPosition"
      },
      "typeVersion": 3.2
    },
    {
      "id": "873e1c90-c4bc-4b7e-84fe-86162c89fdda",
      "name": "Are All Info Complete?",
      "type": "n8n-nodes-base.if",
      "position": [
        80,
        1248
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "8ed2a5a8-de20-4454-85b3-e079a1986d52",
              "operator": {
                "name": "filter.operator.equals",
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $json.text }}",
              "rightValue": "Yes"
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "bf49832f-e7de-4511-925f-8d7dc5462ccc",
      "name": "Normalize Form Leads",
      "type": "n8n-nodes-base.set",
      "position": [
        896,
        1632
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "81540608-a83b-4390-a57c-abcb048c6731",
              "name": "Source",
              "type": "string",
              "value": "Website Form"
            }
          ]
        },
        "includeOtherFields": true
      },
      "typeVersion": 3.4
    },
    {
      "id": "cc30d292-f0c4-498b-a474-c413ab03eb42",
      "name": "Normalize WhatsApp Leads",
      "type": "n8n-nodes-base.set",
      "position": [
        880,
        1120
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "32bdaca5-a67e-4b50-8c54-225f44cd73c3",
              "name": "First name",
              "type": "string",
              "value": "={{ $json.output['First name'] }}"
            },
            {
              "id": "5d75e269-7654-43d6-bf6e-1518a81c7d8f",
              "name": "Last name",
              "type": "string",
              "value": "={{ $json.output['Last name'] }}"
            },
            {
              "id": "42b6b541-5af1-456d-a580-79d3fcbb99b1",
              "name": "Phone number",
              "type": "string",
              "value": "={{ $json.output['Phone number'] }}"
            },
            {
              "id": "58470c2e-92f0-46a8-b1e9-ab518dedbcf7",
              "name": "Email",
              "type": "string",
              "value": "={{ $json.output.Email }}"
            },
            {
              "id": "10b19f5b-2604-4463-9cde-baba4717b12e",
              "name": "What is your budget range?",
              "type": "string",
              "value": "={{ $json.output['What is your budget range?'] }}"
            },
            {
              "id": "5a7cd33d-174f-47aa-a96a-b0cb166c5b9a",
              "name": "How do you plan to purchase the property?",
              "type": "string",
              "value": "={{ $json.output['How do you plan to purchase the property?'] }}"
            },
            {
              "id": "820cbb3e-a4ae-4973-9bfb-374377cccf5e",
              "name": "Are you pre-approved for a mortgage, or currently working with a lender?",
              "type": "string",
              "value": "={{ $json.output['Are you pre-approved for a mortgage, or currently working with a lender?'] }}"
            },
            {
              "id": "c83f3932-7e39-4a13-a871-9f956463f70d",
              "name": "What type of property are you interested in?",
              "type": "string",
              "value": "={{ $json.output['What type of property are you interested in?'] }}"
            },
            {
              "id": "7c08db65-457e-42e4-85fd-6e0d917223f0",
              "name": "Where are you looking to purchase a property?",
              "type": "string",
              "value": "={{ $json.output['Where are you looking to purchase a property?'] }}"
            },
            {
              "id": "2a20d27e-7a80-484c-a266-efee775173fc",
              "name": "When do you plan to purchase a property?",
              "type": "string",
              "value": "={{ $json.output['When do you plan to purchase a property?'] }}"
            },
            {
              "id": "e5957d9a-9617-46b9-9387-119d578dc3f7",
              "name": "Are you currently working with a real estate agent?",
              "type": "string",
              "value": "={{ $json.output['Are you currently working with a real estate agent?'] }}"
            },
            {
              "id": "b2951fb2-141e-4bcf-9169-ca4195f307d8",
              "name": "Source",
              "type": "string",
              "value": "WhatsApp Form"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "9bed02dc-dfc4-429a-a32c-234cc3cb04f4",
      "name": "Notify Agent via Slack",
      "type": "n8n-nodes-base.slack",
      "position": [
        3488,
        1168
      ],
      "parameters": {
        "text": "=New Lead Assigned to You!\n\n*Name:* {{ $json.fields['First name'] }} {{ $json.fields['Last name'] }}\n*Email:* {{ $json.fields.Email }}\n*Phone:* {{ $json.fields['Phone number'] }}\n*Property Type:* {{ $json.fields['Property Type'] }}\n*Source:* {{ $json.fields.Source }}\n*Location:* {{ $json.fields.Location }}\n*Qualified:* {{ $json.fields.Qualified }}\n*Assigned Agent:* {{ $json.fields['Assigned Agent'] }}\n\n*Recommended Action:* Contact within 15 minutes if qualified for best conversion rate",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "list",
          "value": "C09MZKZS5QE",
          "cachedResultName": "test_n8n_invoice"
        },
        "otherOptions": {
          "includeLinkToWorkflow": false
        }
      },
      "credentials": {
        "slackApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.4
    },
    {
      "id": "b9ef618b-9317-4ce1-8651-6d67cbd20973",
      "name": "Sticky Note10",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        784,
        768
      ],
      "parameters": {
        "color": 4,
        "width": 528,
        "height": 1040,
        "content": "## Data Normalization\n\nStandardizes lead  fields:\n- First name\n- Last name\n- Phone number\n- Email\n- What is your budget range?\n- etc\n\n\nEnsures downstream logic works consistently."
      },
      "typeVersion": 1
    },
    {
      "id": "a5491567-d2a5-4f1f-beb9-01ef1e3ecd91",
      "name": "Sticky Note11",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -32,
        1552
      ],
      "parameters": {
        "color": 6,
        "width": 400,
        "height": 240,
        "content": "## Website forms Lead intake"
      },
      "typeVersion": 1
    },
    {
      "id": "0cc9e4ab-d430-4b4e-ae8c-b9fd47a6808b",
      "name": "Sticky Note12",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -112,
        32
      ],
      "parameters": {
        "color": 7,
        "width": 624,
        "height": 288,
        "content": "## WhatsApp Lead intake"
      },
      "typeVersion": 1
    },
    {
      "id": "56f18543-49bc-446d-ba1c-cbce1260d9e7",
      "name": "Sticky Note13",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -112,
        336
      ],
      "parameters": {
        "color": 7,
        "width": 624,
        "height": 288,
        "content": "### WhatsApp AI Agent - Lead Collection\n- Engages WhatsApp users automatically\n- Collects initial lead details and intent"
      },
      "typeVersion": 1
    },
    {
      "id": "627e674a-de54-4733-b5cf-602904b74367",
      "name": "Sticky Note14",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -112,
        656
      ],
      "parameters": {
        "color": 7,
        "width": 624,
        "height": 288,
        "content": "### WhatsApp AI Agent - Info Completeness Check\n- Confirms all required lead information is provided\n- Flags missing details for follow-up"
      },
      "typeVersion": 1
    },
    {
      "id": "76c7dccc-8546-422c-bf8d-e7800fdf23a7",
      "name": "Sticky Note15",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -112,
        1040
      ],
      "parameters": {
        "color": 7,
        "width": 624,
        "height": 448,
        "content": "### WhatsApp AI Agent - Extract Lead Info\n- Extracts structured lead data from chat messages\n- Prepares clean fields for CRM and routing"
      },
      "typeVersion": 1
    }
  ],
  "active": true,
  "settings": {
    "availableInMCP": false,
    "executionOrder": "v1"
  },
  "versionId": "27a52318-2189-4d95-96a2-163f902690b8",
  "connections": {
    "Aggregate": {
      "main": [
        [
          {
            "node": "Basic LLM Chain",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Records": {
      "main": [
        [
          {
            "node": "Weekly Fetch",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send message": {
      "main": [
        [
          {
            "node": "Info Completeness Check",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Weekly Fetch": {
      "main": [
        [
          {
            "node": "Aggregate Report Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Simple Memory": {
      "ai_memory": [
        [
          {
            "node": "Lead Collection Agent",
            "type": "ai_memory",
            "index": 0
          }
        ]
      ]
    },
    "Search records": {
      "main": [
        [
          {
            "node": "Check for Duplicates in CRM",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Basic LLM Chain": {
      "main": [
        [
          {
            "node": "Create A Record",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Create A Record": {
      "main": [
        [
          {
            "node": "Send a message",
            "type": "main",
            "index": 0
          },
          {
            "node": "Notify Agent via Slack",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Typeform Trigger": {
      "main": [
        [
          {
            "node": "Normalize Form Leads",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "WhatsApp Trigger": {
      "main": [
        [
          {
            "node": "WhatsApp Texts Only",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract Lead Info": {
      "main": [
        [
          {
            "node": "Normalize WhatsApp Leads",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "Info Completeness Check",
            "type": "ai_languageModel",
            "index": 0
          },
          {
            "node": "Extract Lead Info",
            "type": "ai_languageModel",
            "index": 0
          },
          {
            "node": "Lead Collection Agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI Chat Model2": {
      "ai_languageModel": [
        [
          {
            "node": "Basic LLM Chain",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "WhatsApp Texts Only": {
      "main": [
        [
          {
            "node": "Lead Collection Agent",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "No Operation, do nothing",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Format Weekly Report": {
      "main": [
        [
          {
            "node": "Send Weekly Report",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Normalize Form Leads": {
      "main": [
        [
          {
            "node": "Combine All Lead Sources",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "7-Day Duplicate Count": {
      "main": [
        [
          {
            "node": "Combine both duplicate and non-duplicate records",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Aggregate Report Data": {
      "main": [
        [
          {
            "node": "Combine both duplicate and non-duplicate records",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Lead Collection Agent": {
      "main": [
        [
          {
            "node": "Send message",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Are All Info Complete?": {
      "main": [
        [
          {
            "node": "Extract Lead Info",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "No Operation, do nothing1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Duplicates Records": {
      "main": [
        [
          {
            "node": "7-Day Duplicate Count",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Remove Duplicate Leads": {
      "main": [
        [
          {
            "node": "Check for Duplicates in CRM",
            "type": "main",
            "index": 0
          },
          {
            "node": "Search records",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Weekly Report Schedule": {
      "main": [
        [
          {
            "node": "Get Records",
            "type": "main",
            "index": 0
          },
          {
            "node": "Get Duplicates Records",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Info Completeness Check": {
      "main": [
        [
          {
            "node": "Are All Info Complete?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Combine All Lead Sources": {
      "main": [
        [
          {
            "node": "Remove Duplicate Leads",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Normalize WhatsApp Leads": {
      "main": [
        [
          {
            "node": "Combine All Lead Sources",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Structured Output Parser": {
      "ai_outputParser": [
        [
          {
            "node": "Extract Lead Info",
            "type": "ai_outputParser",
            "index": 0
          }
        ]
      ]
    },
    "Check for Duplicates in CRM": {
      "main": [
        [
          {
            "node": "Route by Location/Property Type1",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Create Duplicate record",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Create Duplicate record",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Round-Robin Agent Assignment1": {
      "main": [
        [
          {
            "node": "Aggregate",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Route by Location/Property Type1": {
      "main": [
        [
          {
            "node": "Round-Robin Agent Assignment1",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Round-Robin Agent Assignment1",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Round-Robin Agent Assignment1",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Round-Robin Agent Assignment1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Combine both duplicate and non-duplicate records": {
      "main": [
        [
          {
            "node": "Format Weekly Report",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}