By Raj

Estimated reading time: 18 minutes · Technical pillar (~3,000 words in companion Markdown)

Sync Google Calendar with Microsoft Outlook | Apps Script + Microsoft Graph Enterprise Guide

If you need to sync Google Calendar with Microsoft Outlook without another per-seat utility bill, this guide delivers a professional-grade, one-way automation path: read Google Calendar, upsert Outlook events via the Microsoft Graph API, and persist idempotent mappings so reruns update in place instead of duplicating invites. It is written for US and Canadian enterprise stakeholders who care about OAuth governance, North American time zones, and realistic limits of two-way calendars. Companion assets include a full Microsoft Graph API Google Apps Script tutorial implementation you can audit like production code—because automate Google Calendar to Outlook workflows deserve engineering rigour, not fragile hacks.

[!IMPORTANT] Full ~3,000-word Markdown with identical technical depth lives at sync-google-calendar-outlook-apps-script.md — this page mirrors the architecture, decisions, and links for SEO and navigation.

Executive summary: why native connectors disappoint power users

Consumer connectors promise simplicity; enterprise reality demands low-latency updates, deterministic mapping, private-by-default URLs, and audit logs. Native “link my calendars” flows often refresh slowly, mishandle recurring exceptions, or expose subscription secrets. This pillar teaches an API-first alternative so your Google Apps Script Outlook API integration behaves like internal software: triggers, structured logs, secret rotation, and explicit scope reviews for Microsoft 365 administrators.

Two-way vs one-way: the engineering truth

Two-way synchronization is not “double the one-way code.” It is distributed reconciliation: recurring series algebra, exception instances, attendee-driven moves, and conflict policies that last-write-wins cannot safely represent in regulated environments. That is why this repository ships a robust Google → Outlook push with delta upserts—not blind delete/recreate—using a hidden mapping sheet (CalendarSyncMap) plus optional Graph singleValueExtendedProperties for diagnostics.

API vs public iCal debate

ApproachPrivacyControl
Public iCal URLSecret in link; leakage riskLimited field mapping
Graph API + Apps ScriptOAuth secrets in Script PropertiesFull payload + logs

Azure App Registration: clicks that matter

Open Azure PortalMicrosoft Entra IDApp registrationsNew registration. Record Application (client) ID and Directory (tenant) ID. Under Certificates & secrets, create a client secret and copy the Value once.

[!IMPORTANT]

Under API permissionsMicrosoft GraphDelegated, add Calendars.ReadWrite, offline_access, openid, profile. Use Grant admin consent when policy requires it. Interactive consent must capture offline_access so refresh tokens work for scheduled triggers.

Architecture: delta sync without duplicate storms

Instead of deleting and recreating Outlook events (which fractures conference links and spams attendees), the engine issues HTTP PATCH to existing items when the hidden map contains an Outlook ID. New Google events POST once, then persist the returned Graph ID. That is delta sync in the practical sense enterprise teams mean: deterministic upserts, not naive full replaces.

Section 1: Authentication (OAuth2 for Microsoft)

Scheduled automation cannot open a browser every fifteen minutes—store MS_REFRESH_TOKEN in Script Properties and exchange it for an access token using the tenant token endpoint. The sample rotates refresh tokens when Graph returns them.

JavaScript (Apps Script) — excerpt

// Refresh-token grant → access token for Microsoft Graph
var url = "https://login.microsoftonline.com/" + tenant + "/oauth2/v2.0/token";
var body =
  "client_id=" + encodeURIComponent(clientId) +
  "&client_secret=" + encodeURIComponent(clientSecret) +
  "&refresh_token=" + encodeURIComponent(refreshToken) +
  "&grant_type=refresh_token" +
  "&scope=" + encodeURIComponent(
    "https://graph.microsoft.com/Calendars.ReadWrite offline_access"
  );

Section 2: Mapping Google Calendar fields to Outlook JSON

Timed meetings send start/end with paired dateTime and explicit timeZone. All-day events map to Graph date boundaries with UTC anchoring—mirroring Google’s exclusive end semantics. Optional: map private visibility to Graph sensitivity when CalendarApp exposes it.

Section 3: Sync loop & error logging

The main function iterates Google events in the forward window, upserts Graph events, updates the map tab, and appends failures to CalendarSyncLog. Pair this with operational monitoring—especially after Azure policy or Conditional Access changes.

Time zones: EST, CST, MST, PST & Canada

Set Apps Script Project time zone to your operational headquarters. The sample defaults to IANA zones (for example America/Chicago) and can switch to Windows names—Eastern Standard Time, Central Standard Time, etc.—when property GRAPH_TIMEZONE_MODE=windows because some tenants require Windows-style identifiers.

Automation: ScriptApp triggers every 15 or 30 minutes

Installable triggers call syncGoogleCalendarToOutlook on a cadence your Workspace policy allows—often 30 minutes as the safest default. A 15-minute variant ships in the .gs file for teams that confirm shorter intervals are permitted.

JavaScript (Apps Script)

function installSyncTriggerEvery30Minutes() {
  ScriptApp.getProjectTriggers().forEach(function (t) {
    if (t.getHandlerFunction() === "syncGoogleCalendarToOutlook") {
      ScriptApp.deleteTrigger(t);
    }
  });
  ScriptApp.newTrigger("syncGoogleCalendarToOutlook")
    .timeBased()
    .everyMinutes(30)
    .create();
}

Large calendars should keep SYNC_DAYS_FORWARD modest to respect execution limits—see execution time limits and trigger troubleshooting.

Edge cases: all-day, private events, recurring meetings

  • All-day: use Graph date fields; validate exclusive end dates around DST boundaries.
  • Private: best-effort sensitivity mapping—verify with your Calendar visibility model.
  • Recurring: hardest problem in calendar engineering—sync forward windows instance-by-instance; document acceptance tests (March/November DST, floating holidays).

Comparison: Apps Script vs Power Automate vs paid sync tools

OptionBest whenTrade-off
Apps Script + GraphYou want code-level control & sheet-backed logsEngineering time up front
Power AutomateLow-code flows inside MicrosoftComplex branches get hard to maintain
Paid sync toolsDesktop-centric budgets accept subscriptionVendor lock-in & seat pricing

Downloads & related tutorials

Enterprise migration & custom automation

This guide is intentionally free so engineering-led organizations can evaluate Graph honestly. When you have 50+ users, hybrid Exchange, cross-tenant moves, or compliance gates, App Script Expert delivers custom enterprise calendar migration programmes: discovery, permission models, runbooks, and production cutovers—beyond what a generic tutorial can prescribe.

Contact App Script Expert

About the author

Raj architects Google Workspace automation and cloud integrations for operations-focused teams across the United States and Canada.

More about Raj