Skip to main content

Google Workspace Integration

Knowledge > Integrations > Google Workspace

What it is / why we use it

Google Workspace (john@churchwiseai.com) underlies several distinct integrations: Gmail and Calendar access in Claude Code sessions via MCP plugins, a Google Drive sync that mirrors the knowledge repo to Google Docs nightly, Google Calendar surfaced in the founder dashboard, and Google OAuth for ShareWiseAI's social media publishing. These are all separate OAuth flows with different scopes sharing the same Google Cloud project credentials.

Account Info

  • Google account: john@churchwiseai.com (Google Workspace)
  • Google Cloud project: Credentials stored as GOOGLE_CLIENT_ID / GOOGLE_CLIENT_SECRET
  • OAuth tokens for founder tools: Stored in founder_google_tokens Supabase table (single row, access + refresh token)
  • MCP plugins in Claude sessions: Gmail MCP currently connected to pastorjohnmoelker@gmail.com (FA-007 pending: needs re-auth to john@churchwiseai.com); Calendar MCP uses mcp__claude_ai_Google_Calendar__gcal_* tools

How Used Per Product

Product / ContextFeatureDetails
Founder dashboard (churchwiseai-web)Google Calendar tabLists events from all connected calendars; same OAuth token as Drive
Founder dashboard (churchwiseai-web)Google Drive tabBrowse My Drive, Shared Drives, search files
churchwiseai-web (cron)knowledge → Drive syncNightly at 7:30 UTC, converts YAML/Markdown to Google Docs in named Drive folders
ShareWiseAI (churchwiseai-web)Google OAuth for social postingChurches connect Google (YouTube) as a publishing destination
Claude Code sessionsGmail MCPRead/search/draft emails as john@churchwiseai.com (blocked pending FA-007)
Claude Code sessionsCalendar MCPView/create/update calendar events in sessions
All codebasesGoogle Places APIChurch location data enrichment (GOOGLE_PLACES_API_KEY)

Google Cloud Console — Authorized Redirect URIs

Dashboard: https://console.cloud.google.com/apis/credentials → OAuth 2.0 Client IDs → the client used for GOOGLE_CLIENT_ID

IMPORTANT: Google Cloud Console does NOT support wildcards for redirect URIs. Every URI must be listed explicitly. This is different from Supabase (which supports /**). Adding churchwiseai.com/** does nothing — each path must be individually registered.

Source of truth: This section IS the canonical list. If you change the Google Cloud Console, update this section in the same session. If the list and the console disagree, the console is authoritative but this doc must be corrected immediately.

Canonical Authorized Redirect URI List

# Production — Founder OAuth (Calendar + Drive)
https://churchwiseai.com/api/founder/google-auth/callback

# Production — ShareWiseAI Social OAuth (YouTube/Google)
https://churchwiseai.com/api/social/platforms/callback

# Local development — Founder OAuth
http://localhost:3002/api/founder/google-auth/callback

# Local development — ShareWiseAI Social OAuth
http://localhost:3002/api/social/platforms/callback

Total: 4 URIs

How Each URI Is Constructed (code reference)

URISource
churchwiseai.com/api/founder/google-auth/callbackGOOGLE_REDIRECT_URI env var (explicit override). Falls back to VERCEL_URL (preview deployments) or localhost:3002.
churchwiseai.com/api/social/platforms/callbackNEXT_PUBLIC_SITE_URL env var + /api/social/platforms/callback. Hardcoded to churchwiseai.com in production.

Vercel Preview Deployments

  • Founder OAuth in previews: The code falls back to https://{VERCEL_URL}/api/founder/google-auth/callback. This URI is NOT registered in Google Cloud Console — Google will reject it. Founder OAuth does not work on Vercel preview deployments unless the specific preview URL is manually added. This is acceptable (founder auth is not tested in previews).
  • Social OAuth in previews: Uses NEXT_PUBLIC_SITE_URL which is https://churchwiseai.com — redirects to production callback. Social OAuth in preview deployments always routes through production.

Adding New Redirect URIs

When a new OAuth flow is added (new property, new callback path):

  1. Add the URI to Google Cloud Console → Credentials → OAuth 2.0 Client → Authorized redirect URIs
  2. Add to the canonical list above
  3. Update last-verified date below

OAuth Flows — Two Distinct Flows

1. Founder OAuth (Calendar + Drive)

Used by the founder dashboard and the nightly sync cron.

  • Initiate: GET /api/founder/google-auth?token={FOUNDER_TOKEN}
  • Scopes requested: calendar.readonly, calendar.events, drive.readonly, drive.file
  • Callback: /api/founder/google-auth/callback exchanges code for tokens, stores in founder_google_tokens
  • Token refresh: google-calendar.ts:refreshAccessToken() — automatic refresh 5 minutes before expiry, stores new access_token in Supabase
  • Login hint: john@churchwiseai.com is passed as login_hint to prevent wrong-account selection
  • Prompt: consent (forces consent screen to obtain refresh_token every time)

2. ShareWiseAI Social OAuth

Used by church admins to connect Google/YouTube for social posting.

  • Initiate: GET /api/social/platforms/connect — generates authorization URL with PKCE nonce
  • Nonce storage: social_oauth_nonces table in Supabase (prevents CSRF)
  • Callback: /api/social/platforms/callback — exchanges code, stores encrypted tokens for the church's social account
  • Token refresh: /api/social/cron/token-refresh — cron job refreshes expiring social platform tokens
  • Shares GOOGLE_CLIENT_ID/GOOGLE_CLIENT_SECRET with the founder OAuth flow (same Google Cloud project)

Knowledge → Drive Sync (Nightly Cron)

Route: churchwiseai-web/src/app/api/founder/sync-knowledge/route.ts Schedule: 7:30 UTC daily (see vercel.json) Auth: Vercel Cron header (Authorization: Bearer {CRON_SECRET}) or ?token={FOUNDER_TOKEN} Max duration: 300 seconds (Vercel serverless limit override)

Source: Fetches files from the ChurchWiseAI/knowledge GitHub repo via GITHUB_TOKEN (fine-grained PAT, read access)

Sync map (source → Drive folder → title):

SourceDrive FolderDoc Title
data/pricing.yamlPricingChurchWiseAI Pricing Guide
data/features.yamlProductsProduct Feature Matrix
data/products.yamlProductsProduct Portfolio Overview
data/policies.yamlLegalPolicies & Terms Summary
narrative/vision.mdCompanyCompany Vision & Mission
narrative/strategy.mdRoadmapGo-to-Market Strategy
narrative/brand.mdBrandBrand Guidelines
narrative/competitive.mdCompetitiveCompetitive Positioning
narrative/sales-playbook.mdSalesSales Demo Playbook
narrative/customer-journey.mdSalesCustomer Journey Map
narrative/operations.mdSOPsOperations Guide

Behavior: Upsert — finds existing Google Doc by name within the target folder, updates it if found, creates if not. Folders must be created manually in Drive first (the sync does not create folders). If a folder is missing, that entry fails with an error in the response.

Duplicate converter note: The markdown-to-HTML converter in the route is a standalone copy of knowledge/scripts/derive-gdrive.ts. If you update conversion logic, update both files.

Key Environment Variables

VariableUsed InPurpose
GOOGLE_CLIENT_IDchurchwiseai-webOAuth client ID (shared by founder tools and ShareWiseAI)
GOOGLE_CLIENT_SECRETchurchwiseai-webOAuth client secret
GOOGLE_REDIRECT_URIchurchwiseai-webOverride for founder OAuth callback URI (defaults to Vercel URL)
GOOGLE_PLACES_API_KEYchurchwiseai-webGoogle Places API for church location data
GITHUB_TOKENchurchwiseai-webFine-grained PAT (read-only) for fetching ChurchWiseAI/knowledge repo files
CRON_SECRETchurchwiseai-webAuthenticates the Vercel cron invocation of the sync route
FOUNDER_TOKENchurchwiseai-webManual trigger auth for sync and OAuth initiation

CLI / API Patterns & Gotchas

No googleapis npm package: Both google-calendar.ts and google-drive.ts use raw fetch() against the REST API. No googleapis or google-auth-library npm packages. This keeps the bundle lean and avoids Node.js-specific imports that fail in edge runtimes.

Token storage in Supabase: Tokens are stored in founder_google_tokens (single row). There is no multi-user OAuth for the founder tools — it's always john@churchwiseai.com.

401 detection for Drive: google-drive.ts has a throwIf401 helper that checks for expired tokens and throws a clear, actionable error message directing the founder to reconnect from the Calendar settings tab. This surfaces in the cron response JSON when tokens are stale.

MCP plugins vs. HTTP API:

  • The Claude Code session MCP plugins (mcp__claude_ai_Google_Calendar__*) are separate from the HTTP API used by the founder dashboard. They use different OAuth credentials managed by Anthropic's MCP infrastructure.
  • The founder dashboard uses the Google Calendar REST API directly via google-calendar.ts with tokens stored in Supabase.
  • Do not confuse the two. The MCP tools are for agent-to-founder communication in sessions; the dashboard is for the founder's operational use.

GWS CLI: The GWS CLI is available in Claude Code sessions for managing Google Workspace administrative tasks as john@churchwiseai.com. Use for: user management, domain settings, group management. Not used in any codebase.

ShareWiseAI social OAuth encrypted tokens: Social platform tokens (including Google/YouTube) are encrypted before storage using social-crypto.ts. The encryption key is SOCIAL_TOKEN_ENCRYPTION_KEY. Never store these as plaintext.

Failure Modes & Recovery

FailureBehaviorRecovery
founder_google_tokens has no rowSync returns 500 with "Google Drive not connected"Re-run OAuth flow: visit /api/founder/google-auth?token={FOUNDER_TOKEN}
Access token expired (401)throwIf401 throws clear error in syncToken refreshes automatically if refresh token valid; else re-run OAuth
Refresh token revokedCan't auto-refresh; 401 on all Drive callsRe-run OAuth consent flow (always requests prompt: consent to get new refresh token)
Drive folder missingThat sync entry fails; others succeedCreate the missing folder in Drive manually, then re-trigger sync
GITHUB_TOKEN not set or expiredSync returns 500 immediatelyUpdate PAT in Vercel env vars; fine-grained PAT needs contents: read on ChurchWiseAI/knowledge
MCP Gmail connected to wrong accountGmail MCP reads personal inbox, not business inboxRe-authorize MCP to john@churchwiseai.com (FA-007)
ShareWiseAI social token expiredPublishing fails silentlyToken refresh cron runs nightly; manual retry via refresh endpoint

Cost Model / Usage Limits

  • Google Calendar/Drive API: Free within Google Workspace quota. Calendar: 1,000,000 requests/day. Drive: 1,000,000,000 bytes/day upload. Both are well within range for a solo founder dashboard.
  • Google Places API: Billed per request ($5/1,000 for standard lookup). Used for church location enrichment. Monitor usage in Google Cloud Console.
  • Google Cloud OAuth: Free. No per-request cost.
  • Workspace plan: John@churchwiseai.com is on Google Workspace (Business Starter or higher). Standard costs apply.

See Also

  • Cal.com Integration — Cal.com bookings appear in Google Calendar; founder calendar shows Cal.com entries
  • Vercel Integration — Vercel Cron triggers the knowledge sync route
  • churchwiseai-web/src/lib/google-calendar.ts — Calendar API wrapper
  • churchwiseai-web/src/lib/google-drive.ts — Drive API wrapper
  • churchwiseai-web/src/app/api/founder/sync-knowledge/route.ts — Nightly cron