Skip to content

[codex] add local google watch tunnel support#1672

Merged
Uarmagan merged 13 commits intomainfrom
feature/add-gcal-webhook-tunnel
Apr 24, 2026
Merged

[codex] add local google watch tunnel support#1672
Uarmagan merged 13 commits intomainfrom
feature/add-gcal-webhook-tunnel

Conversation

@Uarmagan
Copy link
Copy Markdown
Contributor

@Uarmagan Uarmagan commented Apr 24, 2026

Summary

This PR adds support for testing Google Calendar Watch webhooks from a local Compass backend without forcing the whole app to use a public tunnel.

Before this change, Google Watch callbacks were tied to BASEURL. That worked for production, but it made local end-to-end webhook testing awkward: setting BASEURL to a public HTTPS tunnel also pushed browser API calls and Server-Sent Events through that tunnel. With this change, Compass can keep normal app traffic on localhost while giving Google a separate public HTTPS callback URL.

What Changed

Local Google Watch tunnel support

  • Added a new optional backend setting, GCAL_WEBHOOK_BASEURL.
  • Google Calendar Watch callback addresses now use GCAL_WEBHOOK_BASEURL when it is set.
  • If GCAL_WEBHOOK_BASEURL is not set, Compass falls back to the existing BASEURL behavior.
  • This lets local developers run the backend at http://localhost:3000/api while exposing only Google webhook callbacks through a temporary HTTPS tunnel such as Cloudflare Tunnel.

Safer Google webhook validation

  • The backend now validates that GCAL_WEBHOOK_BASEURL, when provided, is HTTPS.
  • Google credentials can still be omitted for password-only development.
  • When Google is configured and the effective webhook URL is HTTPS, Compass requires TOKEN_GCAL_NOTIFICATION so webhook notifications can be validated.
  • The validation language now refers to the effective Google webhook URL instead of only BASEURL.

Watch creation and callback routing

  • Calendar and event watch setup now build Google callback addresses from the effective webhook URL.
  • The sync flow decides whether to create Google watches based on the effective webhook URL, not just BASEURL.
  • Incremental import watch setup uses the same HTTPS decision, so local HTTP development can still complete imports without trying to create unreachable Google watches.
  • Watch startup now handles missing Google watch resource IDs explicitly instead of assuming Google always returns them.

Google connection health behavior

  • Google connection health now treats missing active watches differently depending on whether webhook callbacks are actually enabled.
  • In local HTTP mode, a connected account can remain healthy without active Google watches because live webhooks are intentionally skipped.
  • When the effective webhook URL is HTTPS, missing watches still surface as needing attention.

Config endpoint cleanup

  • Moved /api/config into a dedicated config route/controller instead of defining it inline in the Express server setup.
  • The config endpoint continues to report whether Google is configured on the backend.

Documentation and local setup guidance

  • Updated local development docs to explain the difference between Google OAuth and Google Calendar Watch callbacks.
  • Documented the Cloudflare Tunnel workflow for local end-to-end Google Watch testing.
  • Updated .env.local.example with GCAL_WEBHOOK_BASEURL guidance and warnings about keeping normal app traffic on localhost.
  • Updated self-hosting notes to explain when production can rely on BASEURL and when local development should use the separate webhook URL.

Changelog Notes

  • Developers can now test Google Calendar live sync callbacks locally by setting GCAL_WEBHOOK_BASEURL to a temporary public HTTPS tunnel while leaving BASEURL pointed at localhost.
  • Local Google sign-in and calendar import remain usable even when live Google Watch webhooks are skipped.
  • Google watch health checks now reflect whether webhook support is actually enabled for the current environment.
  • The old ngrok-specific local tunnel support has been replaced with a provider-neutral webhook URL setting.

Test Plan

  • bun run test:backend -- env.constants
  • bun run test:backend -- gcal.service
  • bun run test:backend -- sync.service
  • bun run test:backend -- user-metadata.service
  • bun run test:backend
  • bun run lint

Uarmagan added 12 commits April 24, 2026 09:50
…/add-gcal-webhook-tunnel

# Conflicts:
#	docs/development/local-development.md
#	docs/self-hosting.md
#	packages/backend/.env.local.example
#	packages/backend/src/common/constants/env.constants.test.ts
#	packages/backend/src/common/constants/env.constants.ts
#	packages/backend/src/common/middleware/supertokens.middleware.ts
#	packages/backend/src/common/services/gcal/gcal.service.ts
#	packages/backend/src/servers/express/express.server.ts
#	packages/backend/src/sync/services/sync.service.test.ts
#	packages/backend/src/sync/services/sync.service.ts
#	packages/backend/src/sync/util/sync.util.ts
#	packages/web/build.ts
#	packages/web/dev.ts
#	packages/web/src/auth/google/hooks/useIsGoogleAvailable/useIsGoogleAvailable.ts
#	packages/web/src/views/CmdPalette/CmdPalette.tsx
#	packages/web/src/views/Day/components/DayCmdPalette.tsx
#	packages/web/src/views/Now/components/NowCmdPalette.tsx
@Uarmagan Uarmagan marked this pull request as ready for review April 24, 2026 18:20
@Uarmagan Uarmagan merged commit 53df203 into main Apr 24, 2026
8 checks passed
@Uarmagan Uarmagan deleted the feature/add-gcal-webhook-tunnel branch April 24, 2026 18:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant