Skill: danielkillenberger/gcal-oauth-bridge (version 1.0.3)

--- name: calendar-bridge description: Interact with the Calendar Bridge — a self-hosted Node.js service that provides a persistent REST API for Google Calendar events. Handles OAuth token auto-refresh so you never have to re-authenticate. Use when checking upcoming events, listing calendars, setting up Google Calendar access, or troubleshooting calendar auth. homepage: https://github.com/DanielKillenberger/gcal-oauth-bridge version: 1.0.2 read_when: - User asks about upcoming events or calendar - User asks what's scheduled or what meetings they have - Calendar Bridge setup or troubleshooting needed metadata: { "openclaw": { "emoji": "📅", "requires": { "env": ["GOOGLE_CLIENT_ID", "GOOGLE_CLIENT_SECRET"] }, "optional": { "env": ["CALENDAR_BRIDGE_API_KEY"] }, "notes": "GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET are required for initial OAuth setup only — once authenticated, the agent only needs network access to localhost:3000. CALENDAR_BRIDGE_API_KEY is optional; if set, the agent must send it as Authorization: Bearer <key> when calling /events. Tokens stored locally in tokens.json on your server, never sent externally." } } triggers: - what's on my calendar - upcoming events - check my calendar - do I have anything scheduled - what meetings do I have - calendar today - calendar this week - calendar next week - list my calendars - google calendar - calendar bridge - set up calendar - calendar auth - calendar access - calendar not working --- # Calendar Bridge Skill Use this skill to interact with the Calendar Bridge service — a local REST API that wraps Google Calendar OAuth with persistent token storage and auto-refresh. **GitHub:** https://github.com/DanielKillenberger/gcal-oauth-bridge ## What is Calendar Bridge? A tiny Node.js/Express service running at `http://localhost:3000` that: - Handles Google Calendar OAuth once via browser - Stores and auto-refreshes tokens (solves the "token expired every 7 days" problem) - Exposes a dead-simple REST API for events, calendars, and auth ## API Endpoints | Endpoint | Description | |----------|-------------| | `GET /health` | Service status + auth state | | `GET /auth/url` | Get OAuth consent URL | | `GET /events?days=7` | Upcoming events from primary calendar | | `GET /events?days=7&calendar=all` | Events from ALL calendars | | `GET /events?days=7&calendar=<id>` | Events from a specific calendar | | `GET /calendars` | List all available calendars | | `POST /auth/refresh` | Force token refresh (normally automatic) | Events response includes: `id`, `summary`, `start`, `end`, `location`, `description`, `htmlLink`, `status`, `calendarId`, `calendarSummary` ## Checking Events ```bash # Quick event check (7 days, primary calendar) curl http://localhost:3000/events # All calendars, next 14 days curl http://localhost:3000/events?days=14&calendar=all # With API key (if CALENDAR_BRIDGE_API_KEY is configured) curl -H "Authorization: Bearer $API_KEY" http://localhost:3000/events?calendar=all ``` To call from OpenClaw/skill context (no API key needed when running on same host): ``` GET http://localhost:3000/events?calendar=all&days=7 ``` ## First-Time Setup ### 1. Clone and install ```bash git clone https://github.com/DanielKillenberger/gcal-oauth-bridge.git cd gcal-oauth-bridge npm install cp .env.example .env # Edit .env with GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET ``` ### 2. Get Google OAuth credentials - Go to https://console.cloud.google.com/apis/credentials - Create OAuth 2.0 Client ID (Desktop app) - Enable Google Calendar API - Add redirect URI: `http://localhost:3000/auth/callback` - Copy Client ID + Secret to `.env` ### 3. Start the service ```bash node app.js # or: npm start ``` ### 4. Authorize (one-time browser flow) If on a remote VPS, first tunnel port 3000: ```bash # From your local machine: ssh -L 3000:localhost:3000 your-server ``` Then: ```bash curl http://localhost:3000/auth/url # Open the returned URL in your browser # Complete Google consent → tokens saved automatically ``` Verify: ```bash curl http://localhost:3000/health # {"status":"ok","authenticated":true,"needsRefresh":false} ``` ### 5. Keep it running (systemd) ```bash systemctl --user enable calendar-bridge.service systemctl --user start calendar-bridge.service ``` ## Re-authentication If tokens are ever revoked (rare — auto-refresh prevents expiry): 1. `ssh -L 3000:localhost:3000 your-server` 2. `curl http://localhost:3000/auth/url` → open URL → complete consent 3. Done — new tokens overwrite old ones ## Troubleshooting - **`{"error":"Not authenticated"}`** → Run the OAuth setup flow above - **`401 Unauthorized`** → `CALENDAR_BRIDGE_API_KEY` is set; add `Authorization: Bearer <key>` header - **Can't reach localhost:3000** → Service not running; check `systemctl --user status calendar-bridge` - **"invalid_grant" / "token expired"** → Tokens were revoked externally; re-authenticate ## Personal Gmail Users Works with personal Gmail. Google shows an "unverified app" warning — click **Advanced → Go to [app]** to proceed. Tokens are stored locally on your server, not shared with anyone. ## Files - **GitHub repo:** https://github.com/DanielKillenberger/gcal-oauth-bridge - App: `app.js` — main Express server - Config: `.env` (from `.env.example`) - Tokens: `tokens.json` (auto-generated, gitignored, never committed)


Security scan verdicts — ClawScan: clean | static analysis: clean | VirusTotal: suspicious | SkillSpector: clean (LOW)