Google Calendar to Outlook Calendar Sync
Bidirectional sync between Google Calendar and Outlook to ensure events are visible across both platforms.
Provided as-is, without warranty of any kind. Review and test each pattern in a non-production environment before deploying it to live automations. See our Terms.
Overview
A bidirectional, scheduled sync that mirrors events between a user's Google Calendar and Outlook calendar. Every 15 minutes the flow inspects both calendars across a configurable look-ahead window, identifies events present on one side but not the other, and creates the missing copy on the opposite side. Synced events are tagged with a configurable prefix (default [Synced]) so the flow can deterministically skip events it produced itself, preventing infinite re-sync loops.
Use Case
Knowledge workers who run separate personal (Google) and corporate (Microsoft 365) calendars routinely miss meetings because the two views don't agree. Manual cross-posting is error-prone. This flow keeps a unified, time-bounded picture without requiring users to give up either calendar — making it a strong fit for IT Admins enabling BYO-Google scenarios and any business user with a split calendar lifestyle.
Flow Architecture
Run Every 15 Minutes
RecurrenceScheduled trigger that fires every 15 minutes (frequency: Minute, interval: 15).
Initialize varGoogleCalendarId
Initialize variableInit a string variable from the flowlibs_GoogleCalendarId env var (default `primary`).
Initialize varOutlookCalendarId
Initialize variableInit a string variable from flowlibs_OutlookCalendarId (default `Calendar`). This is the Outlook calendar `table` path parameter.
Initialize varSyncWindowHours
Initialize variableInit from flowlibs_SyncWindowHours (default `24`). Controls how far ahead of `utcNow()` to consider events.
Initialize varSyncTagPrefix
Initialize variableInit from flowlibs_SyncTagPrefix (default `[Synced]`). Used to mark synced events on both sides so they aren't re-mirrored.
Initialize varTimeZone
Initialize variableInit from flowlibs_TimeZone (default `Eastern Standard Time`). Windows time zone identifier for Outlook event creation.
Compose Sync Window Start
ComposeComposes `utcNow()` as the start of the look-ahead window.
Compose Sync Window End
ComposeComposes `addHours(utcNow(), int(variables('varSyncWindowHours')))` as the end of the look-ahead window.
List Google Calendar Events
Google Calendar — ListEventsCalls `shared_googlecalendar / ListEvents` with `calendarId`, `timeMin`, and `timeMax` set from the two Compose steps.
Environment Variables
| Schema name | Type | Default | Description |
|---|---|---|---|
| flowlibs_GoogleCalendarId | String | primary | Path parameter for the Google Calendar `ListEvents` / `CreateEvent` calls. `primary` selects the signed-in user's main calendar. |
| flowlibs_OutlookCalendarId | String | Calendar | Path `table` parameter for Outlook `V4CalendarGetItems` / `V4CalendarPostItem`. `Calendar` selects the user's default calendar. |
| flowlibs_SyncWindowHours | String | 24 | Number of hours ahead of `utcNow()` to mirror. Larger values mean slower runs and more API quota use. |
| flowlibs_SyncTagPrefix | String | [Synced] | Prefix applied to mirrored event titles. Required to avoid infinite re-sync. |
| flowlibs_TimeZone | String | Eastern Standard Time | Windows time zone passed to `item/timeZone` when creating Outlook events. Must be a valid Windows TZ identifier. |
Connectors & Connections
| Connector | API name | Actions used |
|---|---|---|
| Google Calendar | shared_googlecalendar | ListEvents CreateEvent |
| Office 365 Outlook | shared_office365 | V4CalendarGetItems V4CalendarPostItem |
Note — All connections are referenced as solution connection references; the flow is portable between environments as long as a connection is mapped at import time.
Customization Guide
Almost every realistic variant of this flow can be implemented by changing environment variable values. A few cases require small edits inside the flow definition — those are called out explicitly below.
- Change which calendars sync
- Update flowlibs_GoogleCalendarId to a non-primary calendar's ID, or flowlibs_OutlookCalendarId to a shared mailbox's calendar name. Both env vars are simple strings — no flow edits required.
- Adjust the look-ahead window
- Set flowlibs_SyncWindowHours to 48, 72, etc. Keep this proportional to how frequently events are added to either calendar.
- Adopt a different sync marker
- Change flowlibs_SyncTagPrefix to e.g. >> or [GCAL]. Existing mirrored events will need to be renamed manually or they will be re-synced on the next run.
- Alter the schedule
- Edit the trigger's Recurrence (15 Minute default) — frequencies under 5 minutes risk Google Calendar quota throttling.
- One-way sync only
- Delete the corresponding For Each block (the Google→Outlook or Outlook→Google loop) to disable a sync direction.
- Run as a service account
- Re-author each connector reference using a service account so meeting room calendars or shared mailboxes can be mirrored.
Key Expressions
The flow is intentionally light on Power Fx / WDL gymnastics — the heaviest expressions are the branch-name concatenation and the approval outcome check. They are listed below in the order they appear in the flow.
EXPR.01Sync window end
Computes the upper bound of the look-ahead window from the configurable hours env var.
EXPR.02Outlook OData filter
Builds the `$filter` string passed to `V4CalendarGetItems` so Outlook only returns events inside the sync window.
EXPR.03Skip already-synced Google events
Filter-array predicate used to drop Google events that this flow already mirrored from Outlook.
EXPR.04Mirrored title (Google → Outlook)
Prepends the sync tag prefix to the source Google summary when creating the Outlook event.
EXPR.05Outlook event start (date-no-tz format)
Formats the Google event start so it matches the no-offset format Outlook expects on `item/start`.
EXPR.06Match-existence test
Condition expression — true when no existing mirrored event was found, meaning we should create one.
Comments
Sign in to join the conversation.
Sign inNo comments yet. Be the first to share your experience with this flow.