- New server/google_calendar.mjs wrapping googleapis v3 with auto token refresh - Four new actions: calendar-list-events (auto-accept), calendar-create/update/delete-event (queue) - bin/ccc-gcal-auth.mjs one-time OAuth2 consent flow helper - config.example.json updated with google_calendar block - server/config.mjs, index.mjs wired up following the same pattern as SMTP/mailer - Bump version to 1.2.0 - Add CLAUDE.md and claude-info/ with architecture reference, feature plans, and contributing checklist Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
127 lines
3.6 KiB
Markdown
127 lines
3.6 KiB
Markdown
# Plan: Google Calendar integration
|
|
|
|
Status: **implemented**
|
|
|
|
## Overview
|
|
|
|
Add Google Calendar read/write support as CCC actions. Follows the same pattern as the SMTP/mail integration: credentials in config, a wrapper module, new actions in `actions.mjs`.
|
|
|
|
Listing events is `auto-accept` (read-only). All mutations are `queue` — require human approval in the TUI before executing.
|
|
|
|
---
|
|
|
|
## Step 1 — Google OAuth2 setup (one-time manual)
|
|
|
|
1. Create a Google Cloud project, enable the Calendar API
|
|
2. Create an OAuth2 credential (Desktop app type), download the JSON
|
|
3. Run `ccc-gcal-auth` (see Step 7) to do the consent flow and write `google-token.json`
|
|
4. Point config at both files (see Step 2)
|
|
|
|
---
|
|
|
|
## Step 2 — Config extension
|
|
|
|
Add to `config.json` (and `config.example.json`):
|
|
|
|
```json
|
|
"google_calendar": {
|
|
"credentials": "../google-credentials.json",
|
|
"token": "../google-token.json"
|
|
}
|
|
```
|
|
|
|
Both paths resolved relative to the config file, same as `secrets` and `mail_perms`.
|
|
|
|
---
|
|
|
|
## Step 3 — New module: `server/google_calendar.mjs`
|
|
|
|
Wraps the `googleapis` npm package. Exports:
|
|
|
|
```js
|
|
export function create_calendar_client(cfg)
|
|
```
|
|
|
|
- Loads `cfg.credentials_path` and `cfg.token_path`
|
|
- Creates an OAuth2 client
|
|
- Registers `tokens` event to persist refreshed tokens back to disk automatically
|
|
- Returns a thin wrapper with methods:
|
|
- `list_events({ calendar_id, time_min, time_max, max_results })`
|
|
- `create_event({ calendar_id, summary, start, end, description })`
|
|
- `update_event({ calendar_id, event_id, summary, start, end, description })`
|
|
- `delete_event({ calendar_id, event_id })`
|
|
|
|
`start` and `end` are ISO 8601 strings (e.g. `"2026-05-21T14:00:00+02:00"`).
|
|
|
|
---
|
|
|
|
## Step 4 — Config loader update (`server/config.mjs`)
|
|
|
|
Extend `load_config` to resolve `google_calendar.credentials` and `google_calendar.token` paths and return them (or `null` if the block is absent).
|
|
|
|
---
|
|
|
|
## Step 5 — Server wiring (`server/index.mjs`)
|
|
|
|
```js
|
|
import { create_calendar_client } from './google_calendar.mjs';
|
|
|
|
const calendar = cfg.google_calendar
|
|
? create_calendar_client(cfg.google_calendar)
|
|
: null;
|
|
|
|
// In make_ctx():
|
|
return { caller, users, mail_perm_store, exec, mailer_send, calendar };
|
|
```
|
|
|
|
---
|
|
|
|
## Step 6 — New actions (`server/actions.mjs`)
|
|
|
|
| Action | Policy | Required params | Optional params |
|
|
|---|---|---|---|
|
|
| `calendar-list-events` | `auto-accept` | — | `calendar_id` (default `primary`), `time_min`, `time_max`, `max_results` |
|
|
| `calendar-create-event` | `queue` | `summary`, `start`, `end` | `calendar_id`, `description` |
|
|
| `calendar-update-event` | `queue` | `event_id` | `calendar_id`, `summary`, `start`, `end`, `description` |
|
|
| `calendar-delete-event` | `queue` | `event_id` | `calendar_id` |
|
|
|
|
All handlers guard with:
|
|
```js
|
|
if (!ctx.calendar) { throw new Error('Google Calendar not configured'); }
|
|
```
|
|
|
|
---
|
|
|
|
## Step 7 — Auth helper: `bin/ccc-gcal-auth.mjs`
|
|
|
|
One-time setup script run on the host:
|
|
|
|
```bash
|
|
ccc-gcal-auth --credentials google-credentials.json --token google-token.json
|
|
```
|
|
|
|
- Reads the downloaded OAuth credentials JSON
|
|
- Generates an authorization URL, prints it for the user to open
|
|
- Starts a local HTTP server to receive the redirect with the auth code
|
|
- Exchanges the code for tokens and writes `google-token.json`
|
|
|
|
Add to `bin` map in `package.json`.
|
|
|
|
---
|
|
|
|
## Step 8 — Dependencies
|
|
|
|
```bash
|
|
npm install googleapis
|
|
```
|
|
|
|
Add to `package.json` dependencies.
|
|
|
|
---
|
|
|
|
## Open questions
|
|
|
|
- Token storage: separate `google-token.json` (current plan) vs folded into `secrets.json`?
|
|
- Should `calendar-create-event` be `queue` or `auto-accept`? (Currently `queue` for safety)
|
|
- Multi-calendar support needed beyond `primary`?
|