Lead Qualification
An inbound-lead pipeline on self-hosted n8n. A web form posts to a webhook that responds in about 70 ms; the lead is validated, de-duplicated, classified by an LLM, scored in plain code and routed to HubSpot, Slack, Google Sheets and a personalised Gmail reply. In live testing the sales rep was notified in 6.6 seconds and the prospect got a reply in 8.1 seconds.
- 6.6 s
- from form submit to rep notified
- 8.1 s
- to a personalised reply
- 11/11
- test leads routed correctly
- 25 → 1
- identical submissions become one contact
What I built
- The webhook acknowledges in about 70 ms, then validates and normalises the lead before anything else runs.
- An idempotency key with a UNIQUE constraint makes de-duplication atomic: 25 simultaneous identical submissions produce exactly one contact.
- Google Gemini classifies intent, urgency, pain and fit as strict JSON; the score itself is calculated in readable code, not by the model.
- Each lead is routed as HOT, WARM, COLD, REVIEW or DISCARD: a HubSpot contact and deal, a Slack alert, a Sheets digest and a personalised Gmail reply.
- A dead-letter queue with scheduled replay means a failing downstream service delays a lead instead of losing it: 0 leads lost in live testing.
- Workflows are kept as code (JavaScript builders and a deploy CLI) and covered by a 175-assertion offline test suite.
Stack
- n8n
- Node.js 20
- PostgreSQL
- Google Gemini
- HubSpot
- Slack
- Google Sheets
- Gmail
