Google Sheets to Gmail, follow-ups sent and tracked
Your follow-ups are probably “organized” in a Google Sheet… until the day gets busy. Then the sending slips, the status column gets stale, and you can’t remember who got what.
This Sheets Gmail followups automation hits sales reps first, honestly. But recruiters and small-team founders feel the same drag when outreach has to be consistent to work. The outcome is simple: emails go out on schedule and the sheet updates itself with sent status, timestamps, and message IDs.
Below you’ll see how the workflow runs, what it changes day-to-day, and what you need to launch it without turning your week into a “CRM cleanup project.”
How This Automation Works
The full n8n workflow, from trigger to final output:
n8n Workflow Template: Google Sheets to Gmail, follow-ups sent and tracked
flowchart LR
subgraph sg0["Scheduled Run Flow"]
direction LR
n0@{ icon: "mdi:swap-vertical", form: "rounded", label: "Batch Item Iterator", pos: "b", h: 48 }
n1@{ icon: "mdi:cog", form: "rounded", label: "Cap Records", pos: "b", h: 48 }
n2@{ icon: "mdi:swap-horizontal", form: "rounded", label: "Conditional Check", pos: "b", h: 48 }
n3@{ icon: "mdi:database", form: "rounded", label: "Refresh Sheet Rows", pos: "b", h: 48 }
n4@{ icon: "mdi:message-outline", form: "rounded", label: "Dispatch Gmail Notice", pos: "b", h: 48 }
n5@{ icon: "mdi:database", form: "rounded", label: "Retrieve Pending Emails", pos: "b", h: 48 }
n6@{ icon: "mdi:play-circle", form: "rounded", label: "Scheduled Run Trigger", pos: "b", h: 48 }
n7@{ icon: "mdi:cog", form: "rounded", label: "Delay Cycle", pos: "b", h: 48 }
n2 --> n4
n7 --> n0
n1 --> n0
n6 --> n5
n5 --> n1
n4 --> n3
n3 --> n7
n0 --> n2
end
subgraph sg1["Flow 2"]
direction LR
n8@{ icon: "mdi:message-outline", form: "rounded", label: "Utility: SMTP Dispatch Option", pos: "b", h: 48 }
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 n6 trigger
class n2 decision
class n3,n5 database
The Problem: Follow-ups die in the spreadsheet
Cold outreach looks easy on paper: write a message, send it, follow up later. In reality, it turns into dozens of tiny tasks spread across the day. Open the sheet, copy an address, paste it into Gmail, double-check the name, find the right template, send, then go back and mark “Email Sent” so you don’t hit the same person twice. Miss one checkbox and you create confusion. Miss two days and your “sequence” stops being a sequence.
The friction compounds. Here’s where it breaks down in real life:
- You spend about 5 minutes per lead just moving data between Google Sheets and Gmail, and it’s never the “important” part of the job.
- Follow-ups get skipped because they’re not urgent, which means the list quietly stops converting.
- Manual tracking is fragile, so you can’t trust your own sheet when you’re planning the next batch.
- Without message IDs, replying, auditing, or debugging deliverability becomes guesswork.
The Solution: Scheduled, personalized emails sent from Sheets and logged
This workflow turns your Google Sheet into a lightweight outreach engine that actually stays accurate. On a schedule (the included setup runs every 6 hours, but you can change it), n8n checks your sheet for prospects who have not received the current email in the sequence. It can cap the batch size so you do not blast your whole list at once. Then it loops lead-by-lead, verifies there’s a usable email address, and sends the message through Gmail (or an SMTP fallback). After each send, it writes back to the same row with “Email Sent = Yes,” a sent timestamp, and the message ID, so your tracking stays clean without you touching it.
The workflow starts with a scheduled run. From there, Google Sheets provides the next set of pending rows, Gmail handles delivery, and the sheet becomes the logbook automatically. A short wait between messages helps it behave more like a human sender.
What You Get: Automation vs. Results
| What This Workflow Automates | Results You’ll Get |
|---|---|
|
|
Example: What This Looks Like
Say you send follow-ups to 40 leads per day from a sheet. Manually, it’s maybe 5 minutes to copy details, send in Gmail, then log status, so you burn about 3 hours daily. With this workflow, you spend about 10 minutes prepping the sheet, then n8n runs every 6 hours and does the sending plus logging while you’re working on real sales conversations. The “after” time is mostly review, not busywork.
What You’ll Need
- n8n instance (try n8n Cloud free)
- Self-hosting option if you prefer (Hostinger works well)
- Google Sheets to store leads and email copy
- Gmail to send messages and follow-ups
- Google OAuth credentials (get them from Google Cloud Console APIs & Services)
Skill level: Beginner. You’ll connect accounts, copy a Sheet template, and map a few columns.
Don’t want to set this up yourself? Talk to an automation expert (free 15-minute consultation).
How It Works
A scheduled run kicks things off. The workflow uses a timer (commonly every 6 hours) so outreach keeps moving without someone pressing “send.”
Google Sheets is scanned for pending rows. It pulls prospects where your “Email Sent” field is still marked “No,” then a limit can cap how many are processed in one run.
Each lead is handled one at a time. n8n loops through the batch, checks that an email address exists and looks valid, then sends the subject and body you’ve already prepared in the sheet using Gmail (or the SMTP dispatch option).
The sheet gets updated immediately. After sending, the workflow writes back the sent status, a timestamp, and the message ID, then waits briefly before moving to the next lead.
You can easily modify the schedule frequency to match your sending limits based on your needs. See the full implementation guide below for customization options.
Step-by-Step Implementation Guide
Step 1: Configure the Schedule Trigger
This workflow starts on a recurring schedule to fetch pending emails from your sheet.
- Add the Scheduled Run Trigger node as your trigger.
- Set the schedule rule to run every
6hours (field hours with hoursInterval set to6). - Connect Scheduled Run Trigger → Retrieve Pending Emails to match the execution flow.
Step 2: Connect Google Sheets
These nodes read pending rows and update status after sending emails.
- Open Retrieve Pending Emails and select the spreadsheet with documentId set to
[YOUR_ID]and sheetName set toSheet1(gid=0). - Set a filter in Retrieve Pending Emails to only fetch rows where Email Sent equals
No. - Credential Required: Connect your
googleSheetsOAuth2Apicredentials in Retrieve Pending Emails. - Open Refresh Sheet Rows and set operation to
appendOrUpdate. - Configure column mappings in Refresh Sheet Rows:
- Sent on →
{{ $now }} - Message Id →
{{ $json.id }} - Email Sent →
Yes - Email Address →
{{ $('Conditional Check').first().json['Email Address '] }}
- Sent on →
- Credential Required: Connect your
googleSheetsOAuth2Apicredentials in Refresh Sheet Rows.
Email Address , Email Sent ). Make sure your sheet headers match exactly to avoid lookup failures.Step 3: Set Up Batching and Conditional Logic
This stage limits records, iterates them one-by-one, and only sends when an email address exists.
- Connect Retrieve Pending Emails → Cap Records → Batch Item Iterator.
- In Batch Item Iterator, set batchSize to
=1to process one email at a time. - Connect Batch Item Iterator (second output) → Conditional Check.
- In Conditional Check, set the condition to check that
{{ $json['Email Address '] }}exists. - After updating the sheet, connect Refresh Sheet Rows → Delay Cycle → Batch Item Iterator to pace sends.
- Set Delay Cycle amount to
10(seconds).
Step 4: Configure Email Sending
Send the email via Gmail and optionally via SMTP if you want an alternative dispatch path.
- Connect Conditional Check → Dispatch Gmail Notice → Refresh Sheet Rows.
- In Dispatch Gmail Notice, set:
- sendTo to
{{ $json['Email Address '] }} - subject to
{{ $json['Email Subject'] }} - message to
{{ $json['Email Body'] }} - emailType to
text
- sendTo to
- Credential Required: Connect your
gmailOAuth2credentials in Dispatch Gmail Notice. - Optional: Configure Utility: SMTP Dispatch Option if you want SMTP sending:
- text →
{{ $json['Email body'] }} - subject →
{{ $json['Email subject'] }} - toEmail →
{{ $json['Email Address '] }} - fromEmail →
{{ $json['Sender email '] }} - emailFormat →
text
- text →
- Credential Required: Connect your
smtpcredentials in Utility: SMTP Dispatch Option if you use it.
Step 5: Test and Activate Your Workflow
Verify the end-to-end email dispatch and sheet updates before enabling it in production.
- Click Execute Workflow to run a manual test from Scheduled Run Trigger.
- Confirm that Retrieve Pending Emails returns rows with
Email Sent=No. - Check that Dispatch Gmail Notice sends an email to the value in
{{ $json['Email Address '] }}. - Verify Refresh Sheet Rows updates the row with
Email Sent=Yes,Sent ontimestamp, andMessage Id. - Turn the workflow Active so it runs automatically every 6 hours.
Common Gotchas
- Google Sheets credentials can expire or need specific permissions. If things break, check the n8n Credentials screen and confirm the Google account still has access to the spreadsheet.
- If you’re using Wait nodes or external rendering, processing times vary. Bump up the wait duration if downstream nodes fail on empty responses.
- Gmail sending can fail if you hit daily limits or your account flags automation. If emails stop sending, review the Gmail node error output and reduce your batch size in the Limit node.
Frequently Asked Questions
About 30 minutes if your Google accounts are ready.
No. You’ll mostly map Google Sheet columns to Gmail fields. If you can set up a filter in Sheets, you can handle this.
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 Google Workspace costs if you’re sending from a paid Gmail/Workspace account.
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, but you’ll want to adjust how the Google Sheets “Retrieve Pending Emails” filter works. Most teams add columns like “Stage,” “Last Sent,” and “Next Send Date,” then use the If and Switch logic to decide which subject/body to send. You can also change the Schedule Trigger so stage 2 goes out daily while stage 1 runs every 6 hours.
Usually it’s an expired OAuth connection in n8n. Reconnect your Gmail/Google credentials, then confirm the sending account matches the “Sender Email” value you’re pulling from the sheet. If it still fails, check for Gmail sending limits or a security prompt on the Google account.
It can handle a lot, but your practical limit is Gmail sending volume and whatever cap you set in the Limit node.
Often, yes, if you care about control. This workflow uses looping, conditional checks, and delays in a way that’s straightforward in n8n, and self-hosting avoids “per task” pricing that can get silly once you start sending in batches. Zapier or Make can still work if you only need a tiny setup with a couple steps and you prefer a guided UI. For multi-stage follow-ups, the ability to branch and update rows reliably matters. Talk to an automation expert if you want help choosing.
Set it up once, then let the workflow do the repetitive sending and logging. Your sheet stays accurate, and your follow-ups stop slipping through the cracks.
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.