AutomationFlowsAI & RAG › Qualify Open House Leads and Send AI Follow-ups with Google Sheets and Gmail

Qualify Open House Leads and Send AI Follow-ups with Google Sheets and Gmail

ByHassan @hassans on n8n.io

When a visitor signs in at your open house, this workflow instantly scores their buying intent using Gemini AI, sends a personalized follow-up email via Gmail, logs every visitor to Google Sheets, and alerts the agent for hot leads only. A visitor signs in via your Google Form…

Event trigger★★★★☆ complexityAI-powered17 nodesGoogle Sheets TriggerGoogle Gemini ChatAgentGmailGoogle SheetsSlack
AI & RAG Trigger: Event Nodes: 17 Complexity: ★★★★☆ AI nodes: yes Added:

This workflow corresponds to n8n.io template #16672 — we link there as the canonical source.

This workflow follows the Agent → Gmail recipe pattern — see all workflows that pair these two integrations.

The workflow JSON

Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →

Download .json
{
  "id": "uxoEBRsuVf5Ocqhy",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "Open House Sign-In to Qualified Follow-Up",
  "tags": [],
  "nodes": [
    {
      "id": "a9efc993-07d1-448c-9ee4-6085efd4c856",
      "name": "Google Sheets Trigger",
      "type": "n8n-nodes-base.googleSheetsTrigger",
      "position": [
        -736,
        -16
      ],
      "parameters": {
        "event": "rowAdded",
        "options": {},
        "pollTimes": {
          "item": [
            {
              "mode": "everyMinute"
            }
          ]
        },
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "",
          "cachedResultUrl": "",
          "cachedResultName": ""
        },
        "documentId": {
          "__rl": true,
          "mode": "url",
          "value": ""
        }
      },
      "credentials": {
        "googleSheetsTriggerOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "fa8ef370-96a0-4875-bb5d-87f3a0c6b2f2",
      "name": "Extract Visitor Details",
      "type": "n8n-nodes-base.set",
      "position": [
        -528,
        -16
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "03e714c5-db7e-4d40-958e-636df02ff02f",
              "name": "visitorName",
              "type": "string",
              "value": "={{ $json['Full Name'] }}"
            },
            {
              "id": "46463909-61ce-4352-80a7-f8f753e9d969",
              "name": "visitorEmail",
              "type": "string",
              "value": "={{ $json['Email Address'] }}"
            },
            {
              "id": "a1de33b6-58b7-4c25-9c6d-1f1a5239debe",
              "name": "visitorPhone",
              "type": "string",
              "value": "={{ $json['Phone Number'] }}"
            },
            {
              "id": "072db1a0-5a08-48f7-b9b8-17ce855f9b6f",
              "name": "propertyAddress",
              "type": "string",
              "value": "={{ $json['Which property are you interested in?'] }}"
            },
            {
              "id": "bd4a94f6-54ca-4296-9e11-bff67d994071",
              "name": "budget",
              "type": "string",
              "value": "={{ $json['What is your budget range?'] }}"
            },
            {
              "id": "c845b0a0-f442-40fc-b2a3-a2f4b4206ad6",
              "name": "timeline",
              "type": "string",
              "value": "={{ $json['What is your buying timeline?'] }}"
            },
            {
              "id": "c8bd4a83-48dd-4b24-bbc4-dd0c34e40e0d",
              "name": "buyingIntent",
              "type": "string",
              "value": "={{ $json['How would you describe your buying intent?'] }}"
            },
            {
              "id": "1e093ffa-0e7a-40d2-a500-e10e39412320",
              "name": "submittedAt",
              "type": "string",
              "value": "={{ $json.Timestamp }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "d18d659a-ec00-4579-8100-bc071f6f4736",
      "name": "Google Gemini Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
      "position": [
        -224,
        256
      ],
      "parameters": {
        "options": {},
        "modelName": "models/gemini-2.5-flash"
      },
      "credentials": {
        "googlePalmApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.1
    },
    {
      "id": "7bee3e92-33c0-40d0-ba73-9cd0bcdd329b",
      "name": "Qualify & Draft Follow-Up",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        -320,
        -16
      ],
      "parameters": {
        "text": "=Visitor name: {{ $json.visitorName }}\nProperty they visited: {{ $json.propertyAddress }}\nBudget: {{ $json.budget }}\nBuying timeline: {{ $json.timeline }}\nBuying intent: {{ $json.buyingIntent }}",
        "options": {
          "systemMessage": "You are a real estate lead qualification and follow-up assistant.\n\nDo two things in one response:\n1. Score this open house visitor as Hot, Warm, or Cold based on their \n   budget, timeline, and buying intent.\n2. Write a short, warm follow-up email tailored to their score:\n     Hot = enthusiastic, action-oriented, suggest a private viewing\n     Warm = friendly, informative, share more about the property\n     Cold = light-touch, no pressure, leave the door open\n\nFormat the email_body as two parts separated by a literal \\n\\n:\n  Part 1: greeting line only e.g. \"Hi {name},\"\n  Part 2: message body as a single paragraph\n\nOutput ONLY valid JSON with no preamble or markdown backticks:\n{\n  \"score\": \"Hot | Warm | Cold\",\n  \"reasoning\": \"one sentence explanation\",\n  \"email_subject\": \"short subject line\",\n  \"email_body\": \"Hi {name},\\n\\nMessage body here.\"\n}"
        },
        "promptType": "define"
      },
      "typeVersion": 3.1
    },
    {
      "id": "1bde0413-ebff-4fd2-a139-b6ec37f06307",
      "name": "Parse AI Output",
      "type": "n8n-nodes-base.code",
      "position": [
        32,
        -16
      ],
      "parameters": {
        "jsCode": "const raw = $input.first().json.output;\nlet parsed;\n\ntry {\n  parsed = JSON.parse(raw);\n} catch (e) {\n  parsed = {\n    score: \"Warm\",\n    reasoning: \"AI parsing failed \u2014 manual review recommended.\",\n    email_subject: \"Thanks for visiting the open house!\",\n    email_body: `Hi ${$('Extract Visitor Details').first().json.visitorName},\\n\\nThank you for visiting the open house today. We would love to help you find the right property \u2014 please feel free to reach out at any time.`\n  };\n}\n\nconst visitorData = $('Extract Visitor Details').first().json;\n\nfunction escapeHtml(text) {\n  return text\n    .replace(/&/g, '&amp;')\n    .replace(/</g, '&lt;')\n    .replace(/>/g, '&gt;');\n}\n\nfunction formatEmailHtml(text) {\n  const paragraphs = text\n    .split(/\\n\\s*\\n/)\n    .map(p => p.replace(/\\s+/g, ' ').trim())\n    .filter(Boolean);\n  return paragraphs.map(p => `<p>${escapeHtml(p)}</p>`).join('');\n}\n\nreturn [{\n  json: {\n    ...visitorData,\n    score: parsed.score,\n    reasoning: parsed.reasoning,\n    email_subject: parsed.email_subject,\n    email_body: formatEmailHtml(parsed.email_body),\n    recordId: `${visitorData.visitorEmail}-${Date.now()}`\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "b3500855-73f8-4623-9009-de7e195a1eee",
      "name": "Send Visitor Follow-Up Email",
      "type": "n8n-nodes-base.gmail",
      "position": [
        240,
        -16
      ],
      "parameters": {
        "sendTo": "={{ $json.visitorEmail }}",
        "message": "={{ $json.email_body }}",
        "options": {
          "appendAttribution": false
        },
        "subject": "={{ $json.email_subject }}"
      },
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "88658316-3d7f-4462-8b13-ff3860a04bf4",
      "name": "Log to Open House Sheet",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        448,
        -16
      ],
      "parameters": {
        "columns": {
          "value": {
            "Email": "={{ $('Parse AI Output').item.json.visitorEmail }}",
            "Phone": "={{ $('Parse AI Output').item.json.visitorPhone }}",
            "Budget": "={{ $('Parse AI Output').item.json.budget }}",
            "Timeline": "={{ $('Parse AI Output').item.json.timeline }}",
            "recordId": "={{ $('Parse AI Output').item.json.recordId }}",
            "Timestamp": "={{ $('Parse AI Output').item.json.submittedAt }}",
            "Lead Score": "={{ $('Parse AI Output').item.json.score }}",
            "Visitor Name": "={{ $('Parse AI Output').item.json.visitorName }}",
            "Buying Intent": "={{ $('Parse AI Output').item.json.buyingIntent }}",
            "Email Subject": "={{ $('Parse AI Output').item.json.email_subject }}",
            "Agent Notified": "false",
            "Score Reasoning": "={{ $('Parse AI Output').item.json.reasoning }}",
            "Property Address": "={{ $('Parse AI Output').item.json.propertyAddress }}"
          },
          "schema": [
            {
              "id": "recordId",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "recordId",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Timestamp",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Timestamp",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Visitor Name",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Visitor Name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Email",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Email",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Phone",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Phone",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Property Address",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Property Address",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Budget",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Budget",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Timeline",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Timeline",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Buying Intent",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Buying Intent",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Lead Score",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Lead Score",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Score Reasoning",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Score Reasoning",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Email Subject",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Email Subject",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Agent Notified",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Agent Notified",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1kbvVHhCrG5My6Z4WOLW4ETgNIC6fKZWtHZszKg9DDQc/edit#gid=0",
          "cachedResultName": "Leads"
        },
        "documentId": {
          "__rl": true,
          "mode": "url",
          "value": ""
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "bb3e2488-c46c-4bd5-a911-11e018da1ddc",
      "name": "Is Lead Hot?",
      "type": "n8n-nodes-base.if",
      "position": [
        656,
        -16
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "f4dd0a51-14d3-49e3-b88f-93cc61c34fdb",
              "operator": {
                "name": "filter.operator.equals",
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $json['Lead Score'] }}",
              "rightValue": "Hot"
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "7085c4fb-04dd-4702-81da-a3579cbe5146",
      "name": "Notify Agent \u2014 Hot Lead",
      "type": "n8n-nodes-base.gmail",
      "position": [
        944,
        -224
      ],
      "parameters": {
        "sendTo": "=youremail@gmail.com",
        "message": "=<p><strong>New Hot Lead from Open House</strong></p> <p><strong>Name:</strong> {{ $json['Visitor Name'] }} <br> <strong>Email:</strong> {{ $json.Email }} <br> <strong>Phone:</strong> {{ $json.Phone }} <br> <strong>Property:</strong> {{ $json['Property Address'] }} <br> <strong>Budget:</strong> {{ $json.Budget }}<br> <strong>Timeline:</strong> {{ $json.Timeline }} <br> <strong>Intent:</strong> {{ $json['Buying Intent'] }} </p> <p><strong>AI Score:</strong> {{ $json['Lead Score'] }} <br> <strong>Reasoning:</strong> {{ $json['Score Reasoning'] }}</p>",
        "options": {
          "appendAttribution": false
        },
        "subject": "=\ud83d\udd25 Hot Lead at {{ $json['Property Address'] }} \u2014 {{ $json['Visitor Name'] }}"
      },
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "a05c5102-b757-4c83-8f81-78f804d06e60",
      "name": "Notify Agent via Slack",
      "type": "n8n-nodes-base.slack",
      "position": [
        960,
        240
      ],
      "parameters": {
        "text": "=\ud83d\udd25 *Hot Lead \u2014 {{ $json['Property Address'] }} * *Name:* {{ $json['Visitor Name'] }} *Email:* {{ $json.Email }} *Budget:* {{ $json.Budget }} | *Timeline:* {{ $json.Timeline }} *AI Reasoning:* {{ $json['Score Reasoning'] }}",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "name",
          "value": "#hot-leads"
        },
        "otherOptions": {}
      },
      "typeVersion": 2.4
    },
    {
      "id": "1e0758c1-5350-4dc5-a292-6b3b28154640",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1456,
        -336
      ],
      "parameters": {
        "width": 544,
        "height": 752,
        "content": "## Open House Sign-In to Qualified Follow-Up\n\nWhen a visitor signs in at your open house, this workflow automatically \nqualifies their buying intent, sends them a personalized follow-up email, \nand alerts you immediately if they're a hot lead \u2014 so no opportunity slips \nthrough after a busy open house day.\n\n### How it works\nA Google Form captures visitor details at sign-in. AI (Gemini) scores each \nvisitor as **Hot**, **Warm**, or **Cold** based on their budget, timeline, \nand buying intent \u2014 and drafts a tailored follow-up email in the same step. \nThe email sends immediately via Gmail. Every visitor is logged to Google \nSheets with their score and message. If a lead scores Hot, the agent receives \nan instant notification email so they can prioritize personal outreach.\n\n### Setup\n1. Connect **Google Sheets**, **Gmail**, and **Gemini API** credentials.\n2. Copy the *Open House Sign-In Log* sheet template and link it to the \n   Sheets node.\n3. Set up your **Google Form** with the required sign-in fields (name, \n   email, phone, property, budget, timeline, intent) and link it to a \n   Google Sheet response tab.\n4. Point the trigger to the form's linked response sheet.\n5. Update the agent notification email address in the \n   \"Notify Agent \u2014 Hot Lead\" node.\n6. **Slack is optional** \u2014 add your Slack credential to the Slack node \n   if you want a second notification channel for hot leads. \n   Disable it if not needed.\n\n### Customization\n- Edit the AI prompt to adjust scoring criteria or tone.\n- Add Warm lead agent notifications by duplicating the Hot lead branch.\n- Extend the form with additional qualification questions."
      },
      "typeVersion": 1
    },
    {
      "id": "fa7addd7-e420-4874-9b45-37a7fe4df7c5",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -864,
        -208
      ],
      "parameters": {
        "color": "#FCFCFC",
        "width": 272,
        "height": 416,
        "content": "## New Open House Sign-In\nWatches the Google Form response sheet for new submissions.\nFires once per visitor sign-in during or after the open house."
      },
      "typeVersion": 1
    },
    {
      "id": "dd3bd926-9176-4ea5-abe9-0824a92a5afe",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -336,
        -336
      ],
      "parameters": {
        "color": "#FCFCFC",
        "width": 528,
        "height": 752,
        "content": "## Qualify & Draft Follow-Up\nOne Gemini AI call scores the lead (Hot / Warm / Cold) and drafts a personalized follow-up email in a single step.\nA second node parses and formats the AI output for use downstream."
      },
      "typeVersion": 1
    },
    {
      "id": "64f51780-4243-46ed-8579-842131d6e02d",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        208,
        -336
      ],
      "parameters": {
        "color": "#FCFCFC",
        "width": 928,
        "height": 752,
        "content": "## Email, Log & Agent Alert\nSends the personalized follow-up to the visitor, logs every sign-in to Google Sheets, \nand notifies the agent instantly for Hot leads only. Slack alert is optional alongside \nthe email notification."
      },
      "typeVersion": 1
    },
    {
      "id": "3a7e5a6f-04cd-4e2d-97ae-fe825b702503",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -576,
        -208
      ],
      "parameters": {
        "color": "#FCFCFC",
        "width": 224,
        "height": 416,
        "content": "## Extract Visitor Details\nMaps raw form field names to clean, readable variable names\nused by all downstream nodes."
      },
      "typeVersion": 1
    },
    {
      "id": "efaefa0a-1832-4386-8d6b-f021968a952a",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        864,
        -336
      ],
      "parameters": {
        "color": 3,
        "width": 560,
        "height": 336,
        "content": "## Update Agent Email Address\nReplace the placeholder email in this node with the agent's real email address before going live. Notifications will fail silently if this is left as the default."
      },
      "typeVersion": 1
    },
    {
      "id": "4d051f0e-c15f-41eb-b7ee-19d9b8677607",
      "name": "Sticky Note6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        864,
        16
      ],
      "parameters": {
        "color": 3,
        "width": 560,
        "height": 400,
        "content": "## Slack is Optional\nThis node only runs if you add your Slack OAuth2 credential.\nTo use:\n- Set the correct channel name (e.g. #hot-leads)\n- Make sure your Slack app has permission to post to that channel\nIf you don't need Slack, leave this node disconnected \u2014 the email notification will still fire for Hot leads."
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "binaryMode": "separate",
    "executionOrder": "v1"
  },
  "versionId": "dc75884d-9604-4d48-aa48-1db63ae27bcc",
  "connections": {
    "Is Lead Hot?": {
      "main": [
        [
          {
            "node": "Notify Agent via Slack",
            "type": "main",
            "index": 0
          },
          {
            "node": "Notify Agent \u2014 Hot Lead",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse AI Output": {
      "main": [
        [
          {
            "node": "Send Visitor Follow-Up Email",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Google Sheets Trigger": {
      "main": [
        [
          {
            "node": "Extract Visitor Details",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Notify Agent via Slack": {
      "main": [
        []
      ]
    },
    "Extract Visitor Details": {
      "main": [
        [
          {
            "node": "Qualify & Draft Follow-Up",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Log to Open House Sheet": {
      "main": [
        [
          {
            "node": "Is Lead Hot?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Google Gemini Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "Qualify & Draft Follow-Up",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Qualify & Draft Follow-Up": {
      "main": [
        [
          {
            "node": "Parse AI Output",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send Visitor Follow-Up Email": {
      "main": [
        [
          {
            "node": "Log to Open House Sheet",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}

Credentials you'll need

Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.

Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

When a visitor signs in at your open house, this workflow instantly scores their buying intent using Gemini AI, sends a personalized follow-up email via Gmail, logs every visitor to Google Sheets, and alerts the agent for hot leads only. A visitor signs in via your Google Form…

Source: https://n8n.io/workflows/16672/ — original creator credit. Request a take-down →

More AI & RAG workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

AI & RAG

This workflow automatically monitors a Google Sheet for failed trades, analyzes each failure using AI and updates the sheet with a probable root cause, confidence level and actionable next steps. It a

Google Sheets Trigger, Agent, Google Gemini Chat +4
AI & RAG

This n8n workflow automates the transition from raw financial trade data to professional client communication. It monitors a Google Sheet for portfolio changes, uses Gemini AI to draft a personalized,

Google Sheets Trigger, Agent, Google Gemini Chat +3
AI & RAG

Youtube Video: https://youtu.be/42-oHh9w9Eo This workflow listens for Slack @mentions, uses Google Gemini to classify the request and extract invoice details, then reads and updates Google Sheets, gen

Slack Trigger, Google Sheets, Agent +5
AI & RAG

Automate end-to-end vendor onboarding workflows with an AI-powered autonomous agent built in n8n 🤖. This workflow uses advanced MCTS (Monte Carlo Tree Search) reasoning to intelligently map procuremen

Agent, OpenAI Chat, Google Drive +4
AI & RAG

Youtube Video: https://youtu.be/ehsagyRmri4

@Apify/N8N Nodes Apify, Google Sheets, Agent +4