GummyMail - Next Gen Gumroad AutoReply & CRM System
Pull contacts, verify each address with BillionVerify, and continue to Gumroad β only deliverable addresses get through.
Why verify before the send
Sending to invalid, risky, catch-all, or disposable addresses spikes your bounce rate and erodes sender reputation. A verification gate before the Gumroad step removes that risk automatically β only deliverable addresses continue, the rest are flagged.
The workflow
BillionVerify β verification sits right before the send.
Node by node
- 1Gmail TriggerTriggerΒ· n8n
Starts the workflow β on a schedule, a webhook, or manually while you test.
- 2Google Gemini Chat ModelSourceΒ· n8n
Provides or transforms the contact data flowing through the workflow.
- 3Code in JavaScriptSourceΒ· n8n
Provides or transforms the contact data flowing through the workflow.
- 4Get many database pagesSourceΒ· n8n
Provides or transforms the contact data flowing through the workflow.
- 5IfLogicΒ· n8n
Branches on the verification result: only deliverable addresses continue to the send; the rest are skipped and flagged.
- 6Create a database pageSourceΒ· n8n
Provides or transforms the contact data flowing through the workflow.
- 7Stop and ErrorSourceΒ· n8n
Provides or transforms the contact data flowing through the workflow.
- 8AI AgentSourceΒ· n8n
Provides or transforms the contact data flowing through the workflow.
- 9Verify Email (BillionVerify)VerifyΒ· billionverify
The BillionVerify node verifies the address β status (valid / invalid / risky / catch-all / role / disposable), is_deliverable, and a confidence score β before anything is sent.
- 10IF deliverableLogicΒ· n8n
Branches on the verification result: only deliverable addresses continue to the send; the rest are skipped and flagged.
- 11Send a messageSendΒ· n8n
Sends only to verified, deliverable addresses. Swap in your own provider node if you send elsewhere.
Workflow JSON
Copy or download this workflow, then import it in n8n (Workflows β Import from File / Paste). Install the BillionVerify community node first, then add your API key credential.
{
"name": "GummyMail - Next Gen Gumroad AutoReply & CRM System + BillionVerify",
"nodes": [
{
"id": "f6bbafa7-a682-4714-9bd5-ca8f5e6d20fd",
"name": "Gmail Trigger",
"type": "n8n-nodes-base.gmailTrigger",
"position": [
0,
0
],
"parameters": {
"filters": {
"q": "New sale of "
},
"pollTimes": {
"item": [
{
"mode": "everyHour"
}
]
}
},
"credentials": {
"gmailOAuth2": {
"id": "credential-id",
"name": "gmailOAuth2 Credential"
}
},
"typeVersion": 1.3
},
{
"id": "c8c48cc8-1b6a-4d53-a486-c4f30054deff",
"name": "Create a database page",
"type": "n8n-nodes-base.notion",
"position": [
1008,
-16
],
"parameters": {
"options": {},
"resource": "databasePage",
"databaseId": {
"__rl": true,
"mode": "list",
"value": "2c411b7d-dc06-80fc-87e9-db7d5c714c1e",
"cachedResultUrl": "https://www.notion.so/2c411b7ddc0680fc87e9db7d5c714c1e",
"cachedResultName": "Gumroad Leads"
},
"propertiesUi": {
"propertyValues": [
{
"key": "Name|title",
"title": "={{ $('Code in JavaScript').item.json.name }}"
},
{
"key": "email|rich_text",
"textContent": "={{ $('Code in JavaScript').item.json.email }}"
},
{
"key": "Product|rich_text",
"textContent": "={{ $('Code in JavaScript').item.json.product }}"
},
{
"key": "Purchase Date|rich_text",
"textContent": "={{ $('Code in JavaScript').item.json.purchaseDate }}"
},
{
"key": "Quantity|rich_text",
"textContent": "={{ $('Code in JavaScript').item.json.quantity }}"
},
{
"key": "UniqueKey|rich_text",
"textContent": "={{ $('Code in JavaScript').item.json.uniqueKey }}"
}
]
}
},
"credentials": {
"notionApi": {
"id": "credential-id",
"name": "notionApi Credential"
}
},
"typeVersion": 2.2
},
{
"id": "a09a6310-d570-4e65-81aa-cc7ae72996d6",
"name": "Code in JavaScript",
"type": "n8n-nodes-base.code",
"position": [
240,
0
],
"parameters": {
"jsCode": "// Robust Gumroad email parser for n8n Code node\n// Normalise whitespace so fields that are on same line still parse correctly.\nconst raw = ($json.snippet || \"\");\nconst text = raw.replace(/\\s+/g, \" \").trim() + \" \"; // collapse whitespace and add trailing space\n\nfunction find(pattern, fallback = \"\") {\n const m = text.match(pattern);\n return m ? m[1].trim() : fallback;\n}\n\n// Product: words after $price until a dash, \"View\", \"Email\", \"Quantity\", or known keyword\nlet product = find(/\\$\\d+\\s+([A-Za-z0-9][A-Za-z0-9\\s\\-\\+&]*?)(?=\\s+(?:-|View|Email|Quantity|Product|Referrer|Name|UTM|$))/i);\nif (product) product = product.replace(/\\s+(?:Order|Product price)$/i, \"\").trim();\n\n// Name: accept Customer X Email, Name X next-keyword, Buyer X, or Name at end.\n// Works for multi-word names and when name is last field.\nlet name = \"\";\nconst namePatterns = [\n /Customer\\s+(.+?)(?=\\s+(?:Email|Quantity|UTM|Referrer|Product|Name|$))/i,\n /Name\\s+(.+?)(?=\\s+(?:Product|Email|Quantity|Referrer|UTM|$))/i,\n /Buyer\\s+(.+?)(?=\\s+(?:Email|Quantity|Referrer|Product|UTM|$))/i,\n];\nfor (const p of namePatterns) {\n const m = text.match(p);\n if (m && m[1]) { name = m[1].trim(); break; }\n}\n\n// Email, Quantity, Referrer (stop at next keyword)\nconst email = find(/Email\\s+([^\\s]+)/i);\nconst quantity = find(/Quantity\\s+(\\d+)/i);\nlet referrer = find(/Referrer\\s+(.+?)(?=\\s+(?:Name|Email|Quantity|Product|UTM|$))/i);\n\n// purchaseDate from Gmail internalDate if present\nlet purchaseDate = \"\";\nif ($json.internalDate) {\n purchaseDate = new Date(Number($json.internalDate)).toISOString();\n}\n\n// unique key: fallbacks to avoid undefined\nconst uniqueKey = `${email || \"no-email\"}-${product || \"no-product\"}-${purchaseDate || \"no-date\"}`;\n\nreturn [\n {\n json: {\n product: product || \"\",\n name: name || \"\",\n email: email || \"\",\n quantity: quantity || \"\",\n referrer: referrer || \"\",\n purchaseDate,\n uniqueKey\n }\n }\n];\n"
},
"typeVersion": 2
},
{
"id": "cf3b7bec-90ec-4861-956c-cf981792bad7",
"name": "AI Agent",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
1280,
-16
],
"parameters": {
"text": "=You are an email writing assistant. Write a short, warm, professional, and emotionally positive email to a customer who has just purchased one of my digital products on Gumroad.\n\nUse the following customer details:\n- Name: {{ $json.name }}\n- Product Purchased: {{ $json.property_product }}\n\nWrite the email as if it is coming directly from me (Paul). The tone should be:\n- friendly but professional\n- genuinely appreciative\n- concise (5β7 sentences max)\n- emotionally positive and reassuring\n- no unnecessary marketing fluff\n\nInclude:\n- a warm thank-you for their purchase from Gumroad \n- a sentence appreciating their trust \n- a brief one-line description of what the product helps with \n- reassurance that they can reach me anytime for help \n- a positive closing note wishing them success with the product \n\nDo NOT include subject lines unless I ask separately.\nReturn only the email body in clean paragraph form.",
"options": {},
"promptType": "define"
},
"typeVersion": 3
},
{
"id": "cc162afe-bcb7-472e-8bf1-f6927e3740e7",
"name": "Google Gemini Chat Model",
"type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
"position": [
1280,
256
],
"parameters": {
"options": {}
},
"credentials": {
"googlePalmApi": {
"id": "credential-id",
"name": "googlePalmApi Credential"
}
},
"typeVersion": 1
},
{
"id": "8e9de348-c81b-4719-a4c7-f357638f5599",
"name": "Send a message",
"type": "n8n-nodes-base.gmail",
"position": [
1648,
-16
],
"webhookId": "093a6f85-cd54-496a-a355-cdb71b92d908",
"parameters": {
"sendTo": "={{ $('Code in JavaScript').item.json.email }}",
"message": "={{ $json.output }}",
"options": {
"appendAttribution": false
},
"subject": "Thank you for supporting my work β€οΈ",
"emailType": "text"
},
"credentials": {
"gmailOAuth2": {
"id": "credential-id",
"name": "gmailOAuth2 Credential"
}
},
"typeVersion": 2.1
},
{
"id": "b6afd0bb-e744-49e1-abbb-06018be0d6e1",
"name": "If",
"type": "n8n-nodes-base.if",
"position": [
688,
0
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "41dd1ae9-c8bb-4e72-9148-3702cb72297f",
"operator": {
"type": "number",
"operation": "equals"
},
"leftValue": "={{ Object.keys($json).length }}",
"rightValue": 0
}
]
}
},
"typeVersion": 2.2
},
{
"id": "e49a189b-319f-4d44-afc4-1a4e346ca01a",
"name": "Stop and Error",
"type": "n8n-nodes-base.stopAndError",
"notes": "Error when duplictes is detected.",
"position": [
880,
240
],
"parameters": {
"errorMessage": "The Data already exsists"
},
"notesInFlow": true,
"typeVersion": 1
},
{
"id": "cbfb4691-8738-4fc7-b1c4-6d8359fdb6ce",
"name": "Get many database pages",
"type": "n8n-nodes-base.notion",
"position": [
464,
0
],
"parameters": {
"simple": false,
"filters": {
"conditions": [
{
"key": "UniqueKey|rich_text",
"condition": "equals",
"richTextValue": "={{ $json.uniqueKey }}"
}
]
},
"options": {},
"resource": "databasePage",
"operation": "getAll",
"databaseId": {
"__rl": true,
"mode": "list",
"value": "2c411b7d-dc06-80fc-87e9-db7d5c714c1e",
"cachedResultUrl": "https://www.notion.so/2c411b7ddc0680fc87e9db7d5c714c1e",
"cachedResultName": "Gumroad Leads"
},
"filterType": "manual"
},
"credentials": {
"notionApi": {
"id": "credential-id",
"name": "notionApi Credential"
}
},
"notesInFlow": false,
"typeVersion": 2.2,
"alwaysOutputData": true
},
{
"id": "f07a92a1-f032-490d-be55-19b6fadb4bdd",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
-64,
-336
],
"parameters": {
"color": 7,
"width": 432,
"height": 512,
"content": "## Request Authentication\nListens for Gumroad purchase emails and extracts buyer and product information.\n\n### Action Required\nAuthenticate Gmail\nEnsure Gumroad purchase emails are received in this inbox"
},
"typeVersion": 1
},
{
"id": "59bc2cc5-a46e-481c-9130-08624ef95410",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
400,
-336
],
"parameters": {
"color": 7,
"width": 432,
"height": 512,
"content": "## Customer Lookup\n\nChecks the Notion database for existing customers and stops execution if a duplicate is found.\n\n## Action Required\n- Connect your Notion account\n- Select the correct customer database\n"
},
"typeVersion": 1
},
{
"id": "9d46503d-783a-4359-ad67-130673589713",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
1248,
-336
],
"parameters": {
"color": 7,
"width": 544,
"height": 512,
"content": "## AI Reply & Delivery\nGenerates a personalized thank-you email using AI and sends it to the buyer automatically.\n\n### Outcome\n- Instant post-purchase engagement\n- Professional buyer experience\n- Fully automated workflow completion"
},
"typeVersion": 1
},
{
"id": "1639dd58-ddcd-4734-b0da-86a92104b461",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
880,
-336
],
"parameters": {
"color": 7,
"width": 288,
"height": 512,
"content": "## Create Customer Record\n\nCreates a new customer record in Notion for first-time buyers.\n\n### What it stores:\n- Buyer details\n- Product purchased\n- Purchase value\n- Timestamp"
},
"typeVersion": 1
},
{
"id": "b1493b9a-309f-4859-94cb-48c50b970f42",
"name": "Sticky Note7",
"type": "n8n-nodes-base.stickyNote",
"position": [
-912,
-240
],
"parameters": {
"width": 576,
"height": 320,
"content": "# Mirai MailFlow\nThis workflow automates post-purchase communication for Gumroad creators.\n\nWhen a Gumroad purchase email arrives in Gmail, the workflow extracts buyer and product details, checks for duplicate customers, stores the purchase in Notion, and sends a personalized thank-you email using AI.\n\nSetup requires connecting Gmail, Notion, and an AI model.\nWorks on cloud and self-hosted n8n. Setup takes ~5β10 minutes."
},
"typeVersion": 1
},
{
"parameters": {
"operation": "verify",
"email": "={{ $('Code in JavaScript').item.json.email }}",
"additionalOptions": {}
},
"type": "n8n-nodes-billionverify.billionVerify",
"typeVersion": 1,
"position": [
1288,
-16
],
"name": "Verify Email (BillionVerify)",
"credentials": {
"billionVerifyApi": {
"id": "",
"name": "BillionVerify account"
}
}
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "loose"
},
"combinator": "and",
"conditions": [
{
"id": "is-deliverable",
"leftValue": "={{ $json.is_deliverable }}",
"rightValue": "",
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
}
}
]
}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2,
"position": [
1468,
-16
],
"name": "IF deliverable"
}
],
"connections": {
"If": {
"main": [
[
{
"node": "Create a database page",
"type": "main",
"index": 0
}
],
[
{
"node": "Stop and Error",
"type": "main",
"index": 0
}
]
]
},
"AI Agent": {
"main": [
[
{
"node": "Verify Email (BillionVerify)",
"type": "main",
"index": 0
}
]
]
},
"Gmail Trigger": {
"main": [
[
{
"node": "Code in JavaScript",
"type": "main",
"index": 0
}
]
]
},
"Send a message": {
"main": [
[]
]
},
"Code in JavaScript": {
"main": [
[
{
"node": "Get many database pages",
"type": "main",
"index": 0
}
]
]
},
"Create a database page": {
"main": [
[
{
"node": "AI Agent",
"type": "main",
"index": 0
}
]
]
},
"Get many database pages": {
"main": [
[
{
"node": "If",
"type": "main",
"index": 0
}
]
]
},
"Google Gemini Chat Model": {
"ai_languageModel": [
[
{
"node": "AI Agent",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Verify Email (BillionVerify)": {
"main": [
[
{
"node": "IF deliverable",
"type": "main",
"index": 0
}
]
]
},
"IF deliverable": {
"main": [
[
{
"node": "Send a message",
"type": "main",
"index": 0
}
],
[]
]
}
},
"settings": {
"executionOrder": "v1"
}
}When to use this
- Cleaning a list before a Gumroad send or sync.
- Protecting Gumroad deliverability and sender reputation.
- Keeping bounce rates low so your sending is never throttled.
FAQ
Why verify before sending in Gumroad?
Verifying first keeps your bounce rate low, which protects your sender reputation and your results.
How do I import this workflow?
Download the JSON, then in n8n go to Workflows β Import from File (or paste it). Install the BillionVerify community node and add your API key credential.
What happens to risky or catch-all addresses?
They are routed to the false branch and excluded from the send. You decide whether to retry, review, or drop them.
Add verification to your workflow
Create a free account, grab your API key, and stop bounces before they happen.
Get started free