• Home
BuildWithMatija
Get In Touch
  1. Home
  2. Blog
  3. Tools
  4. Proven n8n Cold Email Automation: 7-Step Workflow Guide

Proven n8n Cold Email Automation: 7-Step Workflow Guide

Build a daily automated cold-email workflow with n8n, Google Sheets & Gmail — randomized delays, 20/day limit, and…

9th March 2026·Updated on:24th February 2026·MŽMatija Žiberna·
Tools
Proven n8n Cold Email Automation: 7-Step Workflow Guide

📚 Get Practical Development Guides

Join developers getting comprehensive guides, code examples, optimization tips, and time-saving prompts to accelerate their development workflow.

No spam. Unsubscribe anytime.

How I Automated Cold Email Outreach with n8n and Google Sheets

I had a CSV with emails, subjects, and copy. I needed to send them out daily — 20 at a time — without babysitting the process. My first instinct was to write a for loop. Then n8n showed me I was thinking about it all wrong.

This guide walks you through building a fully automated cold email workflow using n8n, Google Sheets, and Gmail. By the end, you will have a workflow that runs every morning, picks up the next 20 unsent rows from your sheet, sends each email with a human-like random delay, and marks them as sent — all without writing a single loop.


The Sheet Setup

Before touching n8n, get your Google Sheet ready. You need five columns:

Email, Subject, Copy, sentAt, row_number

The sentAt column is what controls everything. When it is empty, the row is queued. When the workflow sends the email, it sets sentAt to 1. That is your entire state management — dead simple and it works.

The row_number column is added automatically by n8n when it reads the sheet. You will use it later to update the correct row after sending.

Fill in your Email, Subject, and Copy rows. Leave sentAt blank for everything you want sent.


Building the Workflow

Step 1: Schedule Trigger

Add a Schedule Trigger node and set it to run daily at 7am. Make sure the timezone in the node matches your local timezone — n8n defaults to UTC and your 7am will fire at the wrong time if you miss this.

Step 2: Google Sheets — Read Rows

Add a Google Sheets node connected to your spreadsheet. Set the operation to "Get Row(s)" and point it at your sheet. Connect your Google account via OAuth when prompted.

This node returns every row in your sheet as individual items. And here is the thing that changes how you think about n8n entirely.

n8n does not return an array you need to loop over. Every row becomes its own item, and every node downstream runs once per item automatically.

There is no for loop. There is no .map(). There is no iteration logic to write. You build the workflow for a single item and n8n handles the rest. If 200 rows come through, every node fires 200 times. This is the core mental shift.

Step 3: Filter — Skip Already Sent

Add a Filter node and set the condition: sentAt is not equal to 1.

This filters out anything already sent and passes only fresh rows downstream. Combined with n8n's per-item execution, only unsent emails continue through the workflow.

Step 4: Limit — Cap at 20 Per Day

Add a Limit node and set it to 20. Even though your sheet might have hundreds of rows, only the first 20 that pass the filter will continue. This keeps your daily send volume controlled and your domain reputation healthy.

If you have an older Google Workspace account with a solid sending history, 20 is conservative. You can push higher, but start here.

Step 5: Wait — Random Delay Between Sends

This is the detail that makes your outreach look human rather than mechanical. Add a Wait node and in the amount field, open the expression editor and enter:

{{ Math.floor(Math.random() * 61) + 30 }}

This generates a random number between 30 and 90 each time the node runs — meaning each email goes out with a different delay. Since n8n runs this node once per item, every single email in your batch gets its own randomized wait. No two emails leave at the same interval.

Step 6: Gmail — Send the Email

Add a Gmail node, connect your Google account, and map the fields from your sheet:

  • To: {{ $json.Email }}
  • Subject: {{ $json.Subject }}
  • Message: {{ $json.Copy }}

Set the email type to plain text. Plain text emails land better in inboxes and read like a real person sent them — which is exactly what you want for cold outreach.

One more thing: scroll down to Additional Fields, click Add Field, find Append n8n Attribution and toggle it off. By default n8n adds a "This email was sent automatically with n8n" footer to every email. Turning this off removes it entirely. No environment variables, no Docker config — just a toggle in the node.

Step 7: Google Sheets — Update the Row

Add a second Google Sheets node with the operation set to "Update Row". This marks each email as sent after it goes out.

Map the fields like this:

  • row_number: {{ $('Filter').item.json.row_number }}
  • sentAt: 1

The row_number reference pulls from the Filter node specifically because that is where the original row data lives before the Wait and Gmail nodes ran. Setting sentAt to 1 flags the row so the Filter node skips it on every future run.


The Complete Flow

Schedule Trigger (7am daily)
  → Google Sheets (read all rows)
  → Filter (sentAt != 1)
  → Limit (20)
  → Wait (random 30–90 seconds)
  → Gmail (send email)
  → Google Sheets (set sentAt = 1)

Activate the workflow. Fill the sheet with leads. Every morning at 7am, the next 20 unsent rows go out with randomized delays and get marked done. When the sheet is empty, nothing sends. When you add more rows, the cycle continues.


What You Built

You started with a CSV and ended up with a self-managing outreach machine. The key insight is that n8n's item-based execution model eliminates the need for loops entirely — you design for one item and the engine scales it across all of them. The random delay makes the sends look human. The sentAt flag gives you full control over what goes out and what does not. Plain text keeps deliverability high.

Fill the sheet, activate the workflow, and let it run.

Let me know in the comments if you have questions, and subscribe for more practical development guides.

Thanks, Matija

📄View markdown version
0

Frequently Asked Questions

Comments

Leave a Comment

Your email will not be published

Stay updated! Get our weekly digest with the latest learnings on NextJS, React, AI, and web development tips delivered straight to your inbox.

10-2000 characters

• Comments are automatically approved and will appear immediately

• Your name and email will be saved for future comments

• Be respectful and constructive in your feedback

• No spam, self-promotion, or off-topic content

Matija Žiberna
Matija Žiberna
Full-stack developer, co-founder

I'm Matija Žiberna, a self-taught full-stack developer and co-founder passionate about building products, writing clean code, and figuring out how to turn ideas into businesses. I write about web development with Next.js, lessons from entrepreneurship, and the journey of learning by doing. My goal is to provide value through code—whether it's through tools, content, or real-world software.

Table of Contents

  • How I Automated Cold Email Outreach with n8n and Google Sheets
  • The Sheet Setup
  • Building the Workflow
  • Step 1: Schedule Trigger
  • Step 2: Google Sheets — Read Rows
  • Step 3: Filter — Skip Already Sent
  • Step 4: Limit — Cap at 20 Per Day
  • Step 5: Wait — Random Delay Between Sends
  • Step 6: Gmail — Send the Email
  • Step 7: Google Sheets — Update the Row
  • The Complete Flow
  • What You Built
On this page:
  • How I Automated Cold Email Outreach with n8n and Google Sheets
  • The Sheet Setup
  • Building the Workflow
  • The Complete Flow
  • What You Built
Build With Matija Logo

Build with Matija

Matija Žiberna

I turn scattered business knowledge into one usable system. End-to-end system architecture, AI integration, and development.

Quick Links

Payload CMS Websites
  • Bespoke AI Applications
  • Projects
  • How I Work
  • Blog
  • Payload CMS

    • Migration
    • Pricing

    Get in Touch

    Have a project in mind? Let's discuss how we can help your business grow.

    Contact me →
    © 2026BuildWithMatija•Principal-led system architecture•All rights reserved