Integrations

Google Calendar

Connect Google Calendar to Project88 — read events, create events, run reminders, and let agents schedule on your behalf.

The Google Calendar integration connects your calendar via Composio OAuth. Once connected, every agent has calendar tools available by default.

Connect

  1. ⌘KSettings → Connections
  2. Search "Google Calendar" in the dynamic catalog.
  3. Click Connect. OAuth popup → callback page → token stored encrypted in Supabase Vault.

The Calendar mode lights up immediately and the calendar tools become available to agents.

Tools exposed

ToolWhat it does
GOOGLECALENDAR_EVENTS_LISTList events in a date range
read_calendar_eventsHigh-level read (auto-fallback)
create_calendar_eventCreate an event with attendees

The read_calendar_events and create_calendar_event tools have built-in auto-fallback: they try Google first, then Microsoft Outlook if no Google connection is found. So your agents work with whichever calendar provider you've connected — you don't have to swap the tool name.

Calendar mode

The Calendar mode renders three panels:

  • Mini calendar with event dots + day/week toggle + event legend
  • Day or week schedule with color-coded event cards
  • Event detail panel — type badge, time, location with Join Meeting link, description, attendees with RSVP status, and quick actions

Mirroring into Project 88

User-initiated events created against a Google calendar through the in-app create flow are atomically twinned into your default Project 88 calendar via the mirror_google_event_user_create RPC, sharing a mirror_group_id. Sync ingestion from Google does not mirror — otherwise every synced event would balloon into a second P88 row. Edits made directly inside Google.com will drift on the twin until you touch the event from Project 88. See Calendar → The default Project 88 calendar for the full mirror-write story.

Hiding noisy Google calendars

Imported sub-calendars (US Holidays, secondary accounts) can be removed from the sidebar via the gear icon → Remove from my calendar list without disconnecting the integration. They land in a collapsible Hidden section with a one-click restore. The hide flag survives Google sync re-imports (it's stored separately from the soft-delete flag the sync path resurrects on conflict).

Real-time push notifications

Once connected, calendar-sync registers a Google watch channel per calendar (7-day TTL, renewed when <24 h remain) so external Google-side changes — a booking made via a scheduling link, an event edited in Google Calendar itself, an assistant creating on your behalf — surface in Project 88 within seconds. See Calendar → Real-time sync for the client-side toast behavior.

Pushes hit the calendar-webhook edge function, which authenticates them on a per-channel random token (verify_jwt off — Google sends no Supabase JWT) and runs the same syncToken delta pull as the scheduled sync. Migrations 147 and 148 back this: 147 adds calendar_events to the supabase_realtime publication (payloads RLS-gated by the existing org-membership policy), 148 adds watch_channel_id / watch_resource_id / watch_token / watch_expires_at on calendars plus a partial index.

Google domain verification

Google requires the push-endpoint domain to be verified in the Google Cloud console (Search Console domain verification + the "Domain verification" tab under APIs & Services). If *.supabase.co/functions/v1/calendar-webhook isn't verified for the OAuth project, watch registration fails — this is logged (watch: "failed" in the sync response, warning in the edge function logs) and the app gracefully falls back to the 60 s polling layer that ships in the same PR. Check the function logs after the first calendar load to confirm whether push registered.

Reminders

The calendar-reminders Supabase Edge Function runs every minute and emits reminder events for upcoming meetings into the org.

pg_cron jobs read project_url and service_role_key from vault.decrypted_secrets rather than session GUCs — Supabase forbids ALTER DATABASE … SET app.settings.*, so any migration that schedules a cron via GUCs will silently 401 every minute. The Vault lookup is the Supabase-documented pattern; the service_role_key Vault secret is created once via the dashboard SQL editor (it never belongs in a migration). Migration 150 reschedules process-calendar-reminders and gmail-watch-renewal onto this pattern.

Where to next

On this page