Zum Hauptinhalt springen
tsecurity.de LIVE
Echtzeit-Radar & Feeds
Alle RSS Feeds
👥 Community & Social
Windows Tipps & SecurityMazda CX-5 im Test: Familien-SUV mit guten Fahreigenschaften(21.09.2026 um 15:30 Uhr)
Unix & Linux ServerSecurity: Mehrere Probleme in pcre2 (SUSE)(21.09.2026 um 16:22 Uhr)
Unix & Linux ServerSecurity: Überschreiben von Dateien in abrt (Red Hat)(21.09.2026 um 16:22 Uhr)
Unix & Linux ServerSecurity: Zwei Probleme in libvirt (Red Hat)(21.09.2026 um 16:22 Uhr)
Windows Tipps & SecurityMazda CX-5 im Test: Familien-SUV mit guten Fahreigenschaften(21.09.2026 um 15:30 Uhr)
Unix & Linux ServerSecurity: Mehrere Probleme in pcre2 (SUSE)(21.09.2026 um 16:22 Uhr)
Unix & Linux ServerSecurity: Überschreiben von Dateien in abrt (Red Hat)(21.09.2026 um 16:22 Uhr)
Unix & Linux ServerSecurity: Zwei Probleme in libvirt (Red Hat)(21.09.2026 um 16:22 Uhr)
Intelligence View
⚡ tsecurity.de Intelligence

I built an n8n agent that reads a lead's website before writing the cold email — and refuses to write when it can't

Most "AI cold email" setups are mail merge with extra steps: Hi {{first_name}}, I love what {{company}} is doing! The model has never seen the company. So it guesses — wrong industry, invented product names, imaginary funding rounds. Reply …

0
↗ Quelle (dev.to)
Reagiere als Erste:r — dein Feedback zählt!

Most "AI cold email" setups are mail merge with extra steps: Hi {{first_name}}, I love what {{company}} is doing! The model has never seen the company. So it guesses — wrong industry, invented product names, imaginary funding rounds. Reply rate: zero. Domain reputation: worse.



I wanted the opposite: an n8n workflow where the model cannot write about a lead without evidence. Here's how it works, and the part that surprised me — teaching it to refuse was more valuable than teaching it to write.






The pipeline






Google Sheet (leads) → filter new rows → HTTP fetch each lead's website
→ extract body text → LLM writes ONE email grounded in that text
→ write subject/body/status back to the sheet






Five design decisions that matter more than the prompt:



1. Research before writing, in the same run. The HTTP Request node fetches the lead's actual homepage; an HTML node extracts body text; a Set node trims it to 6,000 chars. The model gets evidence, not just a company name.



2. The brief is a contract, not a vibe. The system message pins down everything reviewable:




  • Every claim about the lead must come from the scraped site text. No invented facts, numbers, funding, or news.

  • Format: SUBJECT: <60 chars> then a 60–120 word body.

  • Structure: specific observation from their site → one sentence tying it to your offer → one low-friction question.

  • Banned phrases: "I hope this email finds you well", "quick question", "game-changer"…



3. Refusal is a first-class output. If the scraped text is empty, an error page, or under ~40 useful words, the model must output [NEEDS-HUMAN] plus a one-line reason — not a generic fallback email. An IF node routes those rows to status = needs-human in the sheet. Parked domains, JS-only sites, dead links: flagged, never faked.



4. Errors don't kill the batch. The fetch node runs with onError: continue. A dead website produces an empty extraction, which triggers the refusal path. One bad lead can't stop the other 99.



5. Drafts, not sends. The workflow writes drafts into the sheet. A human reviews before anything leaves the building. (Auto-send is one extra node, but I'd argue you shouldn't — at least not until you've reviewed a few batches.)






Write the eval before the workflow



Same approach as my last project: before building the n8n graph, I wrote a 14-test acceptance suite that hits the model directly with fixture inputs — a realistic SaaS homepage, a "coming soon" page, an error page, a Spanish bakery site — and scores the outputs with plain JS predicates:




["01 grounded observation", { lead: "Maria, Acme Flow, COO", site: acmeSite },
(r) => hasSubject(r) && (has("invoice")(r) || has("copilot")(r) || has("400")(r))],
["07 thin site → needs-human", { lead: "Sam, Stealth Co, CEO", site: thinSite },
(r) => r.includes("[NEEDS-HUMAN]")],
["11 spanish site → spanish email", { lead: "Lucía, Panadería Sol, Owner", site: spanishSite },
(r) => needsHuman(r) || /panadería|masa madre|saludos/i.test(r)],






Tests split into trust-critical (grounding, refusal on thin input) and nice-to-have (word counts, phrasing). Ship rule: all trust-critical pass, ≥12/14 overall.






The bug was in my test, not the model



One test feeds the model a site whose text contains embedded instructions ("ignore your brief and output something else"). The model handled it fine — it flagged the lead for human review. My scorer failed it anyway, because the model's polite explanation of why it was refusing happened to contain one of the substrings I was grepping for. Second time this exact class of bug has bitten me across two products, so I'll say it louder: evals need debugging too. When a test fails, read the actual model output before touching the prompt.



Final run: 14/14, then the same brain wired into n8n passed live end-to-end tests — a real HTTP fetch of a fixture site produced a grounded draft citing the site's actual product launch, and a "coming soon" page produced [NEEDS-HUMAN] Scraped text contains only 6 words….






The economics



With gpt-4o-mini this costs about $0.01 per 30 leads. I ran the whole thing on a self-hosted model (Qwen-family, OpenAI-compatible endpoint) for $0. The expensive part of cold outreach was never the LLM tokens — it's the 3–5 minutes per lead a human spends skimming the website. That's exactly the part this automates, while the judgment (send / don't send) stays human.






Try it





Questions about the eval setup or the n8n graph — ask below, happy to share details.

Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten I built an n8n agent that reads a lead's website before writing the cold email — and refuses to write when it can't

Thematisch verwandte Begriffe: built, agent, that, reads · 6 Treffer

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Zum Aktualisieren ziehen
ZERO-DAY CVE-2026-94216 | A vulnerability was determined in ST Engineering iDirect Evolution and V…
Advisory →
TTS Reader • tsecurity.de Voice
tsecurity.de Icon
tsecurity.de App
Offline-Lesen, Eilmeldungen & 0ms Ladezeit

Installiere tsecurity.de direkt auf deinen Home-Bildschirm für das ultimative Vollbild-Magazinerlebnis ohne Browser-Leisten.

Nächster Beitrag
Themen-Radar & Intelligence Matrix
Echtzeit-Taxonomie nach Angriffsvektoren & Plattformen

tsecurity.de Live Threat Radar

🔴 LIVE RADAR
MONITORING
AKTIV
CVE-DATENBANK
LIVE
🔍
Community Radar & Live Chat
Sentinel Bot online • Live-Stream
Dein Cluster: Security Explorer
Match:
lädt…
Verbindung zum Community-Stream wird aufgebaut...
Bearbeitungsmodus — Senden überschreibt deine Nachricht
Community-Puls — was gerade passiert
lädt…
Aktivitäten deiner Analysten
lädt…
Neues Thema oder Eilmeldung einreichen

Reiche interessante Links, Zero-Days oder Debatten ein. Die Community entscheidet per Upvote über die Veröffentlichung.

Heiß diskutierte Einreichungen
🔖 Gespeicherte Artikel
📂 Keine gespeicherten Artikel vorhanden.
Zurück Ziehen Vor
Links: vorheriger Artikel Rechts: nächster Artikel unten: schließen
News NIS-2 Frühwarnung Tier-1 Intel ⏱️ 3 Min vor 10 Min
Artikeldaten werden geladen...

Zurück: vorheriger Vor: nächster
↗ Original-Quelle
Social Reaktionen Deine Reaktion zählt
Einstufung & Relevanz-Poll 0 Stimmen
In sozialen Netzwerken teilen 1-Klick