setup-guides

Google Calendar Integration Setup

How to wire up the Google Calendar OAuth credentials so users can connect their personal calendar to HiveJournal Tasks.

What it does

When a user connects their Google Calendar:

  • Tasks with a due_date automatically sync as all-day events on their primary calendar
  • Updating the task title/description/date/status updates the calendar event
  • Marking a task done prefixes the event with "✓"
  • Deleting the task deletes the event
  • The user's tasks page shows their upcoming calendar events for the next 7 days

The integration only requests the calendar.events scope — read/write events on calendars the user owns. It does not request access to other calendars, contacts, or any other Google data.

Google Cloud Console steps (one-time)

1. Create or pick a project

  1. Go to console.cloud.google.com
  2. Either create a new project ("HiveJournal" works) or select an existing one
  3. Note the project ID

2. Enable the Google Calendar API

  1. In the left sidebar, APIs & Services → Library
  2. Search for "Google Calendar API"
  3. Click it, then click Enable
  1. APIs & Services → OAuth consent screen
  2. User Type: External (unless you have Google Workspace)
  3. Fill in:
    • App name: HiveJournal
    • User support email: your email
    • App logo: optional, upload the HiveJournal logo
    • App domain: hivejournal.com
    • Authorized domains: hivejournal.com
    • Developer contact email: your email
  4. Scopes — click Add or Remove Scopes and add:
    • https://www.googleapis.com/auth/calendar.events
    • https://www.googleapis.com/auth/userinfo.email
  5. Test users — for now, add yourself and any test accounts. (When you submit for verification later, this becomes public.)
  6. Save

4. Create OAuth 2.0 credentials

  1. APIs & Services → Credentials → Create Credentials → OAuth client ID
  2. Application type: Web application
  3. Name: "HiveJournal Backend"
  4. Authorized redirect URIs — add ALL of these:
    • http://localhost:3001/api/google-calendar/callback (local dev)
    • https://hivejournalbackend-production.up.railway.app/api/google-calendar/callback (production)
  5. Click Create
  6. Copy the Client ID and Client Secret that appear in the modal

5. Set the env vars

In Railway (production backend), add:

KeyValue
GOOGLE_OAUTH_CLIENT_IDthe Client ID from step 4
GOOGLE_OAUTH_CLIENT_SECRETthe Client Secret from step 4
GOOGLE_OAUTH_REDIRECT_URIhttps://hivejournalbackend-production.up.railway.app/api/google-calendar/callback
NEXT_PUBLIC_APP_URLhttps://hivejournal.com (used to redirect back after OAuth)

For local development, add the same vars to apps/backend/.env:

GOOGLE_OAUTH_CLIENT_ID=your-client-id
GOOGLE_OAUTH_CLIENT_SECRET=your-client-secret
GOOGLE_OAUTH_REDIRECT_URI=http://localhost:3001/api/google-calendar/callback
NEXT_PUBLIC_APP_URL=http://localhost:3000

6. Apply migration 063

In Supabase SQL editor, paste the contents of supabase/migrations/063_google_calendar.sql and run it.

7. Test it

  1. Sign in to HiveJournal
  2. Go to /dashboard/tasks
  3. Click "Connect Google Calendar"
  4. You'll be redirected to Google's consent screen, accept
  5. Back on the tasks page, you should see "Connected as your-email@gmail.com"
  6. Add a task with "tomorrow" in it via JQ or the quick-add box
  7. Open Google Calendar — the task should appear as an all-day event tomorrow

Going public (later)

While in Testing mode, only the test users you added in step 3 can connect. To allow any user to connect, you need to submit the OAuth consent screen for verification:

  1. Go back to the consent screen page
  2. Click Publish App
  3. For non-sensitive scopes (which calendar.events is not — it's restricted), Google requires a security review. Expect a few weeks of back-and-forth and possibly a CASA (Cloud Application Security Assessment) requirement.
  4. While verification is pending, the consent screen will show a warning to users — they can still proceed by clicking "Advanced → Go to HiveJournal (unsafe)".

For now, while the user base is small, leaving it in Testing mode and adding new users to the test list manually is fine.

API reference

All endpoints require authentication (Bearer token).

MethodPathDescription
GET/api/google-calendar/connectReturns the OAuth consent URL for the frontend to redirect to
GET/api/google-calendar/callbackGoogle redirects here after consent (not called directly by clients)
GET/api/google-calendar/statusReturns { connected: boolean, google_email?: string }
POST/api/google-calendar/disconnectRevokes the token at Google and deletes the connection
GET/api/google-calendar/events?from=ISO&to=ISO&limit=NLists events in the time range
POST/api/google-calendar/eventsCreates an event manually (used by JQ)

Auto-sync behavior

The auto-sync hooks in apps/backend/src/routes/user-tasks.ts are best-effort and never block task operations:

  • Create task with due_date → creates a calendar event, stores google_event_id on the task row
  • Update task (title, description, due_date, status) → updates the matching event
  • Clear due_date → deletes the event
  • Delete task → deletes the event

If the user is not connected, the sync is a no-op. If the API call fails, it's logged but doesn't fail the task operation.

GOOGLE CALENDAR SETUP — Docs | HiveJournal