AI Lead Scoring and Routing
Scores every inbound lead on intent and fit, then routes it to the right regional team with an SLA attached, automatically.
Fully built and tested in n8n, covering sanitization, duplicate detection, AI scoring, and regional routing end to end. Next phase is connecting this to a real CRM instead of Google Sheets, and building out a feedback loop so sales can mark a Hot lead as a false positive and have that feed back into the scoring rules.
A Form Trigger collects nine fields and redirects the visitor to a thank-you page instantly, the actual pipeline runs in the background afterward. The first stop is a Sanitize Data node that strips HTML, normalizes shouted text, collapses whitespace, and checks the email against a blocklist of disposable domains. An IF node checks for any validation errors, if the email is disposable or something looks wrong, the submission goes straight to a Slack alert in a review channel and stops there, it never reaches the CRM or the AI.
Everything that passes goes to a Google Sheets lookup by email, merged back with the sanitized data. A second IF node checks whether that email already exists in the CRM, if so, the lead gets a warm re-engagement email and the pipeline stops, no duplicate row, no duplicate AI call.
New leads move on to Gemini, which reads the free-text message and returns a structured intent signal, an urgency flag, and a one-sentence fit note. Those AI signals combine with deterministic rules, company size, budget, service type, job title, into a single score. That score decides the category (Hot, Warm, Cold), which decides the SLA and which regional Slack channel gets notified. Every lead, whatever the outcome, gets logged to the CRM sheet with its score and category attached.
- Validation is deliberately split across two layers, the browser catches what it can (required fields, email format), and the workflow catches what the browser can't (disposable domains, suspicious patterns), so neither layer is doing the other's job
- AI signals add to a score rather than deciding the category outright, a lead still needs real structured signals (budget, company size) to reach Hot, the model influences the outcome without controlling it alone
- alwaysOutputData is set on the CRM lookup node, since Google Sheets returns zero items on no match, which would otherwise stop a brand new lead from ever reaching the Merge node
- Structured fields alone missed what actually mattered in a lead's message, a big-budget lead who wrote 'just exploring' scored the same as one who wrote 'need this live by end of month.' Fixed by sending the message to Gemini for a structured intent and urgency read that feeds into, but doesn't override, the deterministic score
- A duplicate submission was creating a second CRM row, a second Slack alert, and a second Gemini call, tripling cost and creating conflicting records for the same lead. Fixed with a lookup-and-merge step before scoring ever runs
- Gemini calls have retry logic (3 tries) since transient API failures or malformed JSON responses would otherwise silently drop a valid lead at the scoring step
- A Structured Output Parser enforces the shape of the AI's response, so downstream routing logic never has to guess at a free-text answer
- A connected Error Workflow catches any uncaught execution failure separately from the business-logic Slack alerts
- Judge Intent and Urgency (the Gemini step) retries three times with a short wait between attempts before it's treated as a real failure
- Re-submitting the same email is always safe, duplicate detection catches it before any data is written twice
- Disposable and suspicious email domains are blocked before a submission ever reaches the CRM or the AI, not after
- Every field is sanitized (HTML stripped, length capped) before it's stored or used in a prompt
Splitting validation into a browser layer and a workflow layer. It meant not over-engineering the frontend and not blindly trusting it either, each layer only handles what the other genuinely can't.
Getting the AI's contribution to the score right. It would have been easy to let the model's read on intent decide the category outright. The better design keeps deterministic signals as the backbone and lets AI add nuance on top, not replace judgment with a guess.
- Connect to a real CRM instead of Google Sheets
- A feedback loop so sales can flag a false-positive Hot lead and have that inform future scoring
- A weekly digest of lead volume, average score, and SLA adherence by region
- Configurable scoring weights instead of hardcoded point values
The Global Error Handler
Every workflow on this site, including this one, reports into the same error handler instead of failing silently. When any node in any workflow throws, n8n's Error Trigger catches it, a small code step pulls out the workflow name, the node that failed, and the actual error message, and it lands in my inbox as a plain email alert. One shared piece of infrastructure instead of duplicating error-handling logic four separate times.