DEV Community

Zhang Lixiang
Zhang Lixiang

Posted on Edited on

n8n orchestrates, LangGraph writes, a human approves: an AI cold-email pipeline that can't spam

"AI SDR" demos usually end with an agent firing off a few hundred emails. In real B2B sales that burns your domain within a week, and the emails are full of claims nobody can back up.

I built a lead-generation pipeline around an export manufacturer's use case, with three rules. Every claim in an email has to come from data the APIs returned, quoted verbatim. A rule checker rejects bad drafts and sends them back for a rewrite, at most twice. And nothing is sent until a person clicks Approve.

The part I found most useful was deciding what goes in n8n and what goes in LangGraph.

n8n does the plumbing

The n8n side is 55 nodes and handles everything deterministic: manual, schedule and webhook triggers; Apollo to find people and enrich emails; Hunter to verify them; dedupe against the CRM and qualification filters; HubSpot or a Google Sheet as the CRM; an approval link per draft, an unsubscribe link, and a suppression list that is checked again right before sending. Sending goes through SendGrid, Gmail or SMTP, behind a SEND_ENABLED flag.

LangGraph does the parts that need a model

A small FastAPI service runs the graph:

research -> write -> check -> (rewrite, max 2) -> draft for approval
Enter fullscreen mode Exit fullscreen mode

The research step writes a short note about the company. Every reason in it must carry a verbatim quote from the lead data, otherwise it's cleared. The write step drafts the email from that note and nothing else.

The check step is plain code. It blocks numbers that don't appear in the research or the approved facts, unsupported claim phrases, placeholders and empty fields, a missing unsubscribe line, and drafts that run too long. A failing draft goes back to a rewrite step with the checker's reasons. After two failed rewrites it's flagged needs_human_fix and never sent.

The model can be any OpenAI-compatible endpoint: OpenAI, DeepSeek, Qwen, OpenRouter.

I made the checker code rather than a second LLM because an LLM grading an LLM tends to agree with itself. A regex and a list of allowed numbers don't. It's dull, and it's the reason I'd trust the drafts enough to put them in front of a salesperson.

Switching industries

Target industry, buyer type, product lines and selling points live in one profile file, and a small script turns it into the n8n variables. The kit includes a battery-storage example and an LED-lighting example.

Testing

There are 21 pytest tests for the LangGraph service and 8 JS tests for the n8n Code nodes. A live run on a real n8n instance (1.123.87) with local mock Apollo, Hunter, HubSpot and SendGrid passed 26 of 26 checks. Ten fake leads end to end gave 6 drafts waiting for approval, 2 disqualified, 1 deduped and 1 blocked by the unsubscribe list.

Those runs used mocked vendor APIs and a deterministic fake model, so I haven't seen how drafts look with a real model and real Apollo data. You bring your own Apollo, Hunter, HubSpot, SendGrid and LLM keys.

The template

The full kit (importable n8n workflow, LangGraph + FastAPI service, Docker Compose, tests, sample profiles) is $29 on Gumroad: B2B AI Lead Generation: n8n + LangGraph template.

I also wrote about a WhatsApp bot where the LLM may only pick an FAQ id. There's a free version in the n8n template library (workflow 21700) and a full kit for $19.

Top comments (0)