Skip to content

feat(google-calendar): wire freebusy, align tools with API v3, add calendar + sharing tools#5084

Merged
waleedlatif1 merged 6 commits into
stagingfrom
validate/google-calendar
Jun 16, 2026
Merged

feat(google-calendar): wire freebusy, align tools with API v3, add calendar + sharing tools#5084
waleedlatif1 merged 6 commits into
stagingfrom
validate/google-calendar

Conversation

@waleedlatif1

Copy link
Copy Markdown
Collaborator

Summary

  • Wired the existing freebusy tool into the Google Calendar block (operation, tools.access for both block versions, tool switch, subBlocks) — it was registered but unreachable from the UI
  • Aligned all existing tools 100% with the Google Calendar API v3 docs; fixed the update attendee-clear footgun, consistent timezone handling, and removed any usage
  • Added list free-text search (q), maxResults, and pageToken (pagination was a dead-end — nextPageToken was returned but unusable); default ordering by start time
  • Added all-day events, recurrence (RRULE), and Google Meet conferencing to create and update; surfaced hangoutLink/recurrence outputs
  • Added four new tools (v1 + v2): create_calendar, share_calendar, list_acl, unshare_calendar
  • No new OAuth scopes — every new tool is authorized by the existing auth/calendar scope
  • Fixed registry alphabetical ordering for the freebusy entries
  • Regenerated integration docs

Type of Change

  • New feature
  • Bug fix

Backwards Compatibility

  • Fully backwards compatible — all pre-existing operations resolve to the same tool IDs with their original subBlocks/conditions intact; all changes are additive except for bug fixes

Testing

Tested manually; bun run lint, typecheck, and bun run check:api-validation all pass

Checklist

  • Code follows project style guidelines
  • Self-reviewed my changes
  • Tests added/updated and passing
  • No new warnings introduced
  • I confirm that I have read and agree to the terms outlined in the Contributor License Agreement (CLA)

@vercel

vercel Bot commented Jun 16, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
docs Skipped Skipped Jun 16, 2026 3:14am

Request Review

@cursor

cursor Bot commented Jun 16, 2026

Copy link
Copy Markdown

PR Summary

Medium Risk
Calendar ACL share/unshare and attendee/update semantics can change real calendars and notifications; behavior fixes on update are intentional but worth spot-checking existing workflows.

Overview
Expands the Google Calendar block and tools so workflows can reach free/busy, calendar lifecycle, and sharing (ACL) operations that were missing or only registered in the registry, and tightens event create/update behavior against Calendar API v3.

New block operations & tools (v1 + v2): Check Free/Busy, Create Calendar, Share Calendar, List Sharing, Remove Sharing—wired through google_calendar / google_calendar_v2 subBlocks, tool routing, registry, and integration metadata/docs.

Event create/update: Shared utils for all-day vs timed datetimes, attendee/recurrence normalization, recurring timeZone validation, and optional Google Meet (conferenceDataVersion + hangoutLink outputs). List events gains q, maxResults, pageToken, and default orderBy=startTime.

Fixes / refactors: Update only sends attendees when the list is non-empty (avoids clearing invitees); invite logic consolidated into inviteAttendees; stricter typing on v2 responses; registry ordering for freebusy entries.

Reviewed by Cursor Bugbot for commit 56099ce. Configure here.

Comment thread apps/sim/tools/google_calendar/utils.ts
@greptile-apps

greptile-apps Bot commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR wires the previously unreachable freebusy tool into the Google Calendar block, aligns all tools with Calendar API v3, and adds four new calendar-management tools (create_calendar, share_calendar, list_acl, unshare_calendar) in both v1 and v2 variants. The changes are fully backwards-compatible — existing operations resolve to the same tool IDs with their original subBlocks intact.

  • Extracted shared logic (buildEventDateTime, normalizeAttendees, normalizeRecurrence, assertRecurringTimeZone, buildGoogleMeetConferenceData) into utils.ts, used consistently across create.ts and update.ts.
  • Added all-day event support, RFC 5545 recurrence (RRULE), and Google Meet conferencing to create/update; the invite.ts attendee-merge logic was refactored into a standalone inviteAttendees helper that issues an explicit PUT after a GET, with proper putResponse.ok checking.
  • All four new tools follow the existing v1/v2 tool pattern (shared oauth/params/request, separate transformResponse and outputs per version), are registered in index.ts and registry.ts, and are correctly wired into both GoogleCalendarBlock and GoogleCalendarV2Block including the versioned tool selector.

Confidence Score: 5/5

Safe to merge — all changes are additive, backwards-compatible, and follow the existing tool/block patterns precisely.

The PR wires five previously unreachable or missing operations into a well-tested integration. The framework's response.ok gate in tools/index.ts correctly guards transformResponse for all new tools; the only DELETE tool (unshare_calendar) handles the 204 No-Content case explicitly. Shared utilities in utils.ts replace scattered inline logic with clearly documented, tested helpers. The two-step invite refactoring is safe because the inner fetch checks putResponse.ok before proceeding, and any thrown error is caught by the framework catch block. No schema changes, no new OAuth scopes, and all pre-existing operations continue to resolve to identical tool IDs.

No files require special attention. All changed files follow the established tool/block conventions.

Important Files Changed

Filename Overview
apps/sim/tools/google_calendar/utils.ts New shared utility module; well-documented helpers for event datetime, attendees, recurrence, Meet conferencing, and the recurring-event timezone assertion that replaces an earlier footgun.
apps/sim/tools/google_calendar/create.ts Migrated to shared utils; adds recurrence, all-day events, Google Meet; conferenceDataVersion=1 is correctly gate-kept behind addGoogleMeet in both the URL and body.
apps/sim/tools/google_calendar/update.ts Aligned to API v3 via shared utils; the recurring-event timezone assertion fires only when new recurrence rules are supplied, which is the correct scope for a PATCH operation.
apps/sim/tools/google_calendar/invite.ts Substantially refactored into a two-step GET→PUT helper; framework ensures response.ok before transformResponse is called, and the inner PUT explicitly checks putResponse.ok before proceeding.
apps/sim/tools/google_calendar/create_calendar.ts New tool; clean v1/v2 implementation; body correctly builds only the four calendar fields that the API accepts.
apps/sim/tools/google_calendar/share_calendar.ts New tool; buildAclBody validates that scopeValue is non-empty for non-default scope types and throws early; sendNotifications is correctly appended as a query param.
apps/sim/tools/google_calendar/list_acl.ts New tool; showDeleted correctly changed to user-only (per prior review); items
apps/sim/tools/google_calendar/unshare_calendar.ts New tool; DELETE correctly checks response.ok / 204 status; JSON parse error is caught with .catch(() => null) (prior review fix applied).
apps/sim/blocks/blocks/google_calendar.ts Five new operations wired to both the legacy block and V2 block; calendarId picker correctly excluded for list_calendars, create_calendar, and freebusy; all new V2 outputs declared.
apps/sim/tools/google_calendar/list.ts Adds q, maxResults, pageToken, orderBy params; orderBy defaults to startTime which is valid because singleEvents=true is always appended.
apps/sim/tools/google_calendar/types.ts New param/response interfaces for all four new tools; GoogleCalendarToolParams and GoogleCalendarResponse union types updated consistently.
apps/sim/tools/google_calendar/index.ts All eight new tools (v1 and v2 for each of the four new operations) correctly re-exported with consistent naming.
apps/sim/tools/registry.ts New tools registered in the central registry; freebusy entries moved to correct alphabetical order per PR description.

Sequence Diagram

%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
    participant UI as Block UI
    participant F as Framework (tools/index.ts)
    participant GC as Google Calendar API

    Note over UI,GC: create / update / list (existing, now enhanced)
    UI->>F: operation + params
    F->>GC: "POST/PATCH/GET (with conferenceDataVersion=1 if addGoogleMeet)"
    GC-->>F: 200 JSON (hangoutLink, recurrence included)
    F->>F: transformResponse(response, params)
    F-->>UI: "{id, htmlLink, hangoutLink?, recurrence?}"

    Note over UI,GC: invite (two-step, refactored)
    UI->>F: eventId + attendees
    F->>GC: "GET /calendars/{id}/events/{eventId}"
    GC-->>F: 200 existing event
    F->>GC: "PUT /calendars/{id}/events/{eventId}?sendUpdates=all"
    GC-->>F: 200 updated event
    F-->>UI: "{id, attendees, ...}"

    Note over UI,GC: new — freebusy (now reachable)
    UI->>F: calendarIds + timeMin + timeMax
    F->>GC: POST /freeBusy
    GC-->>F: "200 {calendars: {id: {busy: [...]}}}"
    F-->>UI: "{timeMin, timeMax, calendars}"

    Note over UI,GC: new — create_calendar / share_calendar / list_acl / unshare_calendar
    UI->>F: summary / role+scope / calendarId / ruleId
    F->>GC: "POST /calendars or POST/GET/DELETE /calendars/{id}/acl"
    GC-->>F: 200 or 204
    F-->>UI: "id / role+scope / rules[] / {ruleId, deleted}"
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
    participant UI as Block UI
    participant F as Framework (tools/index.ts)
    participant GC as Google Calendar API

    Note over UI,GC: create / update / list (existing, now enhanced)
    UI->>F: operation + params
    F->>GC: "POST/PATCH/GET (with conferenceDataVersion=1 if addGoogleMeet)"
    GC-->>F: 200 JSON (hangoutLink, recurrence included)
    F->>F: transformResponse(response, params)
    F-->>UI: "{id, htmlLink, hangoutLink?, recurrence?}"

    Note over UI,GC: invite (two-step, refactored)
    UI->>F: eventId + attendees
    F->>GC: "GET /calendars/{id}/events/{eventId}"
    GC-->>F: 200 existing event
    F->>GC: "PUT /calendars/{id}/events/{eventId}?sendUpdates=all"
    GC-->>F: 200 updated event
    F-->>UI: "{id, attendees, ...}"

    Note over UI,GC: new — freebusy (now reachable)
    UI->>F: calendarIds + timeMin + timeMax
    F->>GC: POST /freeBusy
    GC-->>F: "200 {calendars: {id: {busy: [...]}}}"
    F-->>UI: "{timeMin, timeMax, calendars}"

    Note over UI,GC: new — create_calendar / share_calendar / list_acl / unshare_calendar
    UI->>F: summary / role+scope / calendarId / ruleId
    F->>GC: "POST /calendars or POST/GET/DELETE /calendars/{id}/acl"
    GC-->>F: 200 or 204
    F-->>UI: "id / role+scope / rules[] / {ruleId, deleted}"
Loading

Reviews (6): Last reviewed commit: "fix(google-calendar): validate grantee b..." | Re-trigger Greptile

Comment thread apps/sim/tools/google_calendar/list_acl.ts
Comment thread apps/sim/tools/google_calendar/unshare_calendar.ts Outdated
Comment thread apps/sim/tools/google_calendar/update.ts
Comment thread apps/sim/tools/google_calendar/utils.ts Outdated
…ist_acl showDeleted usable, harden unshare error parse, clarify update attendees
@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile review

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cursor review

Comment thread apps/sim/tools/google_calendar/invite.ts Outdated
Comment thread apps/sim/blocks/blocks/google_calendar.ts
Comment thread apps/sim/blocks/blocks/google_calendar.ts
@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile review

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cursor review

Comment thread apps/sim/tools/google_calendar/list.ts
Comment thread apps/sim/tools/google_calendar/update.ts
@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile review

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cursor review

Comment thread apps/sim/tools/google_calendar/create.ts
Comment thread apps/sim/tools/google_calendar/update.ts
@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile review

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cursor review

Comment thread apps/sim/tools/google_calendar/share_calendar.ts
Throw a clear error when scopeType is user/group/domain but scopeValue is
missing or blank, instead of POSTing a scope-type-only body that the Calendar
ACL API rejects with an opaque error.
@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cursor review

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit 56099ce. Configure here.

@waleedlatif1 waleedlatif1 merged commit b7d30c8 into staging Jun 16, 2026
16 checks passed
@waleedlatif1 waleedlatif1 deleted the validate/google-calendar branch June 16, 2026 03:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant