Google Calendar Integration¶
Google Calendar access via Obsidian Google Calendar plugin (stale/unmaintained) + eval_js bridge
Details¶
Google Calendar access via the Obsidian Google Calendar plugin (v1.10.16) over the eval_js bridge. This is the obsidian_bridge adapter beneath the provider-neutral calendar subsystem — see calendar for the seam (canonical models + CalendarProvider protocol + factory). Consumers depend on work_buddy.calendar.provider + work_buddy.calendar.models, not on env.py directly.
Warning¶
The Google Calendar Obsidian plugin is stale/unmaintained and could stop working at any time. It is a transitional adapter; a native own-OAuth adapter is planned to replace it and retire the bridge at read+write parity. Plan for graceful degradation.
Where it sits¶
work_buddy/calendar/providers/obsidian_bridge.py (ObsidianBridgeCalendarProvider) wraps work_buddy/calendar/env.py (Python eval_js wrappers) + _js/ (snippets executed inside Obsidian). Prerequisites: Obsidian running with the work-buddy bridge, Google Calendar plugin installed + authenticated. The adapter maps the plugin's calendar/event dicts to the canonical CalendarEvent/CalendarRef models.
Runtime API Surface¶
Plugin exposes app.plugins.plugins["google-calendar"].api with: getCalendars, getEvents (requires Moment.js dates), createEvent, updateEvent, deleteEvent, createEventNote. getEvent is broken (returns error for all events) — the adapter's get_event filters a windowed getEvents by id instead. The payload carries no iCalUID, so bridge events use the loc:<provider>:<calendar_id>:<event_id> stable key (native supplies real ical: UIDs later).
Event Object Structure¶
Google Calendar API v3 schema plus a parent field: id, summary, status, htmlLink, start/end (dateTime/date/timeZone), location, description, colorId, transparency, eventType, parent (calendar metadata).
Gateway surface¶
Reads and writes are exposed through the calendar subsystem capabilities (calendar_health, calendar_list_events, calendar_get_event, calendar_coverage, and create/update/delete_calendar_event), gated by the provider-aware calendar tool probe (not google_calendar). The write capabilities carry heavy per-change consent in capabilities.py (one layer up, so every provider inherits identical gating). env.create_event/update_event/delete_event no longer carry their own @requires_consent — the semantic gate moved up to the capability layer, and the writers now carry @reduces_risk_for("obsidian.eval_js", "low") so their internal eval_js passes without a second prompt.
Degradation¶
All functions degrade gracefully: bridge unavailable → typed CalendarBridgeUnreachable. Plugin not installed → check_ready returns {ready: false}. Not authenticated → getCalendars fails, caught and reported. Stale plugin → eval_js timeout, caught by the bridge layer. The collector falls back to a clear 'not available' report rather than crashing the morning bundle.