Google Calendar Integration

Purpose and Scope

This page explains how a self-hosted Cal.diy operator enables Google Calendar as an app-store integration. The setup has two sides: a Google Cloud configuration task that creates OAuth credentials with Calendar access, and a Cal.diy configuration task that stores those credentials and exposes the integration through the app store. The official app documentation describes the credential flow, required redirect URIs, Calendar scopes, environment variables, and app-store refresh command. The app-store package source shows how the Google Calendar package publishes its integration surface to the rest of the monorepo.

Sources: apps/docs/content/apps/google.mdx, packages/app-store/googlecalendar/index.ts

Google Calendar setup is different from simply turning on Google login. The app documentation asks you to authorize both the calendar integration callback and the authentication callback, but it also instructs self-hosters to set the Google login flag to disabled when configuring the calendar app as an internal integration. That distinction matters because the calendar integration needs OAuth access to read and create events, while account login changes who can authenticate to the Cal.diy instance. Treat calendar access, app visibility, and login policy as separate concerns when reviewing a deployment.

Sources: apps/docs/content/apps/google.mdx

Relevant Source Files

  • apps/docs/content/apps/google.mdx — Reader-facing setup guide for obtaining Google API credentials, selecting Calendar scopes, adding redirect URIs, storing the downloaded OAuth JSON, disabling Google login, and repopulating the app store.
  • packages/app-store/googlecalendar/api/index.ts — API barrel for the Google Calendar app package; it exports the app API handlers named add and callback.
  • packages/app-store/googlecalendar/index.ts — Package-level barrel for Google Calendar; it exports the api namespace, lib namespace, and metadata for app-store discovery and consumption.

Credential Setup Flow

Start in the Google API Console with a Google Cloud project. The documented flow begins from the API dashboard, where you enable APIs and services, search for Calendar, and enable the Google Calendar API. This is the prerequisite that lets the OAuth client request Calendar permissions later. If the API is not enabled for the selected project, Cal.diy may still be able to store credentials, but Google will not grant the integration the Calendar access it needs during authorization.

Sources: apps/docs/content/apps/google.mdx

After enabling the API, configure the OAuth consent screen. The app documentation directs you to choose an app type, enter the basic app details, and then add Calendar scopes. The required scopes are the Calendar events scope and the Calendar read-only scope. In practice, these scopes align with scheduling needs: the integration must inspect availability-related calendar data and create or update booking-related events. For test or non-public setups, remember to add the Google accounts that will authorize the integration as test users before completing the consent screen.

Sources: apps/docs/content/apps/google.mdx

Next, create an OAuth Client ID using the Web Application application type. The redirect URI list is the most deployment-sensitive part of the configuration because it must match the URL where the Cal.diy web app runs. The app guide requires two authorized redirect URIs: the Google Calendar integration callback at the integrations route and the Google authentication callback at the auth route. Replace the placeholder host with the externally reachable Cal.diy URL, including the correct scheme, domain, and any reverse-proxy-visible base URL.

Sources: apps/docs/content/apps/google.mdx

Cal.diy Configuration

Once Google creates the OAuth client, download the client ID JSON from the Credentials page. The documentation instructs you to copy the entire JSON contents into both environment files under the Google API credentials key. Keeping the same value in the normal application environment and the app-store environment is important because the web application and app-store seeding path can be evaluated in different process contexts. If one file is updated and the other is not, the integration can appear configured in one phase but fail during another.

Sources: apps/docs/content/apps/google.mdx

The Google app documentation also tells operators to set the Google login flag to false in the main environment file. In that mode, the Google integration is configured as an internal app and login access is restricted. This is especially important for personal self-hosted deployments, where calendar connection is often desired but public Google sign-in is not. After editing environment files, restart any affected application processes so that the server, background tasks, and app-store seeding process read the updated values.

Sources: apps/docs/content/apps/google.mdx

Use the following values as the checklist for the environment and redirect configuration. The values are shown as names and paths rather than secrets; do not commit the downloaded JSON or paste credentials into source-controlled files. Make sure the public URL exactly matches the address users will use in the browser, because OAuth providers compare redirect targets strictly. If the instance is behind a proxy, configure the Google console with the public HTTPS URL, not an internal container address or localhost-only address.

Sources: apps/docs/content/apps/google.mdx

  • Required credential key: GOOGLE_API_CREDENTIALS in both .env and .env.appStore.
  • Recommended login policy for this setup: GOOGLE_LOGIN_ENABLED=false in .env.
  • Integration redirect URI: <Cal.diy URL>/api/integrations/googlecalendar/callback.
  • Authentication redirect URI: <Cal.diy URL>/api/auth/callback/google.
  • Required app-store refresh command after credentials are present: pnpm db-seed.

System-to-Code Mapping

The Google Calendar package follows the same app-store shape used by other integrations in the monorepo. Its package-level entrypoint re-exports three public surfaces: an api namespace, a lib namespace, and metadata. That structure lets callers import the app package without reaching into implementation files directly. The metadata export supports app-store discovery, while the api namespace gives the web application access to route handlers needed for connecting the integration. The source shown here is a small barrel file, but it is the public boundary that downstream code should depend on.

Sources: packages/app-store/googlecalendar/index.ts

Inside the API namespace, the Google Calendar app exposes two named handlers: add and callback. The add handler represents the start of the connection flow, where a user chooses to add Google Calendar from the app store or settings area. The callback handler represents the OAuth return path that Google redirects to after the user grants access. The documented redirect URI maps directly to that callback concept, so OAuth configuration in Google Cloud and exported handler structure in the package must stay aligned.

Sources: packages/app-store/googlecalendar/api/index.ts, apps/docs/content/apps/google.mdx

ConcernSource-backed contract
User setup guideapps/docs/content/apps/google.mdx describes Google Cloud API enablement, consent screen setup, scopes, redirect URIs, credentials, and app-store seeding.
Package entrypointpackages/app-store/googlecalendar/index.ts exports api, lib, and metadata.
API handlerspackages/app-store/googlecalendar/api/index.ts exports add and callback.
OAuth callback pathThe documented integration redirect path is /api/integrations/googlecalendar/callback.
App-store refreshThe documented command after adding credentials is pnpm db-seed.

Execution Flow

A successful setup normally follows a predictable sequence. First, enable the Google Calendar API and prepare the OAuth consent screen with the requested Calendar scopes. Second, create web application credentials with both Cal.diy redirect URIs. Third, download the OAuth JSON and place it in the two environment files named by the documentation. Fourth, disable Google login if you want the calendar app to remain internal rather than opening Google authentication. Finally, repopulate the app store so the Google Calendar app appears with the newly available credentials.

Sources: apps/docs/content/apps/google.mdx

When testing the integration, use a Google account that was added as a test user during consent-screen setup if the OAuth app has not been published more broadly. Then open Cal.diy, find Google Calendar in the app store or relevant settings area, and start the add flow. The exported add handler initiates the provider authorization process, while the exported callback handler receives Google’s redirect. If the callback fails, re-check the exact URL registered in Google Cloud, the public base URL of the deployment, and whether the credentials JSON was copied without truncation.

Sources: apps/docs/content/apps/google.mdx, packages/app-store/googlecalendar/api/index.ts

Operational Notes and Next Steps

The most common mistakes are environment drift and redirect mismatch. Environment drift happens when the downloaded OAuth JSON is pasted into only one of the required files, or when processes are not restarted after editing configuration. Redirect mismatch happens when Google Cloud contains a localhost, HTTP, internal container, or old domain value while users reach Cal.diy through a different public URL. Because Google compares redirect URIs exactly, even a scheme or hostname mismatch can prevent the callback from completing.

Sources: apps/docs/content/apps/google.mdx

After Google Calendar is working, review the broader apps documentation for other providers that use similar OAuth callback patterns, such as Microsoft Calendar or Zoho Calendar. For implementation work, inspect the Google Calendar app-store package through its public barrel exports rather than importing private files directly. For deployment work, pair this page with environment and URL guidance, because OAuth integrations are tightly coupled to the externally visible Cal.diy URL and to the way the instance is served behind proxies or platform routers.