Google Calendar to Meta CAPI, track booked demos
You’re paying for leads, demos are getting booked, and Meta still shows “maybe” conversions. Meanwhile your team is stuck arguing over attribution, exporting calendars, and trying to prove which campaigns actually move pipeline.
This hits performance marketers first, but sales ops and founders feel it too. Meta CAPI tracking shouldn’t require spreadsheets and guesswork. You want demos to show up as real conversions, tied to the right campaigns, so optimization is based on outcomes.
This workflow watches your Google Calendar for booked demos, filters the right events, and sends them to Meta’s Conversions API. You’ll see what it does, what you need, and where people usually get stuck.
How This Automation Works
See how this solves the problem:
n8n Workflow Template: Google Calendar to Meta CAPI, track booked demos
flowchart LR
subgraph sg0["Google Calendar Flow"]
direction LR
n0@{ icon: "mdi:play-circle", form: "rounded", label: "Google Calendar Trigger", pos: "b", h: 48 }
n1@{ icon: "mdi:swap-horizontal", form: "rounded", label: "If", pos: "b", h: 48 }
n2@{ icon: "mdi:cog", form: "rounded", label: "No Operation, do nothing", pos: "b", h: 48 }
n3["<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/>HTTP Request - Meta Conversi.."]
n4@{ icon: "mdi:cog", form: "rounded", label: "Crypto", pos: "b", h: 48 }
n5@{ icon: "mdi:swap-vertical", form: "rounded", label: "Params", pos: "b", h: 48 }
n6@{ icon: "mdi:swap-vertical", form: "rounded", label: "Config", pos: "b", h: 48 }
n1 --> n4
n1 --> n2
n6 --> n1
n4 --> n5
n5 --> n3
n0 --> n6
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 n0 trigger
class n1 decision
class n3 api
classDef customIcon fill:none,stroke:none
class n3 customIcon
The Challenge: Meta can’t “see” booked demos reliably
Most lead funnels track the easy thing: a form submit or a thank-you page view. But booked demos often happen later, in a separate tool, with different identifiers. That’s where reporting breaks. You end up optimizing ads for cheap leads instead of qualified meetings, because Meta never gets the “booked demo” signal. Worse, people start patching it manually: exporting calendar events, updating spreadsheets, or sending ad platform updates by hand. It’s tedious, error-prone, and honestly distracting.
It adds up fast. Here’s where it usually breaks down inside real teams.
- Booked demos live in Google Calendar, but your ad reporting lives somewhere else, so you never get a clean source of truth.
- Manual “demo tracking” depends on someone remembering to log or tag events, which eventually stops happening.
- Meta optimizes toward what it can measure, so you end up feeding it low-quality conversion events.
- Teams waste time debating attribution instead of fixing creative, audiences, and follow-up.
The Fix: Send “Booked Demo” events to Meta CAPI from Google Calendar
This n8n workflow turns your calendar into a conversion source. It triggers whenever a new event appears on a specific Google Calendar account, then checks if the event matches your demo booking name (for example, “Schedule a demo”). If it’s the right event, the workflow prepares the data Meta needs, hashes identifying fields (like email) when available, and assembles a Conversions API payload. Finally, it sends that payload to Meta via an HTTP request. If the event doesn’t match, it safely does nothing, so your calendar can stay messy without spamming Meta.
The workflow starts with a Google Calendar watch trigger. It runs a simple filter so only demo events continue. Then it formats the conversion event (including your Pixel ID, access token, source URL, and event name) and posts it to Meta CAPI, which means Meta can optimize based on meetings, not just clicks.
What Changes: Before vs. After
| What This Eliminates | Impact You’ll See |
|---|---|
|
|
Real-World Impact
Say you book 20 demos a week from paid traffic. Manually tracking them often looks like: 5 minutes to find each event, another 3 minutes to copy details into a sheet, then 2 minutes to reconcile totals later. That’s roughly 10 minutes per demo, or about 3 hours weekly. With this workflow, it’s close to zero time per booking after setup: the trigger runs instantly, the Meta request takes a moment, and you’re done. Those 3 hours don’t sound dramatic until you get them back every week.
Requirements
- n8n instance (try n8n Cloud free)
- Self-hosting option if you prefer (Hostinger works well)
- Google Calendar to detect new booked demo events.
- Meta Conversions API to record demo conversions in Meta.
- Meta Pixel ID + Access Token (get it from Meta Events Manager)
Skill level: Beginner. You’ll connect accounts, paste IDs/tokens, and confirm the calendar event name you want to track.
Need help implementing this? Talk to an automation expert (free 15-minute consultation).
The Workflow Flow
A new Google Calendar event is created. The workflow monitors a chosen Google account and fires as soon as a new event appears.
Your tracking parameters get applied. A setup step injects your Pixel ID, access token, source URL, and preferred event name so the rest of the workflow stays consistent.
Only demo bookings continue. An “if” check filters by event name (like your “Schedule a demo” booking). If it’s not a match, the workflow routes to a safe no-op and exits quietly.
Data is prepared and sent to Meta. If the event matches, email hashing runs when available, the Meta payload is assembled, and an HTTP request pushes the conversion event into Meta CAPI for reporting and optimization.
You can easily modify the event name and source URL to match your funnel and booking flow. See the full implementation guide below for customization options.
Step-by-Step Implementation Guide
Step 1: Configure the Google Calendar Trigger
This workflow starts when a new calendar event is created. Configure the Google Calendar trigger node to watch the correct calendar and polling frequency.
- Add the Calendar Event Watcher node as your trigger.
- Set Trigger On to
eventCreated. - Set Calendar ID to
[YOUR_EMAIL](select your calendar from the list). - In Poll Times, set the mode to
everyMinute. - Credential Required: Connect your googleCalendarOAuth2Api credentials.
Step 2: Connect Google Calendar
Confirm the calendar connection is stable and authorized to read new events from the selected calendar.
- Open Calendar Event Watcher and verify the selected account in Credentials matches your calendar owner.
- Ensure the OAuth consent includes calendar read access for the selected account.
- Save the node and re-run a manual test to confirm events are detected.
Step 3: Set Up Processing and Branch Logic
Prepare configuration values, filter events by name, hash attendee email data, and assemble the Meta Conversions API payload.
- In Setup Parameters, keep Include Other Fields enabled and set the assignments: FB_PIXEL_ID to
[YOUR_ID], FB_ACCESS_TOKEN to[CONFIGURE_YOUR_TOKEN], FB_API_VERSION tov22.0, source_url tohttps://[YOUR_ID], and event_name_filter to[YOUR_ID]. - In Branch Logic Check, configure the condition to compare Left Value
={{ $json.summary }}with Right Value={{ $json.event_name_filter }}using contains. - Note the flow: Setup Parameters → Branch Logic Check, and when the condition matches, Branch Logic Check routes to Hash Email; otherwise it routes to No-Op Placeholder.
- In Hash Email, set Type to
SHA256, Value to={{ $json.attendees[1].email }}, and Data Property Name tohashedEmail. - In Assemble Payload, add assignments: em to
={{ $json.hashedEmail }}, client_ip_address to={{$json.clientIp || '0.0.0.0'}}, client_user_agent to={{$json.userAgent || 'n8n/MetaCAPI'}}, and event_time to={{Math.floor(Date.now() / 1000)}}.
$json.attendees[1].email assumes a second attendee exists. If your events have different attendee structures, adjust the index to avoid empty hashes.Step 4: Configure the Meta Conversions API Request
Send the assembled conversion event to Meta via a custom HTTP request.
- Open Meta API Request and set Method to
POST. - Set URL to
=https://graph.facebook.com/{{$('Setup Parameters').item.json.FB_API_VERSION}}/{{$('Setup Parameters').item.json.FB_PIXEL_ID}}/events. - Enable Send Body and set Content Type to
multipart-form-data. - In Body Parameters, set data to
=[ { event_name: "Schedule", event_time: {{ $json.event_time }}, action_source: "website", event_source_url: "{{$('Setup Parameters').item.json.source_url}}", user_data: { em: ["{{ $json.em }}"], client_ip_address: "{{ $json.client_ip_address }}", client_user_agent: "{{ $json.client_user_agent }}" }, attribution_data: { attribution_share: "1.0" }, original_event_data: { event_name: "Schedule", event_time: {{ $json.event_time }} } } ]. - Set access_token to
={{$('Setup Parameters').item.json.FB_ACCESS_TOKEN}}. - In Header Parameters, set Content-Type to
application/json.
Step 5: Test and Activate Your Workflow
Validate that events are captured and the Meta API call succeeds before enabling the workflow in production.
- Click Execute Workflow and create a new calendar event that matches your event_name_filter value.
- Confirm the execution path goes from Calendar Event Watcher → Setup Parameters → Branch Logic Check → Hash Email → Assemble Payload → Meta API Request.
- Check the Meta API Request response for a success status and payload acceptance.
- If the event does not match the filter, verify that it routes to No-Op Placeholder as expected.
- When satisfied, toggle the workflow to Active for continuous monitoring.
Watch Out For
- Google Calendar OAuth credentials can expire or lose access when a user changes passwords. If the trigger stops firing, check the Google connection inside n8n credentials first.
- If you’re using Wait nodes or external rendering, processing times vary. Bump up the wait duration if downstream nodes fail on empty responses.
- Meta CAPI tokens and permissions are finicky. If the HTTP request starts returning errors, confirm the access token is still valid and that your Pixel has the correct permissions in Events Manager.
Common Questions
About 30 minutes if you already have your Pixel and token ready.
Yes. You won’t write code, but you will copy/paste IDs, connect Google OAuth, and test one real booking.
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 Meta API usage (usually negligible) and any server costs if you self-host.
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.
You can change what counts as a conversion by editing the event name check in the “Branch Logic Check” step, then updating the “Setup Parameters” and “Assemble Payload” steps to send “Purchase,” “Lead,” “InitiateCheckout,” or a custom event. Many teams also adjust the source_url to match their booking page domain for cleaner attribution. If you capture additional fields (like phone or last name) in the calendar description, you can map them into the payload too. The structure stays the same.
Usually it’s expired Google OAuth credentials or the wrong calendar/account selected in the trigger. Reconnect the Google credential in n8n, then confirm the trigger is watching the calendar where bookings actually land. Also check that the event name filter matches exactly, because “Schedule a Demo” and “Schedule a demo” won’t behave the same.
Plenty for most small teams: hundreds of events a day is fine.
Often, yes, especially if you want control over the exact Meta payload and hashing without paying extra for “premium” steps. n8n makes it straightforward to add branching logic, do nothing safely when an event doesn’t match, and keep everything in one workflow. It’s also easier to extend later, like sending a Slack alert when a VIP company books. Zapier or Make can still be a fit if you want the simplest possible setup and don’t care about customization. If you’re torn, Talk to an automation expert and you’ll get a straight recommendation.
Once this is running, demo tracking stops being a weekly chore and starts being reliable data inside Meta. Set it up once, then get back to the work that actually grows 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.