AI Lead Intake & Qualification Pipeline
A self-hosted n8n automation I built at Vitrosens Biotechnology that turns inbound sales emails into structured, qualified leads. It watches a mailbox, sends each email to an LLM to extract the contact details, then a deterministic step re-validates and scores the lead, routes qualified ones to the CRM (with a logged audit record and a Teams ping) and sets rejected ones aside with a reason. Every run leaves a uniform audit record that feeds a static dashboard and a scheduled monthly report. Runs as three hardened Docker containers.
- n8n
- Gemini
- Python
- Docker
- Nginx
- ApexCharts
Summary. A self-hosted n8n automation I built at Vitrosens Biotechnology that turns inbound sales emails into structured, qualified leads. It watches a mailbox, extracts the contact details with an LLM, scores and qualifies the lead with deterministic code, and routes the good ones to the CRM, while every run leaves an audit record that feeds a dashboard and a monthly report.
Extraction you can trust
The LLM (Gemini by default, with a fallback model wired in) does the reading: it pulls the company, contact name, email, phone, country, and website out of the message, plus a short summary framed in the company's context. It is held to a strict JSON schema with allowed values, and the prompt opens with an injection guard. Then a deterministic code step re-validates everything against allowlists and scores the lead on field completeness, with a hard gate that rejects anything with no email and no phone, since that lead is unreachable. The model proposes; the code decides.
Four workflows behind it
The stack is four small, published workflows, all version-controlled as JSON and generated from code: the main email-to-lead pipeline, a pipeline error handler that captures any failure as an audit record, a monthly operations report that emails on the first of the month, and a demo leads handler that stands in for a real CRM so the downstream handoff can be shown end to end.
Every run leaves a record
Whether a run succeeds or fails, it writes one uniform audit record to disk, and failures anywhere in the pipeline are captured the same way through n8n's error workflow, so nothing disappears quietly. A dependency-free Python package, clean and fully tested, turns those records into a static dashboard with KPI cards, a leads-per-day trend, a pipeline funnel, and a searchable audit table, and into a monthly operations report that is emailed automatically.
Self-hosted and locked down
It runs as three Docker containers: n8n as the engine, a small Python tools container that rebuilds the dashboard data and the report, and nginx in front. The dashboard sits behind self-signed TLS and HTTP basic auth on a hidden path, with fail2ban banning an address after repeated failed logins, and the n8n editor on its own port; the root path serves nothing. A single, idempotent deploy script brings the whole stack up.
Stack
n8n for the workflow, Gemini for extraction, Microsoft Outlook for the mailbox, and Python for the stats and reports, with the dashboard drawn by a vendored ApexCharts so it works offline. Docker, nginx, and fail2ban for delivery and hardening. The workflows are version-controlled as JSON and generated from code, with a real test, lint, and type-check suite.
Questions
Does the AI decide who counts as a lead?
No. The LLM extracts the fields from the email, but a deterministic code step re-validates them against allowlists and scores the lead, so the decision is repeatable and the model cannot wave bad data through. The prompt also has an injection guard.
What happens if the LLM or the CRM call fails?
Every failure, anywhere in the pipeline, is captured as the same kind of audit record on disk through n8n’s error workflow, so nothing is lost silently and it shows up on the dashboard.