snek-tech-blog/content/posts/ical-and-google/index.md

81 lines
4.9 KiB
Markdown

---
title: "iCalendar, Google Calendar, CalDAV, and friends"
date: 2023-06-16T19:19:19+10:00
draft: true
showSummary: true
summary: "Ever wondered if it's possible to link Calendar.app to a Google Suite Calendar that isn't your default account calendar? Let's find out!"
---
# Syncing GSuite Calendars to Calendar.app
## TL;DR
If you're just looking for a solution to syncing your GSuite Calendars to Calendar.app, go to [The Actual How-To]({{< relref "ical-and-google.md#the-actual-how-to" >}}).
## Background: CalDAV and friends
So before we get into this, it'll be useful to explain how online calendars work. You've probably seen calendar invites in your email before, and noticed that a lot of email providers also provide planning/calendar apps. The way this integration is done is via [CalDAV](https://en.wikipedia.org/wiki/CalDAV).
## What is CalDAV?
CalDAV, or Calendering Extensions for WebDAV, is a standard to allow for standardised events, tasks, and busy/free info to be shared and subscribed to. It structures data using the iCalendar format (not to be confused with the macOS app iCal, which uses this same format), and allows for sharing and subscription to calendars via an updated ics file, and can fall back to delivering updates via email (this is how Microsoft Exchange handles sending out event updates to external CalDAV servers, for example). Access can be public, or controlled via a multitude of authentication mechanisms, and ACLs are used to control whether a user can view events, free/busy information only, or edit/create/delete events.
## Authentication with CalDAV
CalDAV servers can allow for a myriad methods of authentication, including OAuth, Basic Auth, SAML, OIDC, and so on. This is where our issue comes in.
## The Problem
By default, Calendar.app *does* allow for the import of and syncing with Google Calendar accounts, however there exist several limitations:
1. You can only import the main calendar associated with your account. If you have several calendars, or are invited to another calendar that you want to sync to Calendar.app, this is not possible.
2. You can import the Calendar address as an arbitrary CalDAV endpoint, however the Google API only accepts OAuth requests, which Calendar.app doesn't know and will not open the flow for.
## How do we fix it?
We need some way to either force Calendar.app to open the OAuth flow, or get the google API to accept some other authentication mechanism. After fighting Calendar.app for a while, including some time in IDA, we found no easy (or hard) way to do this, so we turned our attention to making the Google CalDAV API behave.
After digging around the API Docs for a while, we discovered that there exists a legacy endpoint:
!["A screenshot showing that an \"old endpoint\" at https://google.com/calendar/dav exists, but is deprecated" !](gsuite-caldav-dep.png)
With a little more google-fu, we managed to find some old tutorials on syncing to the google CalDAV servers that use this deprecated endpoint.
If we put all that together, we can maybe clobber Calendar.app into syncing properly while also allowing you to have more than one calendar per Google account.
Some testing later, it turns out we were right!
## The Actual How-To
*Note: This has been tested on macOS 13.3.1(a) (22E772610a) with Apple Calendar 11.0 (2932.4.5).*
### Steps
1. Create an app password for Calendar from [My Account](https://myaccount.google.com) →
Security → 2-Step Verification → App passwords
2. Generate App password for Calendar. (Device type likely doesn't matter here, but we tested Mac)
3. In Apple Calendar, go to Calendar → Add Account → Other CalDAV Account
Account Type → Advanced:
* **User Name:** \<Google account email\>
* **Password:** \<App password from above\>
* **Server Address:** www.google.com
* **Server Path:** /calendar/dav/\<calid\>@group.calendar.google.com/user
* **Port:** 443
* **Use SSL:** [X]
4. Click "Sign In" and it should Just Work™!
### Notes
The `calid` value comes from Other calendars → Settings → Integrate calendar → Calendar ID.
This seemingly only works with the old www.google.com/calendar/dav endpoint, since the newer https://apidata.googleusercontent.com/caldav/v2 one requires OAuth, and the DataAccess.framework handling for CalDAV requests will only use OAuth for Google account types, and not generic CalDAV.
### Resources
* [Google CalDAV API Docs](https://developers.google.com/calendar/caldav/v2/guide)
* [CalDAV URL example for deprecated endpoint](https://www.davx5.com/tested-with/google)
* [App-password Docs](https://support.google.com/accounts/answer/185833?hl=en)
## The Caveats
Since this is a deprecated endpoint, this could stop working at any time, and [knowing Google](https://9to5google.com/2023/06/15/google-domains-squarespace), it really could be ANY TIME.
## Thanks
Massive thanks to arc and one alice, who did most of the legwork here, in between their knowledge of GSuite and macOS; we just did the write-up and background.