Google Sheets + Twilio, qualify leads and call fast
Web leads come in messy. Someone types a half-thought message, a phone number with extra characters, and suddenly your “hot lead” queue is a guessing game (and the good ones quietly go cold).
Marketing managers feel the whiplash first, but real estate teams and agency operators see the same issue in different clothes. Sheets Twilio automation turns every new lead into a scored, cleaned record and triggers a fast follow-up call so you stop relying on luck and speed alone.
This workflow qualifies inbound web leads with AI, checks property details, logs everything to Google Sheets, and uses Twilio to place an outreach call with a clear summary you can act on.
The Challenge: Fast leads get lost in messy intake
When a lead hits your site, you have a short window to respond. But the intake is rarely clean. Names don’t match your CRM format, messages are vague (“curious about the listing”), and your team ends up doing manual triage: read the message, interpret intent, search the listing, decide priority, then call or text. It’s not hard work. It’s draining work. And the worst part is the inconsistency. Two people can read the same message and prioritize it differently, which means follow-up depends on who saw it first.
It adds up fast. Here’s where it breaks down in day-to-day operations:
- New leads sit in an inbox or form tool until someone notices, which can easily burn the first hour of the response window.
- Manual “lead scoring” becomes gut feel, so the quiet but serious buyer gets treated like a tire-kicker.
- Property context is missing, so your first call is spent re-collecting basic details instead of qualifying.
- Data gets logged late (or not at all), and reporting becomes a weekly cleanup project.
How This Automation Works
See how this solves the problem:
n8n Workflow Template: Google Sheets + Twilio, qualify leads and call fast
flowchart LR
subgraph sg0["AI Agent - Extract L Flow"]
direction LR
n26@{ icon: "mdi:swap-vertical", form: "rounded", label: "Set Lead Variables", pos: "b", h: 48 }
n27@{ icon: "mdi:code-braces", form: "rounded", label: "Generate Intro Message", pos: "b", h: 48 }
n28["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/httprequest.dark.svg' width='40' height='40' /></div><br/>ElevenLabs - Generate Voice"]
n29["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/httprequest.dark.svg' width='40' height='40' /></div><br/>Twilio - Place Call"]
n30@{ icon: "mdi:robot", form: "rounded", label: "AI Agent - Extract Lead Info", pos: "b", h: 48 }
n31@{ icon: "mdi:code-braces", form: "rounded", label: "Store Extracted Values", pos: "b", h: 48 }
n32@{ icon: "mdi:swap-vertical", form: "rounded", label: "Normalize User Data", pos: "b", h: 48 }
n33@{ icon: "mdi:swap-horizontal", form: "rounded", label: "IF Lead Interested", pos: "b", h: 48 }
n34@{ icon: "mdi:code-braces", form: "rounded", label: "Assign Lead Score", pos: "b", h: 48 }
n35@{ icon: "mdi:cog", form: "rounded", label: "Format Timestamp", pos: "b", h: 48 }
n36@{ icon: "mdi:database", form: "rounded", label: "Google Sheets - Log Lead", pos: "b", h: 48 }
n37@{ icon: "mdi:robot", form: "rounded", label: "AI Agent - Lead Summary", pos: "b", h: 48 }
n38@{ icon: "mdi:database", form: "rounded", label: "Google Sheets - Log Summary", pos: "b", h: 48 }
n39["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/webhook.dark.svg' width='40' height='40' /></div><br/>Webhook - New Lead1"]
n40@{ icon: "mdi:brain", form: "rounded", label: "OpenAI Chat Model3", pos: "b", h: 48 }
n41@{ icon: "mdi:brain", form: "rounded", label: "OpenAI Chat Model4", pos: "b", h: 48 }
n35 --> n36
n34 --> n35
n33 --> n34
n40 -.-> n37
n41 -.-> n30
n26 --> n27
n32 --> n33
n29 --> n30
n39 --> n26
n27 --> n28
n31 --> n32
n37 --> n38
n36 --> n37
n28 --> n29
n30 --> n31
end
subgraph sg1["When clicking ‘Test workflow’ Flow"]
direction LR
n12@{ icon: "mdi:play-circle", form: "rounded", label: "When clicking ‘Test workflow’", pos: "b", h: 48 }
n13@{ icon: "mdi:play-circle", form: "rounded", label: "Schedule Trigger", pos: "b", h: 48 }
n14["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/httprequest.dark.svg' width='40' height='40' /></div><br/>HTTP Request"]
n15@{ icon: "mdi:robot", form: "rounded", label: "Information Extractor", pos: "b", h: 48 }
n16@{ icon: "mdi:swap-vertical", form: "rounded", label: "Split Out", pos: "b", h: 48 }
n17@{ icon: "mdi:database", form: "rounded", label: "Real Estate Data", pos: "b", h: 48 }
n18@{ icon: "mdi:robot", form: "rounded", label: "AI Agent", pos: "b", h: 48 }
n19@{ icon: "mdi:brain", form: "rounded", label: "OpenAI Chat Model1", pos: "b", h: 48 }
n20@{ icon: "mdi:wrench", form: "rounded", label: "Calculator", pos: "b", h: 48 }
n21@{ icon: "mdi:wrench", form: "rounded", label: "SerpAPI", pos: "b", h: 48 }
n22@{ icon: "mdi:cog", form: "rounded", label: "Google Docs", pos: "b", h: 48 }
n23@{ icon: "mdi:robot", form: "rounded", label: "OpenAI", pos: "b", h: 48 }
n24@{ icon: "mdi:robot", form: "rounded", label: "OpenAI1", pos: "b", h: 48 }
n25@{ icon: "mdi:brain", form: "rounded", label: "OpenAI Chat Model2", pos: "b", h: 48 }
n21 -.-> n18
n18 --> n22
n18 --> n16
n18 --> n23
n18 --> n24
n16 --> n17
n20 -.-> n18
n14 --> n15
n13 --> n14
n19 -.-> n18
n25 -.-> n15
n15 --> n18
n12 --> n14
end
subgraph sg2["ClassifyIntentUrgenc Flow"]
direction LR
n0["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/webhook.dark.svg' width='40' height='40' /></div><br/>IncomingLeadWebhook"]
n1@{ icon: "mdi:swap-vertical", form: "rounded", label: "RenameInputFields", pos: "b", h: 48 }
n2@{ icon: "mdi:swap-horizontal", form: "rounded", label: "ValidateMessageExists", pos: "b", h: 48 }
n3["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/code.svg' width='40' height='40' /></div><br/>CleanUserText"]
n4@{ icon: "mdi:robot", form: "rounded", label: "ClassifyIntentUrgency", pos: "b", h: 48 }
n5@{ icon: "mdi:swap-vertical", form: "rounded", label: "ExtractClassification", pos: "b", h: 48 }
n6["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/code.svg' width='40' height='40' /></div><br/>StandardizeFields"]
n7["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/httprequest.dark.svg' width='40' height='40' /></div><br/>PropertyCheckAPI"]
n8@{ icon: "mdi:swap-horizontal", form: "rounded", label: "IsKnownListing", pos: "b", h: 48 }
n9["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/code.svg' width='40' height='40' /></div><br/>CalculateLeadScore"]
n10@{ icon: "mdi:swap-vertical", form: "rounded", label: "CreateStructuredLeadObject", pos: "b", h: 48 }
n11@{ icon: "mdi:brain", form: "rounded", label: "OpenAI Chat Model", pos: "b", h: 48 }
n3 --> n4
n8 --> n9
n7 --> n8
n11 -.-> n4
n1 --> n2
n6 --> n7
n9 --> n10
n0 --> n1
n4 --> n5
n5 --> n6
n2 --> n3
end
%% Styling
classDef trigger fill:#e8f5e9,stroke:#388e3c,stroke-width:2px
classDef ai fill:#e3f2fd,stroke:#1976d2,stroke-width:2px
classDef aiModel fill:#e8eaf6,stroke:#3f51b5,stroke-width:2px
classDef decision fill:#fff8e1,stroke:#f9a825,stroke-width:2px
classDef database fill:#fce4ec,stroke:#c2185b,stroke-width:2px
classDef api fill:#fff3e0,stroke:#e65100,stroke-width:2px
classDef code fill:#f3e5f5,stroke:#7b1fa2,stroke-width:2px
classDef disabled stroke-dasharray: 5 5,opacity: 0.5
class n12,n13 trigger
class n30,n37,n15,n18,n23,n24,n4 ai
class n40,n41,n19,n25,n11 aiModel
class n20,n21 ai
class n33,n2,n8 decision
class n36,n38,n17 database
class n28,n29,n39,n14,n0,n7 api
class n27,n31,n34,n3,n6,n9 code
classDef customIcon fill:none,stroke:none
class n28,n29,n39,n14,n0,n3,n6,n7,n9 customIcon
The Fix: AI lead qualification + instant call follow-up
The workflow starts the moment a lead is submitted through your web form and hits an n8n webhook endpoint. It immediately standardizes the incoming fields (so you get consistent names, phones, and message text), then checks that the message is actually usable. From there, OpenAI (GPT-4o Mini via a LangChain agent) reads the cleaned message like a sharp assistant would: it classifies intent (buying, selling, general inquiry) and flags urgency. Next, the workflow enriches the lead by calling a property lookup API to confirm whether the property is a known listing and pull context. Finally, it calculates a lead score and builds a structured lead payload you can store and act on.
For outreach, a second webhook triggers the call flow. It drafts a short personalized intro script, sends it to ElevenLabs for natural voice audio, and uses Twilio to place the call. After the interaction, the workflow extracts qualification details with AI, assigns a status, logs the results in Google Sheets, and writes a clean summary you can skim in seconds.
What Changes: Before vs. After
| What This Eliminates | Impact You’ll See |
|---|---|
|
|
Real-World Impact
Say you get 10 new web leads a day. Manually, it’s common to spend about 10 minutes per lead to read the message, normalize fields, look up the property, decide priority, then log it in a sheet. That’s roughly 100 minutes daily, plus the lag before anyone calls. With this workflow, the lead is cleaned, scored, and written to Google Sheets automatically, then the call flow can run as soon as you trigger it, which usually takes a minute to kick off. You’re getting back about an hour a day and responding while the lead still cares.
Requirements
- n8n instance (try n8n Cloud free)
- Self-hosting option if you prefer (Hostinger works well)
- Google Sheets to store leads and summaries.
- Twilio to place the outbound voice calls.
- OpenAI API key (get it from the OpenAI dashboard).
Skill level: Intermediate. You’ll connect a few accounts, set webhook URLs, and confirm your sheet columns match the workflow fields.
Need help implementing this? Talk to an automation expert (free 15-minute consultation).
The Workflow Flow
A new lead hits your webhook endpoint. Your form submits to an n8n Webhook, which captures raw fields like name, email, phone, property reference, and the message.
The lead gets cleaned and validated. n8n standardizes field names, checks that the message is present, and runs a small code step to sanitize the text so AI classification is more consistent.
AI qualifies and your systems get context. OpenAI (via LangChain agent + chat model nodes) labels intent and urgency, then an HTTP request checks listing context with a property lookup API. After that, a scoring function calculates how you should prioritize this lead.
Follow-up happens fast, and the record is complete. For call outreach, a separate webhook starts the voice flow: a script is drafted, ElevenLabs generates audio, Twilio places the call, and another AI agent extracts the key answers. Then Google Sheets is updated with both detailed fields and a short summary.
You can easily modify the scoring rules to fit your market and your definition of “qualified.” See the full implementation guide below for customization options.
Step-by-Step Implementation Guide
Step 1: Configure the Webhook Trigger
Set up the inbound and secondary webhook triggers that kick off lead processing and voice call flows.
- Open Inbound Lead Webhook and copy the Test URL to use for incoming lead submissions.
- Open New Lead Webhook and copy the Test URL for the voice call flow entry point.
- Trigger each webhook once with sample payloads to generate example data for mapping in later steps.
Step 2: Configure the Scheduled and Manual Triggers
Enable periodic and on-demand research runs that fetch external data and populate research outputs.
- Open Scheduled Run Trigger and set your preferred schedule for automated research refreshes.
- Keep Manual Test Trigger available for ad-hoc runs while testing the research pipeline.
- Confirm both triggers connect to External Data Request in the workflow canvas.
Step 3: Map and Sanitize Incoming Lead Data
Normalize inbound data and prepare clean text for intent detection and lead scoring.
- In Map Incoming Fields, map inbound webhook fields (name, phone, message, address) to your standardized schema.
- In Check Message Present, ensure your condition checks for the presence of the message field before processing.
- In Sanitize User Text, implement cleaning logic (strip HTML, normalize whitespace) for reliable intent detection.
- In Pull Intent Results and Normalize Lead Fields, map the detected intent and normalize lead data formats.
Step 4: Set Up AI Intent Detection and Extraction
Configure the AI stack that interprets lead intent, extracts info, and generates summaries.
- Open Detect Intent Priority and verify it uses OpenAI Chat Engine A as its language model.
- Open Data Extraction Agent and confirm it is connected to OpenAI Chat Engine C.
- Open Research Assistant Agent and ensure it is connected to OpenAI Chat Engine B.
- Open Generate Lead Summary and verify it uses OpenAI Chat Engine D for summary generation.
- Open Lead Info Extraction and verify it uses OpenAI Chat Engine E for call transcript extraction.
Step 5: Configure Property Lookups and Lead Scoring
Enrich leads with property data and compute scoring logic before logging and outreach.
- In Property Lookup API, set the endpoint and request structure for your property data service.
- In Verify Listing Known, define the criteria that determines whether a listing is recognized.
- In Compute Lead Score, implement scoring logic that considers intent, listing match, and lead completeness.
- In Build Lead Payload, set the output fields that will be used downstream or sent to external systems.
Step 6: Configure Research and Parallel Outputs
Set up the research pipeline and parallel outputs for documents, spreadsheets, and AI completions.
- In External Data Request, set the request details for the research data source.
- In Data Extraction Agent, configure extraction rules for the inbound data format.
- Note that Research Assistant Agent outputs to both Docs Report Writer, Split Records, OpenAI Completion A, and OpenAI Completion B in parallel.
- In Split Records, define the output key that contains the list of records to split.
Step 7: Configure Voice Call Flow and Lead Updates
Build the outbound voice flow and ensure extracted values feed back into lead processing.
- In Assign Lead Variables, map the webhook fields needed for voice outreach (phone, name, property).
- In Draft Intro Message, craft the script text that will be converted to audio.
- In Create Voice Audio and Dial Out Call, set the HTTP request endpoints for your telephony provider.
- Confirm Lead Info Extraction feeds into Save Extracted Values and then Standardize User Data.
Step 8: Configure Lead Logging and Summaries
Finalize the lead logging pipeline for timestamped entries and summaries in Google Sheets.
- In Check Lead Interest, define the conditional logic that determines if a lead is worth scoring.
- In Set Lead Score and Format Date Time, finalize the fields used to log and timestamp the lead.
- In Log Lead to Sheets, map your lead fields to the target Google Sheet.
- In Generate Lead Summary, produce a structured summary that will be logged.
- In Log Summary to Sheets, map the summary fields to your summary sheet.
Step 9: Test and Activate Your Workflow
Run end-to-end tests to verify each branch and then activate the workflow for production use.
- Click Execute Workflow and trigger Inbound Lead Webhook with a sample lead payload.
- Run Manual Test Trigger to validate the external research pipeline and parallel outputs.
- Confirm successful execution when Log Lead to Sheets, Log Summary to Sheets, and Docs Report Writer produce new entries/documents.
- Activate the workflow by toggling the Active switch once all credentials and mappings are verified.
Watch Out For
- Google Sheets credentials can expire or need specific permissions. If things break, check the n8n credential connection status and the sheet sharing settings first.
- If you’re using Wait nodes or external rendering, processing times vary. Bump up the wait duration if downstream nodes fail on empty responses.
- Default prompts in AI nodes are generic. Add your brand voice early or you’ll be editing outputs forever.
Common Questions
About an hour if your Twilio and Google Sheets accounts are ready.
Yes, but you’ll want someone comfortable with webhook setup. No coding is required, though you may tweak a few text fields and scoring rules.
Yes. n8n has a free self-hosted option and a free trial on n8n Cloud. Cloud plans start at $20/month for higher volume. You’ll also need to factor in OpenAI API usage (often a few cents per lead) plus Twilio call charges.
Two options: n8n Cloud (managed, easiest setup) or self-hosting on a VPS. For self-hosting, Hostinger VPS is affordable and handles n8n well. Self-hosting gives you unlimited executions but requires basic server management.
You can adjust the scoring in the “Compute Lead Score” code node and the “Set Lead Score” function to match your pipeline. If your listing source is different, swap the “Property Lookup API” HTTP Request to hit your real endpoint and map its response in “Verify Listing Known.” Teams often customize the AI prompts in the intent/urgency agent so it reflects local market language, and they rename Google Sheets columns to match their CRM fields.
Usually it’s invalid or rotated Twilio credentials, or a “From” number that isn’t enabled for voice calling in your Twilio account. Also check that you’re formatting the destination phone number consistently (E.164 format is the safest) and that your Twilio project is allowed to call that region. If calls initiate but audio doesn’t play, the ElevenLabs request may be failing upstream, so confirm the audio URL exists before the “Dial Out Call” request runs.
For most small teams, it’ll handle daily lead volume without any tuning.
Often, yes, especially if you want AI-based scoring, branching logic, and multiple write-backs to Google Sheets without paying extra for every path. n8n is also easier to extend because you can edit the code and function nodes, not just connect blocks. And self-hosting removes execution limits, which matters once your lead volume climbs. Zapier or Make can be quicker for a simple “form → sheet → notification” flow, but this workflow is doing more than that. Talk to an automation expert if you want a quick recommendation for your exact stack.
Once this is running, leads stop being “messages to handle” and become clean, prioritized next actions. Honestly, that’s the difference between chasing and closing.
Need Help Setting This Up?
Our automation experts can build and customize this workflow for your specific needs. Free 15-minute consultation—no commitment required.