OpenAI + Gmail, personalized cold emails on autopilot
Cold outreach falls apart in the boring places. Prospect lists get messy, “personalized” emails start sounding copy-pasted, and one busy day turns into a week of backlog.
Growth marketers usually feel it first, but it hits agency owners running multiple offers and consultants doing outbound too. This OpenAI Gmail automation takes you from “I should email these leads” to consistent, quota-safe sending without living in spreadsheets.
You’ll see how this workflow finds leads, pulls context from their websites, writes tight emails under 200 words, then rotates across five Gmail accounts so deliverability doesn’t tank.
How This Automation Works
The full n8n workflow, from trigger to final output:
n8n Workflow Template: OpenAI + Gmail, personalized cold emails on autopilot
flowchart LR
subgraph sg0["MANUAL TRIGGER: Start Workflow Flow"]
direction LR
n0["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/code.svg' width='40' height='40' /></div><br/>Extract URLs from Google Sea.."]
n1@{ icon: "mdi:cog", form: "rounded", label: "Remove Duplicate URLs", pos: "b", h: 48 }
n2@{ icon: "mdi:cog", form: "rounded", label: "Remove Duplicate Emails", pos: "b", h: 48 }
n3@{ icon: "mdi:swap-vertical", form: "rounded", label: "Split Emails into Items", pos: "b", h: 48 }
n4@{ icon: "mdi:cog", form: "rounded", label: "Aggregate Email Lists", pos: "b", h: 48 }
n5["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/httprequest.dark.svg' width='40' height='40' /></div><br/>Search Google Maps"]
n6@{ icon: "mdi:swap-horizontal", form: "rounded", label: "Filter Out Google/Schema URLs", pos: "b", h: 48 }
n7@{ icon: "mdi:swap-vertical", form: "rounded", label: "Loop Through Unique URLs", pos: "b", h: 48 }
n8["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/httprequest.dark.svg' width='40' height='40' /></div><br/>Fetch Website Content (via U.."]
n9@{ icon: "mdi:swap-vertical", form: "rounded", label: "Loop Through Website Content..", pos: "b", h: 48 }
n10["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/code.svg' width='40' height='40' /></div><br/>Extract and Filter Emails"]
n11@{ icon: "mdi:swap-vertical", form: "rounded", label: "Loop Through Search Queries", pos: "b", h: 48 }
n12@{ icon: "mdi:cog", form: "rounded", label: "Wait Before Google Search", pos: "b", h: 48 }
n13["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/code.svg' width='40' height='40' /></div><br/>Process AI-Generated Queries"]
n14@{ icon: "mdi:robot", form: "rounded", label: "Generate Google Maps Queries..", pos: "b", h: 48 }
n15["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/code.svg' width='40' height='40' /></div><br/>Extract Domain from Email"]
n16@{ icon: "mdi:swap-vertical", form: "rounded", label: "Loop Through Unique Emails", pos: "b", h: 48 }
n17["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/httprequest.dark.svg' width='40' height='40' /></div><br/>Scrape Website Content (Jina.."]
n18@{ icon: "mdi:swap-horizontal", form: "rounded", label: "Check for Scraping Error", pos: "b", h: 48 }
n19["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/code.svg' width='40' height='40' /></div><br/>Truncate Website Content"]
n20@{ icon: "mdi:swap-horizontal", form: "rounded", label: "Check if URL Exists", pos: "b", h: 48 }
n21@{ icon: "mdi:cog", form: "rounded", label: "Wait Between Emails", pos: "b", h: 48 }
n22["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/code.svg' width='40' height='40' /></div><br/>Generate Random Delay"]
n23@{ icon: "mdi:robot", form: "rounded", label: "Generate Personalized Email ..", pos: "b", h: 48 }
n24@{ icon: "mdi:robot", form: "rounded", label: "Parse AI Email Output (JSON)", pos: "b", h: 48 }
n25@{ icon: "mdi:cog", form: "rounded", label: "NoOp (If URL Invalid)", pos: "b", h: 48 }
n26@{ icon: "mdi:play-circle", form: "rounded", label: "MANUAL TRIGGER: Start Workflow", pos: "b", h: 48 }
n27@{ icon: "mdi:brain", form: "rounded", label: "Configure OpenAI Chat Model ..", pos: "b", h: 48 }
n28@{ icon: "mdi:code-braces", form: "rounded", label: "Set Random Index", pos: "b", h: 48 }
n29@{ icon: "mdi:swap-horizontal", form: "rounded", label: "Switch SMTP", pos: "b", h: 48 }
n30@{ icon: "mdi:message-outline", form: "rounded", label: "Gmail 1", pos: "b", h: 48 }
n31@{ icon: "mdi:message-outline", form: "rounded", label: "Gmail 3", pos: "b", h: 48 }
n32@{ icon: "mdi:message-outline", form: "rounded", label: "Gmail 4", pos: "b", h: 48 }
n33@{ icon: "mdi:message-outline", form: "rounded", label: "Gmail 5", pos: "b", h: 48 }
n34@{ icon: "mdi:message-outline", form: "rounded", label: "Gmail ", pos: "b", h: 48 }
n35@{ icon: "mdi:swap-vertical", form: "rounded", label: "Loop Over Items", pos: "b", h: 48 }
n34 --> n22
n30 --> n22
n31 --> n22
n32 --> n22
n33 --> n22
n29 --> n30
n29 --> n34
n29 --> n31
n29 --> n32
n29 --> n33
n35 --> n14
n28 --> n29
n5 --> n0
n20 --> n1
n20 --> n25
n21 --> n16
n4 --> n3
n22 --> n21
n1 --> n7
n2 --> n16
n3 --> n2
n18 --> n16
n18 --> n19
n7 --> n9
n7 --> n8
n19 --> n23
n15 --> n17
n10 --> n9
n12 --> n5
n16 --> n11
n16 --> n15
n11 --> n35
n11 --> n12
n24 -.-> n23
n13 --> n11
n6 --> n20
n26 --> n35
n0 --> n6
n8 --> n7
n17 --> n18
n9 --> n4
n9 --> n10
n14 --> n13
n23 --> n28
n27 -.-> n23
end
%% Styling
classDef trigger fill:#e8f5e9,stroke:#388e3c,stroke-width:2px
classDef ai fill:#e3f2fd,stroke:#1976d2,stroke-width:2px
classDef aiModel fill:#e8eaf6,stroke:#3f51b5,stroke-width:2px
classDef decision fill:#fff8e1,stroke:#f9a825,stroke-width:2px
classDef database fill:#fce4ec,stroke:#c2185b,stroke-width:2px
classDef api fill:#fff3e0,stroke:#e65100,stroke-width:2px
classDef code fill:#f3e5f5,stroke:#7b1fa2,stroke-width:2px
classDef disabled stroke-dasharray: 5 5,opacity: 0.5
class n26 trigger
class n14,n23,n24 ai
class n27 aiModel
class n6,n18,n20,n29 decision
class n5,n8,n17 api
class n0,n10,n13,n15,n19,n22,n28 code
classDef customIcon fill:none,stroke:none
class n0,n5,n8,n10,n13,n15,n17,n19,n22 customIcon
The Problem: Cold email personalization doesn’t scale
If you’ve ever tried to “scale” cold email the manual way, you know the trap. You start with good intentions: research the prospect, write something specific, send at a safe pace. Then volume creeps in. You stop checking the website. The first lines get generic. And when you finally push send, Gmail quotas or deliverability limits smack you right back down. Now you’re juggling multiple sender accounts, tracking who got what, and praying you don’t double-send to the same domain. Honestly, the mental overhead is worse than the typing.
The friction compounds. Here’s where it usually breaks.
- Lead lists come from five places, so duplicates and bad emails slip in constantly.
- Personalization takes “just a few minutes” per prospect until you multiply it by 100.
- Sending from one Gmail account triggers quota problems, or you get cautious and barely send anything.
- Multi-offer campaigns become a spreadsheet circus because each offer needs different language and different links.
The Solution: AI-written outreach + safe Gmail rotation
This workflow runs a complete outbound loop inside n8n. You define your offers once (name, description, URL), then the workflow generates targeted Google Maps-style searches for each offer, pulls back results, and extracts real websites to research. It scrapes site content, filters out junk URLs, deduplicates domains and email addresses, then uses OpenAI (GPT-4o, GPT-3, or o3-mini) to write a concise HTML cold email customized to what that business actually does. Finally, it sends through Gmail while rotating between five sender accounts and adding randomized delays so volume stays steady and quotas are less likely to surprise you.
It starts with a manual launch, then moves through three big phases: build search queries, collect and clean lead data, and generate + send emails with throttling. The end result is a sent email (from a chosen Gmail account) that includes the right offer link for that prospect, without you hand-writing the first draft.
What You Get: Automation vs. Results
| What This Workflow Automates | Results You’ll Get |
|---|---|
|
|
Example: What This Looks Like
Say you want to reach out to 100 local businesses for one offer. Manually, you might spend 5 minutes finding each site and another 5 minutes writing a decent first email, which is roughly 15 hours before you even think about sending safely. With this workflow, you launch once, let it scrape and draft in the background, then spend maybe 30–45 minutes skimming the generated emails and running the send. You get the same 100 prospects contacted without turning your whole week into tab-hopping.
What You’ll Need
- n8n instance (try n8n Cloud free)
- Self-hosting option if you prefer (Hostinger works well)
- OpenAI for drafting and query generation.
- Gmail to send emails from multiple accounts.
- Airtable or Google Sheets to store leads and campaign inputs.
- OpenAI API key (get it from your OpenAI dashboard).
Skill level: Intermediate. You’ll connect accounts, paste in your offers, and lightly adjust prompts and limits.
Don’t want to set this up yourself? Talk to an automation expert (free 15-minute consultation).
How It Works
A manual launch starts the run. You kick it off when you’re ready to generate leads and send, which is useful if you want to control timing and volume.
Your offers get turned into search intent. OpenAI creates batches of targeted searches (up to 100 per offer), then the workflow runs HTTP requests, filters out Google schema-style links, and keeps only real business websites worth checking.
Prospects are cleaned before you touch them. It scrapes site content (including via Jina scraping), extracts email addresses, deduplicates URLs and emails, and skips items with missing or invalid URLs so you’re not blasting junk.
Emails are drafted, then sent with protection. OpenAI generates a short personalized HTML email, the workflow parses it into structured fields, then a Switch node assigns one of five Gmail senders and applies a variable delay to smooth out sending patterns.
You can easily modify the offer selection and sending pace to match your needs. See the full implementation guide below for customization options.
Step-by-Step Implementation Guide
Step 1: Configure the Manual Trigger
Start the workflow manually to process a batch of outreach targets through search, scraping, and email delivery.
- Add the Manual Launch Trigger node as the starting trigger.
- Connect Manual Launch Trigger to Iterate Input Items to begin batch processing.
- Confirm Iterate Input Items outputs to Create Maps Queries (AI) for AI-driven query creation.
Step 2: Connect Map Search and Link Extraction
This stage creates search queries, pauses between requests, and parses the resulting map data into usable site links.
- In Create Maps Queries (AI), add your prompt and expected output structure for search query generation.
- Credential Required: Connect your OpenAI credentials in Create Maps Queries (AI).
- Ensure Process AI Queries feeds Iterate Search Queries, which then triggers Pause Before Map Search.
- Connect Pause Before Map Search to Query Maps Search and then to Parse Links from Search Results.
- Route parsed links through Exclude Google Schema Links and then Validate URL Presence before Deduplicate Web Links.
- Confirm Validate URL Presence sends invalid items to Skip Invalid URL for safe dropping.
Step 3: Scrape Sites and Build Email Lists
This stage iterates URLs, scrapes content, extracts emails, and deduplicates the email list.
- Confirm Deduplicate Web Links passes unique URLs into Iterate Unique URLs and Retrieve Site Content.
- Ensure Retrieve Site Content loops back to Iterate Unique URLs for batch processing.
- Connect Iterate Unique URLs to Cycle Content Batches and then to Extract & Filter Emails.
- Aggregate results with Combine Email Lists and split items using Separate Email Items.
- Run Deduplicate Email Addresses before Iterate Unique Emails to prevent duplicate outreach.
- After Iterate Unique Emails, derive domains via Derive Domain from Email and scrape content with Scrape Site Content (Jina).
- Use Detect Scrape Errors to route successful scrapes to Shorten Site Content and failed items back into Iterate Unique Emails.
Step 4: Set Up AI Email Composition
Generate personalized outreach emails using AI and structured parsing.
- Connect Shorten Site Content to Compose Personalized Email to generate outreach content from the scraped data.
- Credential Required: Connect your OpenAI credentials in Configure AI Chat Model and ensure it is linked as the language model to Compose Personalized Email.
- Ensure Parse AI Email JSON is connected as the output parser for Compose Personalized Email.
- For AI sub-nodes like Parse AI Email JSON, add credentials to the parent node Compose Personalized Email via Configure AI Chat Model, not the parser itself.
Step 5: Configure Email Routing and Sending
Randomly assign a sender and distribute emails across multiple Gmail accounts with controlled delays.
- Route Compose Personalized Email to Assign Random Index, then into Route SMTP Choice.
- Route SMTP Choice sends to all five Gmail nodes; confirm each branch connects to a distinct sender: Gmail Sender One, Gmail Sender Two, Gmail Sender Three, Gmail Sender Four, and Gmail Sender Five.
- Credential Required: Connect your Gmail OAuth2 credentials to all Gmail nodes (5 nodes handle sending).
- Verify each Gmail sender connects to Generate Variable Delay and then to Delay Between Emails before looping to Iterate Unique Emails.
Step 6: Test and Activate Your Workflow
Run a manual test to validate the end-to-end flow from query generation through email delivery.
- Click Execute Workflow from the editor to run Manual Launch Trigger.
- Confirm output data flows from Create Maps Queries (AI) to Query Maps Search, through scraping, then to Compose Personalized Email.
- Verify that at least one Gmail node sends an email and that Generate Variable Delay and Delay Between Emails insert pauses.
- When results look correct, toggle the workflow to Active for production use.
Common Gotchas
- Gmail credentials can expire or need specific permissions. If things break, check the n8n Credentials panel and your Google account security alerts first.
- If you’re using Wait nodes or external scraping, processing times vary. Bump up the wait duration if downstream nodes fail on empty responses.
- Default prompts in AI nodes are generic. Add your brand voice early or you’ll be editing outputs forever.
Frequently Asked Questions
About an hour if your OpenAI key and Gmail accounts are ready.
No. You’ll mostly connect accounts, paste in offer details, and tweak a couple of prompts.
Yes. n8n has a free self-hosted option and a free trial on n8n Cloud. Cloud plans start at $20/month for higher volume. You’ll also need to factor in OpenAI API costs (usually a few cents per batch, depending on how much text you scrape and summarize).
Two options: n8n Cloud (managed, easiest setup) or self-hosting on a VPS. For self-hosting, Hostinger VPS is affordable and handles n8n well. Self-hosting gives you unlimited executions but requires basic server management.
Yes, and that’s what it’s built for. Add or edit your products/services in the pinned offer data (the workflow uses that list to generate searches, select the right offer, and embed the correct URL). Common tweaks include changing the email tone, limiting queries per offer, and routing different offers to different sender accounts.
Usually it’s expired Google OAuth access or the wrong Gmail account connected to the wrong sender node. Reconnect the Gmail credential in n8n, then confirm each “Gmail Sender One/Two/Three…” node points to the intended mailbox. If it fails only on higher volume, you may also be hitting daily send limits, so lower the run size or increase the delays between emails.
A lot, but your real limits are Gmail quotas, your delays, and your n8n plan. On n8n Cloud Starter you’re capped by monthly executions, while self-hosting removes that cap and shifts the bottleneck to your server. Practically, most teams start with a few hundred emails per day spread across the five accounts, watch deliverability, then ramp slowly. If you’re scraping heavy pages, also expect runs to take longer because content retrieval and summarizing is the slow part.
Often, yes, because this flow needs branching, deduping, scraping, and variable delays, which get awkward (and expensive) in simpler tools. n8n also lets you self-host, which is a big deal when you’re doing lots of executions. The tradeoff is a little more setup responsibility on your side. If you want, you can run it in n8n Cloud and keep maintenance close to zero. Talk to an automation expert if you’re deciding between platforms.
Once this is running, outreach stops being a “big push” and becomes a steady background system. Set it up, sanity-check the outputs, and use the extra hours for work that actually moves revenue.
Need Help Setting This Up?
Our automation experts can build and customize this workflow for your specific needs. Free 15-minute consultation—no commitment required.