Skip to content

feat(google_calendar): Each user signs in, more event operations, fix log-message validation and calendar ID encoding (1.0.0) - #4173

Merged
crazywoola merged 2 commits into
langgenius:mainfrom
ForeignKeyCN:feat/google-calendar-per-user-signin
Nov 2, 2026
Merged

crazywoola merged 2 commits into
langgenius:mainfrom
ForeignKeyCN:feat/google-calendar-per-user-signin

Conversation

@ForeignKeyCN

@ForeignKeyCN ForeignKeyCN commented Nov 2, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Google Calendar 1.0.0 adds Each user signs in next to the existing OAuth credential, adds the common event operations that were missing, and fixes two bugs in the original tools. It follows the same per-user design as the Microsoft and Atlassian plugins (#4163–#4171) and is the first of the Google series.

Fixes in the original tools

  • Every call failed on recent Dify. list_calendars, list_events, create_event and search_events emit log messages with the SDK's default metadata=None, which recent Dify rejects. The result was tool parameters validation error: 11 validation errors for DifyPluginToolInvokeMessage … message.LogMessage.metadata Input should be a valid dictionary. All 33 log calls now pass metadata={}.
  • Calendar IDs with # were not found. For example en.usa#holiday@group.v.calendar.google.com returned 404: the ID went into the URL unencoded, so everything after # became a fragment. IDs are now encoded as one path segment.

Their names, parameters and output are otherwise unchanged. Existing OAuth credentials keep working.

Each user signs in

A new API-key style credential holds:

  • Mode: Each user signs in.
  • Client ID and Client Secret of the same Google Web-application client.
  • Sign-in Callback URL: the plugin endpoint GET /google_calendar/callback.

The flow:

  • The first time a chat user needs the calendar, the tool returns a Google sign-in link: authorization code + PKCE, access_type=offline, prompt=consent select_account, scopes openid email …/auth/calendar.
  • The endpoint only stores the one-time code. The tool redeems it with the client secret and the PKCE verifier.
  • Per-user tokens are Fernet-encrypted in plugin storage, keyed by a hash of client_id | Dify user ID, and never appear in tool output.

Edge cases handled:

  • Account name: after sign-in the agent reports which Google account was used (openid email → userinfo).
  • Unticked permissions: Google lets users untick permissions on the consent screen. When the calendar scope isn't granted, the user is asked to sign in again instead of getting a later 403.
  • Expired or revoked sign-in: an invalid_grant on refresh (revoked, password change, or 7 days on a "Testing" app) or a 401 from the API starts a new sign-in.
  • Forwarded links: the callback page warns people who did not start the sign-in and lets them cancel it.
  • Sign-out: google_calendar_sign_out forgets the user's sign-in.

The original tools get the token through a small connect() helper, so they work in both modes. tools/user_auth.py keeps the plugin-specific values (name, scope) at the top, so the next Google plugins reuse it unchanged.

New tools (prefixed google_calendar_: the new Agent rejects duplicate tool names across plugins)

Operation Tool
Event: Get google_calendar_get_event (guests and responses, meeting link)
Event: Update google_calendar_update_event, which changes only the given fields:
• guests are added, or replaced with attendees_mode: replace
• a time without a UTC offset uses time_zone or the event's own time zone
• all-day end dates are exclusive (a one-day event ends the next day)
• send_updates chooses who is notified
Event: Delete google_calendar_delete_event
Calendar: Availability google_calendar_check_availability (free/busy for one or more calendars)
Event: Create / Get Many the original create_event, list_events, search_events

Every new tool returns typed output variables (success / error plus its fields).

Not changed: the original tool names. list_events, list_calendars, create_event and search_events are also Outlook tool names, so the two plugins can't share one new-style Agent ("Duplicate Dify Tool name"). Renaming them would break existing workflows, so they stay; the README documents the clash. Tool names should probably be namespaced per plugin in Dify itself.

Release Notes

  • Each user signs in: chat agents can let every user work on their own Google Calendar.
  • New tools: get, update and delete events, and check availability (free/busy).
  • Fix: the calendar tools failed on recent Dify versions with "11 validation errors for DifyPluginToolInvokeMessage".
  • Fix: calendars whose ID contains # (such as holiday calendars) can be read.

Change Type

  • Documentation / non-plugin change
  • Non-LLM plugin (tools, extensions, datasource, etc.)
  • LLM plugin

Screenshots / Videos

The README adds the per-user credential form and Google's unverified-app notice, next to the existing OAuth setup screenshots.

Testing

  • Unit tests: 36 passed (pytest tests). They cover:
    • The sign-in flow: PKCE link, callback, redeem, cache, refresh keeping the refresh token, invalid_grant → new link, a 401 → new link, unticked permission, per-user isolation, secret rotation, cancel/error pages, sign-out.
    • Every new tool: field patching, guest merge, time zones, exclusive all-day end, encoded IDs, free/busy with partial errors.
    • The original tools in both modes, and their log messages carrying metadata.
    • Every tool's output variables, the manifest and endpoint, and provider validation.
  • Self-hosted Dify (Community), Each user signs in, real Google account, in an agent chat:
    • Google's unverified-app notice → consent → Signed in → the agent named the account.
    • list_calendars → list_events for the week → create_event ("Dify test", 3–4 PM) → google_calendar_check_availability 2–5 PM reported 3–4 PM busy.
    • This run found both original-tool bugs above (the validation error and the # calendar ID). Both are fixed.
  • Not run against Google: google_calendar_update_event and google_calendar_delete_event (unit tests only).

Checklist

  • I have read the contribution guidelines
  • Version bumped: 0.1.7 → 1.0.0

@ForeignKeyCN ForeignKeyCN changed the title feat(google_calendar): Each user signs in, n8n's event operations, fix log-message validation and calendar ID encoding (1.0.0) feat(google_calendar): Each user signs in, more event operations, fix log-message validation and calendar ID encoding (1.0.0) Nov 2, 2026

@crazywoola crazywoola left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Reviewed the plugin scope, manifest, documentation, and relevant source changes. Approving this revision to run the repository pre-merge plugin validation; merge is contingent on successful validation.

This branch was successfully deployed

1 active deployment
tools/google_calendar — 83418750 Deployed Nov 2, 2026 by crazywoola via test (tools/google_calendar) #2950
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.

2 participants