Google Sheets to Google Calendar, follow-ups handled
You add meeting details to a spreadsheet… and then the real work starts. Copying times into Google Calendar, double-checking time zones, sending a “confirmed” message, and later realizing no one followed up.
This Sheets Calendar automation hits sales teams hardest, but client managers and solo consultants feel it too. The outcome is simple: meetings get created automatically, confirmations go out in seconds, and follow-ups happen without you chasing.
Below you’ll see exactly what the workflow does, what you need to run it, and how it turns a “messy spreadsheet process” into booked next steps.
How This Automation Works
The full n8n workflow, from trigger to final output:
n8n Workflow Template: Google Sheets to Google Calendar, follow-ups handled
flowchart LR
subgraph sg0["Followup Flow"]
direction LR
n10@{ icon: "mdi:play-circle", form: "rounded", label: "Followup Trigger", pos: "b", h: 48 }
n11@{ icon: "mdi:location-exit", form: "rounded", label: "Retrieve Past Events", pos: "b", h: 48 }
n12@{ icon: "mdi:cog", form: "rounded", label: "Flag Seen Items", pos: "b", h: 48 }
n13@{ icon: "mdi:swap-vertical", form: "rounded", label: "Iterate Past Records", pos: "b", h: 48 }
n14@{ icon: "mdi:swap-horizontal", form: "rounded", label: "Filter Followups", pos: "b", h: 48 }
n15@{ icon: "mdi:robot", form: "rounded", label: "Meeting Assistant", pos: "b", h: 48 }
n16@{ icon: "mdi:swap-vertical", form: "rounded", label: "Compose Followup Text", pos: "b", h: 48 }
n17@{ icon: "mdi:web", form: "rounded", label: "WhatsApp Followup", pos: "b", h: 48 }
n18@{ icon: "mdi:message-outline", form: "rounded", label: "Email Followup", pos: "b", h: 48 }
n19@{ icon: "mdi:cog", form: "rounded", label: "Delay Followup", pos: "b", h: 48 }
n20@{ icon: "mdi:brain", form: "rounded", label: "LLM Chat Model", pos: "b", h: 48 }
n21@{ icon: "mdi:location-exit", form: "rounded", label: "Calendar Availability", pos: "b", h: 48 }
n22@{ icon: "mdi:robot", form: "rounded", label: "Structured Output", pos: "b", h: 48 }
n19 --> n13
n20 -.-> n15
n22 -.-> n15
n21 -.-> n15
n12 --> n13
n15 --> n16
n18 --> n19
n11 --> n12
n14 --> n15
n16 --> n17
n16 --> n18
n13 --> n14
n10 --> n11
end
subgraph sg1["Timed Flow"]
direction LR
n0@{ icon: "mdi:play-circle", form: "rounded", label: "Timed Trigger", pos: "b", h: 48 }
n1@{ icon: "mdi:database", form: "rounded", label: "Fetch Sheet Rows", pos: "b", h: 48 }
n2@{ icon: "mdi:swap-vertical", form: "rounded", label: "Iterate Records", pos: "b", h: 48 }
n3@{ icon: "mdi:cog", form: "rounded", label: "Format DateTime", pos: "b", h: 48 }
n4["<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/>Transform Script"]
n5@{ icon: "mdi:location-exit", form: "rounded", label: "Add Calendar Entry", pos: "b", h: 48 }
n6@{ icon: "mdi:web", form: "rounded", label: "WhatsApp Notify", pos: "b", h: 48 }
n7@{ icon: "mdi:message-outline", form: "rounded", label: "Email Confirmation", pos: "b", h: 48 }
n8@{ icon: "mdi:database", form: "rounded", label: "Modify Sheet Status", pos: "b", h: 48 }
n9@{ icon: "mdi:cog", form: "rounded", label: "Delay Step", pos: "b", h: 48 }
n4 --> n5
n9 --> n2
n3 --> n4
n1 --> n2
n5 --> n6
n5 --> n7
n2 --> n3
n7 --> n8
n0 --> n1
n8 --> n9
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 n10,n0 trigger
class n15,n22 ai
class n20 aiModel
class n14 decision
class n1,n8 database
class n17,n6 api
class n4 code
classDef customIcon fill:none,stroke:none
class n4 customIcon
The Problem: Meeting logistics steal your selling time
Meeting scheduling looks harmless until you’re doing it all day. A new lead asks for a call, you log it in Google Sheets, then bounce to Google Calendar, then send a WhatsApp confirmation, then email the same thing “just in case.” Later, you promise yourself you’ll follow up… and it slips. Or worse, you follow up twice because you can’t remember if you already did. Multiply that by a week of calls and the admin work quietly becomes the job.
It adds up fast. The friction compounds, especially when you’re scaling outreach or managing multiple clients.
- Each meeting takes about 10 minutes of copying, formatting, and double-checking across tools.
- Status tracking breaks because your sheet and calendar drift out of sync over time.
- Confirmations get delayed, which means more no-shows and more “are we still on?” messages.
- Follow-ups depend on memory, and memory is unreliable when your day is stacked.
The Solution: Google Sheets → Google Calendar + automatic confirmations and follow-ups
This workflow runs in two branches that work independently, so you get both clean scheduling and consistent follow-up. First, it checks your Google Sheet on a schedule (often every minute), grabs any new rows that are ready, formats the date and time, then creates a Google Calendar event with the right title, description, location, color, and start/end time. Once the calendar entry exists, it immediately sends a confirmation through WhatsApp (via Rapiwa) and Gmail. Finally, it updates the original row in Google Sheets so you can see it was sent and won’t be processed again.
The second branch watches for past events that need attention. It pulls recent events from Google Calendar, marks items it has already seen (so it doesn’t spam people), filters down to “follow-up” events only, then uses an AI meeting agent to suggest a few open slots based on calendar availability. Those suggested times are sent through WhatsApp and email, then the workflow waits and continues checking on schedule.
What You Get: Automation vs. Results
| What This Workflow Automates | Results You’ll Get |
|---|---|
|
|
Example: What This Looks Like
Say you schedule 20 meetings a week from a Google Sheet. Manually, you’re doing Google Calendar creation (about 5 minutes), a WhatsApp confirmation (about 2 minutes), an email confirmation (about 3 minutes), plus status updates and fixes (another 2 minutes). That’s roughly 10 minutes per meeting, or about 3 hours a week. With this workflow, you add the row once and the system handles the rest; the “time cost” becomes a quick check-in and the occasional tweak, closer to 20 minutes total.
What You’ll Need
- n8n instance (try n8n Cloud free)
- Self-hosting option if you prefer (Hostinger works well)
- Google Sheets for the meeting intake and status tracking.
- Google Calendar to create events and check availability.
- Rapiwa (WhatsApp API) to send WhatsApp confirmations and follow-ups.
- Gmail to email confirmations and follow-up options.
- Google Gemini (PaLM) API key (get it from Google AI Studio / Gemini API in your Google Cloud project).
Skill level: Intermediate. You’ll connect a few accounts, map sheet columns to calendar fields, and adjust message templates.
Don’t want to set this up yourself? Talk to an automation expert (free 15-minute consultation).
How It Works
A scheduled check looks for new rows. n8n runs on a timer and pulls meeting entries from Google Sheets where the status indicates they are ready to send.
Date and time are cleaned up. The workflow formats your “start time” and “end time” values so Google Calendar receives consistent timestamps (this is where many manual mistakes usually happen).
The meeting gets created and confirmed. A Google Calendar event is created, then WhatsApp (Rapiwa) and Gmail send confirmation messages using your templates, so the attendee gets the details in the channels they actually read.
Past meetings trigger follow-ups. A second scheduled branch scans recent Calendar events, filters to the ones that need a follow-up, then an AI agent checks availability and drafts a message with a few suggested slots. WhatsApp and Gmail send it out.
You can easily modify the sheet columns and message templates to match your process 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 from two scheduled triggers: one for new scheduling requests and one for follow-up analysis.
- Open Timed Trigger and set the Rule to an interval based on the minutes field.
- Open Followup Trigger and set the Rule to an interval based on the minutes field.
Step 2: Connect Google Sheets
These nodes fetch new scheduling rows and update their status after confirmation.
- Open Fetch Sheet Rows and set Document to
[YOUR_ID]and Sheet togid=0(Sheet1). - In Fetch Sheet Rows, keep the Filters set on status to limit rows by status.
- Credential Required: Connect your googleSheetsOAuth2Api credentials in Fetch Sheet Rows.
- Open Modify Sheet Status and confirm Operation is
update. - Verify the mapped columns in Modify Sheet Status: set status to
checked, reminder status tosent, and row_number to{{ $('Fetch Sheet Rows').item.json.row_number }}. - Credential Required: Connect your googleSheetsOAuth2Api credentials in Modify Sheet Status.
[YOUR_ID] with the actual Google Sheet ID; leaving placeholders will return no rows.Step 3: Set Up Date Processing and Calendar Creation
This segment formats date/time from the sheet and creates calendar events.
- In Format DateTime, set Date to
{{ $json['end time'] }}, Operation toformatDate, and Custom Format toyyyy-MM-dd HH:mm:ss ZZZZ. - Review Transform Script to ensure it converts
formattedDateinto a UTC ISO string and outputsformatted. - Open Add Calendar Entry and set End to
{{ $json.formatted }}. - In Add Calendar Entry, set Use Default Reminders to
{{ false }}and add a reminder with methodemailand minutes30. - Under Additional Fields, set summary to
{{ $json.title }}, location to{{ $json.location }}, description to{{ $json.description }}, and sendUpdates toall. - Credential Required: Connect your googleCalendarOAuth2Api credentials in Add Calendar Entry.
start time and end time fields with valid date strings to avoid formatting errors.Step 4: Configure Output/Action Nodes
After the calendar event is created, the workflow sends confirmation messages in parallel.
- Verify that Add Calendar Entry outputs to both WhatsApp Notify and Email Confirmation in parallel.
- In WhatsApp Notify, set number to
[YOUR_ID]and message toHi, just create “{{ $json.summary }}” meeting scheduled for {{ $json.end.dateTime }}. Please let me know if this time still works for you. Looking forward to it!. - Credential Required: Connect your rapiwaApi credentials in WhatsApp Notify.
- In Email Confirmation, set sendTo to
[YOUR_EMAIL], message toHi, just create “{{ $json.summary }}” meeting scheduled for {{ $json.end.dateTime }}. Please let me know if this time still works for you. Looking forward to it!, and subject toMeeting scheduled for {{ $json.end.dateTime }}. - Credential Required: Connect your gmailOAuth2 credentials in Email Confirmation.
[YOUR_ID] and [YOUR_EMAIL] before testing, or notifications will fail.Step 5: Set Up Processing/AI Node for Followups
This branch analyzes past meetings and generates follow-up slot suggestions using AI and calendar availability.
- In Retrieve Past Events, set timeMin to
{{ $now.minus({ day: 4 }) }}and timeMax to{{ $now.minus({ day: 0 }) }}, with OperationgetAlland Return All enabled. - Credential Required: Connect your googleCalendarOAuth2Api credentials in Retrieve Past Events.
- In Flag Seen Items, set Operation to
removeItemsSeenInPreviousExecutionsand Dedupe Value to{{ $json.id }}. - Open Filter Followups and configure the conditions for which events should receive follow-up suggestions (the default condition is blank).
- In Meeting Assistant, set Text to
### Details of the previous call as following title: {{ $json.summary }} date: {{ $json.start.dateTime }} {{ $json.start.timeZone }} duration: {{ DateTime.fromISO($json.end.dateTime).diffTo(DateTime.fromISO($json.start.dateTime), 'minutes') }} minutesand keep Has Output Parser enabled. - Ensure LLM Chat Model is connected as the language model for Meeting Assistant (the model is
gpt-4.1-mini). - Ensure Calendar Availability is connected as the tool for Meeting Assistant with timeMin
{{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Start_Time', ``, 'string') }}and timeMax{{ /*n8n-auto-generated-fromAI-override*/ $fromAI('End_Time', ``, 'string') }}. - Credential Required: Connect your googleCalendarOAuth2Api credentials in Calendar Availability (AI tool node; credentials are used by Meeting Assistant).
- Verify Structured Output is connected to Meeting Assistant and uses the provided JSON schema for
slotsparsing. - In Compose Followup Text, set message to the provided expression that formats
$json.output.slotsinto a list of suggested times.
Step 6: Configure Followup Output/Action Nodes
Follow-up messages are sent in parallel after the AI composes the suggested slots.
- Verify that Compose Followup Text outputs to both WhatsApp Followup and Email Followup in parallel.
- In WhatsApp Followup, set number to
[YOUR_ID]and message to{{ $json.message }}. - Credential Required: Connect your rapiwaApi credentials in WhatsApp Followup.
- In Email Followup, set sendTo to
[YOUR_EMAIL], message to{{ $json.message }}, and subject to{{ $json.message.split(" ").slice(0, 10).join(" ") }}. - Credential Required: Connect your gmailOAuth2 credentials in Email Followup.
Step 7: Test and Activate Your Workflow
Run through a full test to validate both scheduling and follow-up branches before turning on production scheduling.
- Click Execute Workflow and confirm Timed Trigger pulls rows from Fetch Sheet Rows and creates an event via Add Calendar Entry.
- Check that Add Calendar Entry outputs to both WhatsApp Notify and Email Confirmation in parallel, and that Modify Sheet Status updates the sheet.
- Manually execute the follow-up branch from Followup Trigger to verify Retrieve Past Events → Meeting Assistant → Compose Followup Text → WhatsApp Followup/Email Followup.
- Successful execution should show created calendar events, sent confirmations, and follow-up messages containing slot lists.
- Once validated, toggle the workflow to Active so the triggers run on schedule.
Common Gotchas
- Google Sheets and Google Calendar credentials can expire or need specific permissions. If things break, check the n8n Credentials screen and your Google OAuth consent settings first.
- If you’re using Wait nodes or external processing, 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 45 minutes if your accounts and sheet columns are ready.
No. You’ll mostly connect accounts and map spreadsheet columns to calendar fields.
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 Gemini API usage (usually small for a few follow-up messages).
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 you should. Most people customize the “Filter Followups” step (what counts as a follow-up) and the “Compose Followup Text” message template, then adjust the AI agent’s system message to match working hours and how far ahead to suggest slots.
Usually it’s expired OAuth access in Google. Reconnect the Google Calendar credential inside n8n, then confirm the correct Calendar ID is selected in both the “Add Calendar Entry” and “Retrieve Past Events” actions. If it still fails, check that your Google account actually has permission to create events on that calendar, not just view it.
A lot. On n8n Cloud Starter you can run thousands of executions per month, and if you self-host you’re mostly limited by your server and Google API limits. Practically, teams handling dozens of meetings a day run this fine, as long as you keep the sheet tidy and avoid pulling huge date ranges from Calendar.
Often, yes, if you care about follow-ups and “don’t message twice” logic. This workflow uses deduplication (“Mark as Seen”), filtering, waits, and an AI agent that checks Calendar availability, which is the kind of branching that can get awkward or expensive in simpler tools. Zapier or Make can still work if you only want “row added → create event → send one message.” For the two-branch approach (create + follow-up), n8n is a better fit for most teams. If you’re undecided, Talk to an automation expert and get a quick recommendation.
Once this is running, meetings stop being a daily admin grind. You get clean Calendar events, instant confirmations, and follow-ups that actually happen.
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.