Google Calendar Sync

Duet can sync todos with due dates to Google Calendar, giving you a unified view of your schedule. Agent-created events are automatically flagged so you know where they came from.

Features

  • Two-way sync - changes in Duet update your calendar, and vice versa.
  • Agent-created events flagged - events created by agents are labeled so you can distinguish them from your own.
  • Automatic sync - whenever a todo with a due date is created or updated, the calendar syncs automatically.
  • Manual sync - trigger a sync at any time from settings or via the API.

Step 1: Create a Google Cloud Project

  1. Go to the Google Cloud Console.
  2. Click Select a project at the top, then New Project.
  3. Name it something like "Duet Calendar" and click Create.
  4. Select your new project from the project picker.

Step 2: Enable the Google Calendar API

  1. In the Cloud Console, go to APIs & Services > Library.
  2. Search for Google Calendar API.
  3. Click on it and press Enable.

Step 3: Create OAuth 2.0 Credentials

  1. Go to APIs & Services > Credentials.
  2. Click Create Credentials > OAuth client ID.
  3. If prompted, configure the OAuth consent screen first:
    • User Type: External (or Internal if using Google Workspace)
    • Fill in the required fields (app name, support email)
    • Add the scope: https://www.googleapis.com/auth/calendar
    • Add your email as a test user
  4. For Application type, select Web application.
  5. Name it "Duet".
  6. Under Authorized redirect URIs, add your callback URL:
# For local development:
http://localhost:7777/api/calendar/callback

# For production (replace with your domain):
https://your-domain.com/api/calendar/callback
  1. Click Create and note down your Client ID and Client Secret.

Step 4: Configure Environment Variables

Add the OAuth credentials to your Duet environment:

# In your .env file or environment:
GOOGLE_CLIENT_ID=your-client-id.apps.googleusercontent.com
GOOGLE_CLIENT_SECRET=your-client-secret

If you're using Docker, add these to your .env file. If deployed to Fly.io, use fly secrets set.

# Fly.io
fly secrets set GOOGLE_CLIENT_ID=your-client-id.apps.googleusercontent.com
fly secrets set GOOGLE_CLIENT_SECRET=your-client-secret

Step 5: Connect in Duet

  1. Open Duet in your browser.
  2. Go to Settings.
  3. In the Google Calendar section, click Connect Google Calendar.
  4. You'll be redirected to Google to authorize access.
  5. Grant Duet permission to manage your calendar events.
  6. You'll be redirected back to Duet. The connection status should show as connected.

How Sync Works

  • When you create or update a todo with a due date, a corresponding calendar event is created or updated automatically.
  • When you mark a todo as done, the calendar event is updated to reflect completion.
  • Events created by agents include an [Agent] prefix in the event title so they stand out.
  • Deleting a todo removes its associated calendar event.

API Endpoints

You can also manage the calendar integration via the API:

EndpointDescription
GET /api/calendar/auth-urlGet the OAuth authorization URL
GET /api/calendar/callbackOAuth callback (redirect target)
GET /api/calendar/statusCheck if calendar is connected
POST /api/calendar/syncTrigger a manual sync
POST /api/calendar/disconnectDisconnect Google Calendar
# Check connection status
curl http://localhost:7777/api/calendar/status -b cookies.txt

# Trigger a manual sync
curl -X POST http://localhost:7777/api/calendar/sync -b cookies.txt

Troubleshooting

  • OAuth error: redirect_uri_mismatch - make sure the redirect URI in your Google Cloud Console exactly matches your Duet callback URL, including the protocol and port.
  • Events not appearing - verify the todo has a due date set. Only todos with due dates are synced to the calendar.
  • Token expired - Duet automatically refreshes OAuth tokens. If issues persist, disconnect and reconnect the calendar from Settings.
  • Test user restriction - if your OAuth consent screen is in "Testing" mode, only users added as test users can authorize the app. Add your Google account as a test user or publish the app.