getreadystack's picture
Upload index.html with huggingface_hub
4790050 verified
Raw History Blame Contribute Delete
23.4 kB
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>n8n Lead Generation Template Pack — 5 B2B Outbound Workflows (CAN-SPAM and GDPR Fields Built In)</title>
<meta name="description" content="For B2B founders, SDRs and lead-gen agencies sending into US and EU inboxes from one n8n instance: every message carries a physical postal address and a working one-click unsubscribe link, and every opt-out is written to your do-not-contact tab the moment it is clicked. CAN-SPAM gives you 10 busines">
<link rel="canonical" href="https://getreadystack.com/tools/n8n-lead-generation-template-pack">
<script data-grow-initializer="">!(function(){window.growMe||((window.growMe=function(e){window.growMe._.push(e);}),(window.growMe._=[]));var e=document.createElement("script");(e.type="text/javascript"),(e.src="https://faves.grow.me/main.js"),(e.defer=!0),e.setAttribute("data-grow-faves-site-id","U2l0ZTphZjljMzgyMC0yMmU5LTRhYjgtYTIxNS03OTRhMGY1N2ExYzM=");var t=document.getElementsByTagName("script")[0];t.parentNode.insertBefore(e,t);})();</script>
<script type="application/ld+json" data-yj="yj-capsule-v1">{"@context": "https://schema.org", "@type": "FAQPage", "inLanguage": "en", "mainEntity": [{"@type": "Question", "name": "What does n8n Lead Generation Template Pack — 5 B2B Outbound Workflows actually do?", "acceptedAnswer": {"@type": "Answer", "text": "Five ready-to-import n8n workflows that carry your own lead list from a Google Sheet to a sent 3-step outbound sequence, with a physical postal address and a one-click unsubscribe link in every message and a written send log behind it. Opt-outs and hard bounces land on your do-not-contact tab the moment they arrive and the sequence re-reads that tab before every single run — CAN-SPAM allows 10 business days to honour an opt-out (15 U.S.C. § 7704(a)(4)(A)), this pack does it on the next run."}}, {"@type": "Question", "name": "Who is n8n Lead Generation Template Pack — 5 B2B Outbound Workflows for?", "acceptedAnswer": {"@type": "Answer", "text": "Two axes at once. Axis 1 — the job: B2B founders, SDRs and lead-gen agencies who already run n8n (self-hosted or cloud) and own their sending domain. Axis 2 — the jurisdiction pair: US recipients under CAN-SPAM and EU/EEA recipients under GDPR, which is why one sequence carries both a physical postal address in the footer and an Art. 6(1)(f) objection line, and why a separate workflow tracks the Art. 14 one-month deadline for EEA rows."}}, {"@type": "Question", "name": "What can I do for free, and what needs the paid version?", "acceptedAnswer": {"@type": "Answer", "text": "Run the free import-and-scrub workflow over your existing list first and read the rejection reasons — that alone tells you how much of your list you were not allowed to email. Then activate the unsubscribe webhook, copy its Production URL into the eight values of the 'Your sender identity and send cap' node, and only then activate the sequence."}}, {"@type": "Question", "name": "What would this cost if someone did it for me?", "acceptedAnswer": {"@type": "Answer", "text": "n8n Community Edition is free to self-host, so what this replaces is a recurring per-seat licence: cold-outreach sequencing platforms in this category (Apollo, Lemlist, Instantly and similar) are billed per user per month and stop sending the month you stop paying, while this pack is bought once and runs on the n8n instance you already have. On the regulatory side the anchor is statutory, not estimated: GDPR Art. 83(5) caps fines at €20 million or 4% of total worldwide annual turnover, whichever is higher, and CAN-SPAM requires a valid physical postal address and a working opt-out honoured within 10 business days (15 U.S.C. § 7704(a)(4)(A))."}}], "datePublished": "2026-09-25", "dateModified": "2026-09-25", "author": {"@type": "Organization", "name": "ReadyStack", "url": "https://getreadystack.com"}}</script>
</head>
<body>
<main><h1>n8n Lead Generation Template Pack — 5 B2B Outbound Workflows (CAN-SPAM and GDPR Fields Built In)</h1><p>Five ready-to-import n8n workflows that carry your own lead list from a Google Sheet to a sent 3-step outbound sequence, with a physical postal address and a one-click unsubscribe link in every message and a written send log behind it. Opt-outs and hard bounces land on your do-not-contact tab the moment they arrive and the sequence re-reads that tab before every single run — CAN-SPAM allows 10 business days to honour an opt-out (15 U.S.C. § 7704(a)(4)(A)), this pack does it on the next run.</p><h2>Free workflow — copy &amp; import</h2><pre id="j">{
"name": "1 - Lead list import, do-not-contact scrub and GDPR field stamping",
"nodes": [
{
"parameters": {},
"id": "b896059c-64f1-6f98-b896-059c64f16f98",
"name": "Run the check on your list",
"type": "n8n-nodes-base.manualTrigger",
"typeVersion": 1,
"position": [
0,
300
]
},
{
"parameters": {
"operation": "read",
"options": {}
},
"id": "b896059c-64f1-6f99-b896-059c64f16f99",
"name": "Read your do-not-contact tab",
"type": "n8n-nodes-base.googleSheets",
"typeVersion": 4.5,
"position": [
220,
300
]
},
{
"parameters": {
"jsCode": "const rows = $input.all().map(i => i.json);\nconst emails = [];\nconst domains = [];\nfor (const r of rows) {\n const e = String(r.email || r.Email || '').trim().toLowerCase();\n if (e) emails.push(e);\n const d = String(r.domain || r.Domain || '').trim().toLowerCase().replace(/^www\\./, '');\n if (d) domains.push(d);\n}\nreturn [{ json: { dnc_emails: emails, dnc_domains: domains, dnc_rows_read: rows.length } }];"
},
"id": "b896059c-64f1-6f9a-b896-059c64f16f9a",
"name": "Build the suppression set",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
440,
300
]
},
{
"parameters": {
"operation": "read",
"options": {}
},
"id": "b896059c-64f1-6f9b-b896-059c64f16f9b",
"name": "Read your raw lead list",
"type": "n8n-nodes-base.googleSheets",
"typeVersion": 4.5,
"position": [
660,
300
]
},
{
"parameters": {
"jsCode": "const dnc = $('Build the suppression set').first().json;\nconst blockedEmails = new Set(dnc.dnc_emails);\nconst blockedDomains = new Set(dnc.dnc_domains);\nconst roleAccounts = ['info', 'sales', 'support', 'admin', 'contact', 'hello', 'office', 'billing', 'noreply', 'no-reply', 'postmaster', 'abuse', 'privacy', 'jobs', 'careers'];\nconst freeMail = ['gmail.com', 'yahoo.com', 'hotmail.com', 'outlook.com', 'live.com', 'aol.com', 'icloud.com', 'me.com', 'gmx.de', 'gmx.net', 'web.de', 'proton.me', 'protonmail.com', 'mail.ru', 'yandex.ru'];\nconst pattern = /^[^@\\s]+@[^@\\s.]+\\.[^@\\s]{2,}$/;\nconst seen = new Set();\nconst now = new Date();\nconst day = d => d.toISOString().slice(0, 10);\nconst out = [];\nfor (const item of $input.all()) {\n const r = item.json;\n const email = String(r.email || r.Email || '').trim().toLowerCase();\n const local = email.split('@')[0] || '';\n const domain = (email.split('@')[1] || '').replace(/^www\\./, '');\n let status = 'ready';\n let reason = '';\n if (!pattern.test(email)) { status = 'rejected'; reason = 'email_not_valid'; }\n else if (seen.has(email)) { status = 'rejected'; reason = 'duplicate_in_file'; }\n else if (blockedEmails.has(email)) { status = 'rejected'; reason = 'on_do_not_contact_list'; }\n else if (blockedDomains.has(domain)) { status = 'rejected'; reason = 'domain_on_do_not_contact_list'; }\n else if (freeMail.includes(domain)) { status = 'rejected'; reason = 'not_a_business_domain'; }\n else if (roleAccounts.includes(local)) { status = 'rejected'; reason = 'role_account'; }\n if (email) seen.add(email);\n let collected = String(r.collected_at || '').trim();\n let collectedDate = collected ? new Date(collected) : now;\n if (isNaN(collectedDate)) collectedDate = now;\n if (!collected) collected = day(now);\n const noticeDue = new Date(collectedDate);\n noticeDue.setMonth(noticeDue.getMonth() + 1);\n out.push({ json: {\n email: email,\n first_name: String(r.first_name || '').trim(),\n last_name: String(r.last_name || '').trim(),\n company: String(r.company || '').trim(),\n role: String(r.role || r.title || '').trim(),\n domain: domain,\n country: String(r.country || '').trim().toUpperCase(),\n status: status,\n reason: reason,\n lawful_basis: status === 'ready' ? 'GDPR Art. 6(1)(f) legitimate interest' : '',\n source_url: String(r.source_url || '').trim(),\n collected_at: collected,\n art14_notice_due: day(noticeDue),\n art14_notice_sent: String(r.art14_notice_sent || '').trim(),\n step: Number(r.step || 0),\n last_sent_at: String(r.last_sent_at || '').trim(),\n replied: String(r.replied || '').trim(),\n bounced: String(r.bounced || '').trim(),\n unsubscribed: String(r.unsubscribed || '').trim(),\n paused: String(r.paused || '').trim(),\n checked_at: now.toISOString()\n } });\n}\nreturn out;"
},
"id": "b896059c-64f1-6f9c-b896-059c64f16f9c",
"name": "Clean, dedupe, suppress and stamp the GDPR fields",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
880,
300
]
},
{
"parameters": {
"operation": "append",
"options": {}
},
"id": "b896059c-64f1-6f9d-b896-059c64f16f9d",
"name": "Write every address back with a status and a reason",
"type": "n8n-nodes-base.googleSheets",
"typeVersion": 4.5,
"position": [
1100,
300
]
},
{
"parameters": {
"content": "SETUP (about five minutes)\n\n1. In your Google Sheet, create three tabs, spelled exactly like this:\n - Leads - Raw columns: email, first_name, last_name, company, role, country, source_url, collected_at\n - Do Not Contact columns: email, domain, reason, added_at\n - Leads - Checked leave it empty; this workflow writes the header row and the results\n country should be a two-letter code (US, DE, FR). collected_at should be a date like 2026-08-19. Both may be left blank; if collected_at is blank, today's date is used.\n\n2. In both Google Sheets nodes, choose your OWN Google Sheets OAuth2 credential. No credential ships with this file. Then paste your Sheet ID into the Document field of all three Sheets nodes. The Sheet ID is the long part of the sheet URL between /d/ and /edit.\n\n3. Press Execute Workflow. Every row from Leads - Raw comes back in Leads - Checked with status = ready or rejected, and a reason on the rejected ones.\n\nWHAT THE REASONS MEAN\n email_not_valid the address does not match the syntax pattern\n duplicate_in_file the same address appeared earlier in the same run\n on_do_not_contact_list the address is on your Do Not Contact tab\n domain_on_do_not_contact_list the whole domain is on your Do Not Contact tab\n not_a_business_domain a free-mail domain such as gmail.com\n role_account a shared inbox such as info@ or sales@\n\nTUNING\nOpen the Code node 'Clean, dedupe, suppress and stamp the GDPR fields'. The lists roleAccounts and freeMail are plain arrays at the top - add or remove entries to match how you sell. If you sell to sole traders who really do use gmail.com, delete that entry from freeMail.\n\nWHAT GETS STAMPED AND WHY\nRows that pass are stamped with lawful_basis = GDPR Art. 6(1)(f) legitimate interest, with the source_url you recorded, and with art14_notice_due set one month after collected_at. One month is the outer limit in GDPR Art. 14(3)(a) for telling a person you hold data you did not get from them. Nothing is deleted from your sheet - rejected rows are written back with the reason, so you can fix them and run again.",
"height": 220,
"width": 320
},
"id": "b896059c-64f1-6f9e-b896-059c64f16f9e",
"name": "Setup",
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
1320,
100
]
}
],
"connections": {
"Run the check on your list": {
"main": [
[
{
"node": "Read your do-not-contact tab",
"type": "main",
"index": 0
}
]
]
},
"Read your do-not-contact tab": {
"main": [
[
{
"node": "Build the suppression set",
"type": "main",
"index": 0
}
]
]
},
"Build the suppression set": {
"main": [
[
{
"node": "Read your raw lead list",
"type": "main",
"index": 0
}
]
]
},
"Read your raw lead list": {
"main": [
[
{
"node": "Clean, dedupe, suppress and stamp the GDPR fields",
"type": "main",
"index": 0
}
]
]
},
"Clean, dedupe, suppress and stamp the GDPR fields": {
"main": [
[
{
"node": "Write every address back with a status and a reason",
"type": "main",
"index": 0
}
]
]
}
},
"settings": {
"executionOrder": "v1"
},
"pinData": {},
"meta": {
"templateId": "n8n-lead-gen-b2b-outbound-pack"
}
}</pre></main>
<section data-yj-cta="paid" style="margin:3rem auto;max-width:46rem;padding:1.5rem 1.25rem;border:1px solid #d8dee9;border-radius:12px;background:#fbfcfe;font:16px/1.6 system-ui,-apple-system,Segoe UI,sans-serif"><h2 style="margin:0 0 .5rem;font-size:1.25rem">Get the complete version <span class="yj-price">$59</span></h2><p style="margin:.25rem 0 1rem;color:#41505f">This page is the working piece. The full pack has everything below.</p><p style="margin:0 0 1rem;color:#41505f">For B2B founders, SDRs and lead-gen agencies sending into US and EU inboxes from one n8n instance: every message carries a physical postal address and a working one-click unsubscribe link, a</p><p style="margin:0 0 1rem;color:#5b6b7c;font-size:.94rem">n8n Community Edition is free to self-host, so what this replaces is a recurring per-seat licence: cold-outreach sequencing platforms in this category (Apollo, Lemlist, Instantly and similar) are billed per user per month and stop</p><a href="https://getreadystack.com/api/buy/cl/polar_cl_GxB7xE7ByCjvNPbMOjZOb2xb6mhgHCk0F5cez0LGTwL" rel="nofollow" style="display:inline-block;padding:.7rem 1.3rem;border-radius:8px;background:#1b64f2;color:#fff;text-decoration:none;font-weight:600">Buy the full version — $59</a></section>
<section class="yj-related" style="max-width:920px;margin:56px auto 40px;padding:0 20px"><h2 style="font:600 21px/1.3 system-ui,sans-serif;margin:0 0 6px;color:#1b1f24">More from ReadyStack</h2><p style="font:400 14.5px/1.5 system-ui,sans-serif;margin:0 0 20px;color:#5b6570">Ready-to-use files. One-time download, no subscription.</p><div style="display:grid;grid-template-columns:repeat(auto-fill,minmax(250px,1fr));gap:14px"><a class="yj-rel-c" href="https://getreadystack.com/tools/clothing-shopify-theme"><span class="yj-rel-t">Clothing Shopify Theme — Size, Fit &amp; Seasonal Drop Sections for Apparel Stores</span><span class="yj-rel-p">$200</span></a><a class="yj-rel-c" href="https://getreadystack.com/tools/docker-image-for-development"><span class="yj-rel-t">Docker Image for Development — Node.js 22 + TypeScript Dev Container with Post</span><span class="yj-rel-p">$19</span></a><a class="yj-rel-c" href="https://getreadystack.com/tools/notary-website-template"><span class="yj-rel-t">Notary Website Template — 9-Page Mobile Notary &amp; Loan Signing Site in Plain HT</span><span class="yj-rel-p">$49</span></a><a class="yj-rel-c" href="https://getreadystack.com/tools/ecommerce-icon-pack"><span class="yj-rel-t">Ecommerce Icon Pack UI Kit — Cart, Checkout &amp; Order-Status Components in 32 St</span><span class="yj-rel-p">$168</span></a><a class="yj-rel-c" href="https://getreadystack.com/en/p/cut-your-car-payment-the-refinance-decision-workbook"><span class="yj-rel-t">Cut Your Car Payment: The Refinance Decision Workbook</span><span class="yj-rel-p">$12</span></a><a class="yj-rel-c" href="https://getreadystack.com/tools/wholesale-shopify-theme"><span class="yj-rel-t">Wholesale Shopify Theme — B2B trade store for stockists (MOQ, case packs, net </span><span class="yj-rel-p">$200</span></a></div><style>.yj-rel-c{display:flex;flex-direction:column;gap:8px;padding:15px 16px;border:1px solid #e2e6ea;border-radius:6px;text-decoration:none;background:#fff}.yj-rel-c:hover{border-color:#b9c2cb;background:#fafbfc}.yj-rel-t{font:500 14.5px/1.42 system-ui,sans-serif;color:#1b1f24}.yj-rel-p{font:600 13px system-ui,sans-serif;color:#0a6238}</style></section><!--yj-share-s101--><div style="margin:28px 0 8px;text-align:center"><button id="yjcp" type="button" style="font:inherit;padding:10px 18px;border:1px solid #8884;border-radius:10px;background:transparent;cursor:pointer">Copy link</button></div><script>(function(){var b=document.getElementById("yjcp");if(!b)return;var t=b.textContent;b.addEventListener("click",function(){var u=location.href.split("#")[0];function d(){b.textContent="Link copied";setTimeout(function(){b.textContent=t;},1800);}if(navigator.clipboard&&navigator.clipboard.writeText){navigator.clipboard.writeText(u).then(d,function(){prompt("",u);});}else{prompt("",u);}});})();</script>
<section class="yj-email-gate" style="max-width:46rem;margin:2.5rem auto;padding:1.25rem;border:1px solid rgba(140,150,165,.28);border-radius:10px;font:400 15px/1.5 system-ui,sans-serif"><b style="font-size:1.05rem">Want the full version?</b><div style="opacity:.75;margin:.35rem 0 .8rem">Enter your email and we send the download link.</div><div style="display:flex;gap:8px;flex-wrap:wrap"><input id="yjge" type="email" placeholder="you@example.com" style="flex:1;min-width:210px;padding:11px 13px;border:1px solid rgba(140,150,165,.34);border-radius:8px;background:rgba(255,255,255,.04);color:inherit"><button id="yjgb" style="padding:11px 18px;border-radius:8px;border:0;cursor:pointer;font:600 15px system-ui,sans-serif">Send it to me</button></div><div id="yjgo" hidden style="margin-top:.6rem;color:#5fbf9a">Sent. Check your inbox.</div><script>(function(){var b=document.getElementById("yjgb"),e=document.getElementById("yjge");if(!b||!e)return;b.addEventListener("click",function(){var v=e.value.trim();if(!/.+@.+\..+/.test(v))return;try{localStorage.setItem("yj_em","1");}catch(_){}fetch(location.origin+"/api/subscribe",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({email:v,slug:"n8n-lead-generation-template-pack",lang:"en",source:"hub_gate"})}).catch(function(){}).then(function(){document.getElementById("yjgo").hidden=false;});});})();</script></section>
<div class="yj-home-find"><div class="yj-lgbar"><a href="/" class="yj-lg on">EN</a><a href="/de/" class="yj-lg">DE</a><a href="/ja/" class="yj-lg">JA</a><a href="/es/" class="yj-lg">ES</a><a href="/pt/" class="yj-lg">PT</a></div><section class="yj-find"><h2>Find a tool</h2><input id="yjq" type="search" autocomplete="off" placeholder="Type a product name, format or task"><div id="yjr"></div></section><style>.yj-lgbar{position:absolute;top:14px;right:18px;display:flex;gap:6px;z-index:60}.yj-lg{font:600 12px/1 system-ui,sans-serif;padding:6px 9px;border-radius:4px;text-decoration:none;color:#8b96a3;border:1px solid rgba(140,150,165,.28)}.yj-lg:hover{color:#e8eaed;border-color:rgba(160,175,195,.6)}.yj-lg.on{color:#0e1116;background:#cfd6de;border-color:#cfd6de}.yj-find{max-width:760px;margin:34px auto 8px;padding:0 20px}.yj-find h2{font:600 20px/1.3 system-ui,sans-serif;margin:0 0 10px}#yjq{width:100%;box-sizing:border-box;padding:13px 15px;font:400 15.5px system-ui,sans-serif;border:1px solid rgba(140,150,165,.34);border-radius:8px;background:rgba(255,255,255,.04);color:inherit}#yjq:focus{outline:none;border-color:#7FD1C4}#yjr{margin-top:10px;display:flex;flex-direction:column;gap:6px}#yjr a{display:flex;justify-content:space-between;gap:12px;padding:11px 14px;border:1px solid rgba(140,150,165,.22);border-radius:6px;text-decoration:none;font:400 14.5px/1.4 system-ui,sans-serif;color:inherit}#yjr a:hover{border-color:#7FD1C4}#yjr .pr{font:600 13px system-ui,sans-serif;color:#5fbf9a;white-space:nowrap}</style><script>(function(){var q=document.getElementById("yjq"),r=document.getElementById("yjr"),D=null;function load(){if(D)return Promise.resolve(D);return fetch("/search-index.json").then(function(x){return x.json();}).then(function(j){D=j;return j;}).catch(function(){D=[];return D;});}function esc(t){return String(t).replace(/[&<>"]/g,function(c){return {"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;"}[c];});}function run(){var v=q.value.trim().toLowerCase();if(v.length<2){r.innerHTML="";return;}load().then(function(j){var w=v.split(/\s+/),o=[];for(var i=0;i<j.length&&o.length<12;i++){var t=j[i].t.toLowerCase();var ok=true;for(var k=0;k<w.length;k++){if(t.indexOf(w[k])<0){ok=false;break;}}if(ok)o.push(j[i]);}r.innerHTML=o.length?o.map(function(x){return "<a href=\""+esc(x.u)+"\">"+"<span>"+esc(x.t)+"</span>"+(x.p?"<span class=\"pr\">$"+x.p+"</span>":"")+"</a>";}).join(""):"";});}q.addEventListener("input",run);q.addEventListener("focus",load);})();</script></div>
<script data-yj="yj-view-beacon">(function(){try{var p=location.pathname;var k='yjv:'+p;if(sessionStorage.getItem(k))return;sessionStorage.setItem(k,'1');fetch('/api/ev',{method:'POST',keepalive:true,headers:{'Content-Type':'application/json'},body:JSON.stringify({path:p,lang:"en",ref:(document.referrer||''),src:(function(){try{return (new URLSearchParams(location.search).get('ref')||'').replace(/[^a-z_]/g,'').slice(0,12)}catch(e){return ''}})()})}).catch(function(){});}catch(e){}})();</script>
<script data-yj="yj-use-beacon v2">(function(){try{var r=document.querySelector('main')||document.body;var p=location.pathname,k='yju:'+p,sent=false,armed=false;function ours(el){return !!(el&&el.closest&&el.closest('[data-yj],[data-yj-cta],.yj-email-gate,.yj-find,.yj-related,#yj-ask,#yjgo,#yjr'));}function fire(){if(sent||!armed||sessionStorage.getItem(k))return;sent=true;sessionStorage.setItem(k,'1');fetch('/api/ev',{method:'POST',keepalive:true,headers:{'Content-Type':'application/json'},body:JSON.stringify({path:p,lang:"en",t:'use',src:(function(){try{return (new URLSearchParams(location.search).get('ref')||'').replace(/[^a-z_]/g,'').slice(0,12)}catch(e){return ''}})()})}).catch(function(){});}r.addEventListener('click',function(e){var b=e.target&&e.target.closest?e.target.closest('button,input[type=submit],[role=button]'):null;if(!b||ours(b))return;armed=true;setTimeout(fire,400);},true);r.addEventListener('input',function(e){if(!ours(e.target))armed=true;},true);var mo=new MutationObserver(function(){if(armed){fire();if(sent)mo.disconnect();}});mo.observe(r,{childList:true,characterData:true,subtree:true});}catch(e){}})();</script>
</body>
</html>