Skip to content

Google Calendar Source

What it ingests

Calendar events — titles, times, attendees, and recurrence — from every Workspace user in the org. Coverage fans out across every member by impersonating each user, so a single subject is not required for ingestion.

Unlike Google Meet, Calendar sees meetings that were held, not only meetings that were recorded. An unrecorded recurring 1:1 is visible here. When an event carries a Google Meet conference that Meet has already ingested, the calendar row attaches to the same Meeting entity as the transcript rather than minting a second one.

The mapper stays structured and low-volume: one Event entity per calendar event and per recurring series, not one per RSVP change.

Credential

References a google_service_account_json credential by id — the same type Meet and Drive already use. No new service account. The secret is the full service-account key JSON. Leave it blank to fall back to application-default credentials (ADC) for local/dev use without impersonation.

The existing domain-wide delegation grant must include:

https://www.googleapis.com/auth/calendar.readonly

Test connection names this scope if it is missing, rather than returning a generic 403.

bash
curl -sS -X POST https://your-corveil-host/api/credentials \
  -H "Authorization: Bearer <admin>" -H "Content-Type: application/json" \
  -d @- <<'JSON'
{ "type": "google_service_account_json", "name": "acme-workspace-sa",
  "secret": "{\"type\":\"service_account\", ... }" }
JSON

If you already created this credential for Meet or Drive, reuse it. Add calendar.readonly to the existing DWD grant in the Workspace Admin console — do not mint a second key.

Config fields

All config fields are optional — with a DWD service account and no config, the source fans out across every org member.

KeyNotes
impersonate_subjectConnection-test user only. A Workspace user Test connection impersonates to probe Calendar reachability. Not needed for ingestion.
member_allowlistComma-separated Workspace users. Restricts fan-out to these members (staged rollout / testing).
workspace_domainsComma-separated domains. Only members whose email domain matches are impersonated; others are skipped.
lookback_daysHow far back the first poll / backfill reads. Defaults to 90. Incremental polls use updatedMin and are not capped by this window.
lookahead_daysHow far forward the first poll / backfill reads. Defaults to 180. Incremental polls omit the forward cap so a newly created future meeting is ingested when it is created.
poll_overlap_minutesMinutes to re-scan before the last cursor, to catch edits that landed while a poll was in flight. Defaults to 30.

Provider-side setup

  1. Reuse the service account already used for Meet / Drive, or create one and download its key JSON.
  2. Enable the Google Calendar API on the project.
  3. In the Workspace Admin console, enable domain-wide delegation for the service account and authorize https://www.googleapis.com/auth/calendar.readonly on the existing client (alongside the Meet / Drive readonly scopes).

Wire-up

POST /api/sensors

json
{
  "sensor_type": "googlecalendar",
  "name": "Acme Google Calendar",
  "config": {},
  "credentials": { "service_account_json": "<google_service_account_json credential id>" }
}

Staged rollout to two users first:

json
{
  "sensor_type": "googlecalendar",
  "name": "Acme Calendar (pilot)",
  "config": { "member_allowlist": "alice@acme.com, bob@acme.com" },
  "credentials": { "service_account_json": "<credential id>" }
}

Verify

Run Test connection. With a service account it impersonates impersonate_subject to probe Calendar reachability; if that subject is unset it only checks that the key parses. A missing calendar.readonly grant fails with a named scope error.

Once polling, newly created or edited events appear as calendar events. An event whose attendees include people already in the graph (Slack, GitHub, Meet) canonicalizes onto those same Person entities by email.