mirror of
https://github.com/simstudioai/sim.git
synced 2026-09-24 15:45:35 +08:00
fix(google-calendar): align with live API docs, add calendar/ACL update+delete tools (#5485)
* fix(google-calendar): align with live API docs, add calendar/ACL update+delete tools - remove any types from V2 response typing in get/move/quick_add/instances - add google_calendar_update_calendar (PATCH calendars.patch) - add google_calendar_delete_calendar (DELETE calendars.delete) - add google_calendar_update_acl (PATCH acl.patch) - all new tools covered by existing calendar OAuth scope, no new scopes requested * fix(google-calendar): dedupe GoogleCalendarAclRole type in update_acl.ts export it from types.ts and import instead of redeclaring locally
This commit is contained in:
@@ -37,7 +37,10 @@ export const GoogleCalendarBlock: BlockConfig<GoogleCalendarResponse> = {
|
||||
{ label: 'Invite Attendees', id: 'invite' },
|
||||
{ label: 'Check Free/Busy', id: 'freebusy' },
|
||||
{ label: 'Create Calendar', id: 'create_calendar' },
|
||||
{ label: 'Update Calendar', id: 'update_calendar' },
|
||||
{ label: 'Delete Calendar', id: 'delete_calendar' },
|
||||
{ label: 'Share Calendar', id: 'share_calendar' },
|
||||
{ label: 'Update Sharing', id: 'update_acl' },
|
||||
{ label: 'List Sharing', id: 'list_acl' },
|
||||
{ label: 'Remove Sharing', id: 'unshare_calendar' },
|
||||
],
|
||||
@@ -621,14 +624,36 @@ Return ONLY the timestamp string - no explanations, no quotes, no extra text.`,
|
||||
title: 'Time Zone',
|
||||
type: 'short-input',
|
||||
placeholder: 'America/Los_Angeles',
|
||||
condition: { field: 'operation', value: ['create_calendar', 'freebusy'] },
|
||||
condition: { field: 'operation', value: ['create_calendar', 'freebusy', 'update_calendar'] },
|
||||
},
|
||||
|
||||
{
|
||||
id: 'summary',
|
||||
title: 'New Calendar Name',
|
||||
type: 'short-input',
|
||||
placeholder: 'Team Calendar',
|
||||
condition: { field: 'operation', value: 'update_calendar' },
|
||||
},
|
||||
{
|
||||
id: 'description',
|
||||
title: 'New Calendar Description',
|
||||
type: 'long-input',
|
||||
placeholder: 'Shared team events and milestones',
|
||||
condition: { field: 'operation', value: 'update_calendar' },
|
||||
},
|
||||
{
|
||||
id: 'location',
|
||||
title: 'New Calendar Location',
|
||||
type: 'short-input',
|
||||
placeholder: 'San Francisco, CA',
|
||||
condition: { field: 'operation', value: 'update_calendar' },
|
||||
},
|
||||
|
||||
{
|
||||
id: 'role',
|
||||
title: 'Access Role',
|
||||
type: 'dropdown',
|
||||
condition: { field: 'operation', value: 'share_calendar' },
|
||||
condition: { field: 'operation', value: ['share_calendar', 'update_acl'] },
|
||||
required: true,
|
||||
options: [
|
||||
{ label: 'See free/busy only', id: 'freeBusyReader' },
|
||||
@@ -668,7 +693,7 @@ Return ONLY the timestamp string - no explanations, no quotes, no extra text.`,
|
||||
id: 'sendNotifications',
|
||||
title: 'Send Notification Email',
|
||||
type: 'dropdown',
|
||||
condition: { field: 'operation', value: 'share_calendar' },
|
||||
condition: { field: 'operation', value: ['share_calendar', 'update_acl'] },
|
||||
mode: 'advanced',
|
||||
options: [
|
||||
{ label: 'Yes', id: 'true' },
|
||||
@@ -682,7 +707,7 @@ Return ONLY the timestamp string - no explanations, no quotes, no extra text.`,
|
||||
title: 'ACL Rule ID',
|
||||
type: 'short-input',
|
||||
placeholder: 'user:person@example.com',
|
||||
condition: { field: 'operation', value: 'unshare_calendar' },
|
||||
condition: { field: 'operation', value: ['unshare_calendar', 'update_acl'] },
|
||||
required: true,
|
||||
},
|
||||
|
||||
@@ -716,7 +741,10 @@ Return ONLY the timestamp string - no explanations, no quotes, no extra text.`,
|
||||
'google_calendar_invite',
|
||||
'google_calendar_freebusy',
|
||||
'google_calendar_create_calendar',
|
||||
'google_calendar_update_calendar',
|
||||
'google_calendar_delete_calendar',
|
||||
'google_calendar_share_calendar',
|
||||
'google_calendar_update_acl',
|
||||
'google_calendar_list_acl',
|
||||
'google_calendar_unshare_calendar',
|
||||
],
|
||||
@@ -747,8 +775,14 @@ Return ONLY the timestamp string - no explanations, no quotes, no extra text.`,
|
||||
return 'google_calendar_freebusy'
|
||||
case 'create_calendar':
|
||||
return 'google_calendar_create_calendar'
|
||||
case 'update_calendar':
|
||||
return 'google_calendar_update_calendar'
|
||||
case 'delete_calendar':
|
||||
return 'google_calendar_delete_calendar'
|
||||
case 'share_calendar':
|
||||
return 'google_calendar_share_calendar'
|
||||
case 'update_acl':
|
||||
return 'google_calendar_update_acl'
|
||||
case 'list_acl':
|
||||
return 'google_calendar_list_acl'
|
||||
case 'unshare_calendar':
|
||||
@@ -803,7 +837,10 @@ Return ONLY the timestamp string - no explanations, no quotes, no extra text.`,
|
||||
processedParams.addGoogleMeet === 'true' || processedParams.addGoogleMeet === true
|
||||
}
|
||||
|
||||
if (operation === 'share_calendar' && processedParams.sendNotifications !== undefined) {
|
||||
if (
|
||||
['share_calendar', 'update_acl'].includes(operation) &&
|
||||
processedParams.sendNotifications !== undefined
|
||||
) {
|
||||
processedParams.sendNotifications =
|
||||
processedParams.sendNotifications === 'true' ||
|
||||
processedParams.sendNotifications === true
|
||||
@@ -907,7 +944,10 @@ export const GoogleCalendarV2Block: BlockConfig<GoogleCalendarResponse> = {
|
||||
'google_calendar_invite_v2',
|
||||
'google_calendar_freebusy_v2',
|
||||
'google_calendar_create_calendar_v2',
|
||||
'google_calendar_update_calendar_v2',
|
||||
'google_calendar_delete_calendar_v2',
|
||||
'google_calendar_share_calendar_v2',
|
||||
'google_calendar_update_acl_v2',
|
||||
'google_calendar_list_acl_v2',
|
||||
'google_calendar_unshare_calendar_v2',
|
||||
],
|
||||
@@ -946,6 +986,7 @@ export const GoogleCalendarV2Block: BlockConfig<GoogleCalendarResponse> = {
|
||||
scope: { type: 'json', description: 'Grantee scope (share operation)' },
|
||||
rules: { type: 'json', description: 'List of ACL sharing rules (list sharing operation)' },
|
||||
ruleId: { type: 'string', description: 'Removed ACL rule ID (remove sharing operation)' },
|
||||
calendarId: { type: 'string', description: 'Deleted calendar ID (delete calendar operation)' },
|
||||
nextPageToken: { type: 'string', description: 'Next page token' },
|
||||
timeZone: { type: 'string', description: 'Calendar time zone' },
|
||||
},
|
||||
|
||||
@@ -0,0 +1,126 @@
|
||||
import { CALENDAR_API_BASE } from '@/tools/google_calendar/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export interface GoogleCalendarDeleteCalendarParams {
|
||||
accessToken: string
|
||||
calendarId: string
|
||||
}
|
||||
|
||||
interface GoogleCalendarDeleteCalendarResponse {
|
||||
success: boolean
|
||||
output: {
|
||||
content: string
|
||||
metadata: {
|
||||
calendarId: string
|
||||
deleted: boolean
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const buildDeleteCalendarUrl = (params: GoogleCalendarDeleteCalendarParams) =>
|
||||
`${CALENDAR_API_BASE}/calendars/${encodeURIComponent(params.calendarId.trim())}`
|
||||
|
||||
export const deleteCalendarTool: ToolConfig<
|
||||
GoogleCalendarDeleteCalendarParams,
|
||||
GoogleCalendarDeleteCalendarResponse
|
||||
> = {
|
||||
id: 'google_calendar_delete_calendar',
|
||||
name: 'Google Calendar Delete Calendar',
|
||||
description: 'Permanently delete a secondary calendar (not the primary calendar)',
|
||||
version: '1.0.0',
|
||||
|
||||
oauth: {
|
||||
required: true,
|
||||
provider: 'google-calendar',
|
||||
},
|
||||
|
||||
params: {
|
||||
accessToken: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'hidden',
|
||||
description: 'Access token for Google Calendar API',
|
||||
},
|
||||
calendarId: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description:
|
||||
'Secondary calendar ID to delete (e.g., calendar@group.calendar.google.com). The primary calendar cannot be deleted.',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: buildDeleteCalendarUrl,
|
||||
method: 'DELETE',
|
||||
headers: (params: GoogleCalendarDeleteCalendarParams) => ({
|
||||
Authorization: `Bearer ${params.accessToken}`,
|
||||
'Content-Type': 'application/json',
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response, params) => {
|
||||
if (response.status === 204 || response.ok) {
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
content: 'Calendar successfully deleted',
|
||||
metadata: {
|
||||
calendarId: params?.calendarId || '',
|
||||
deleted: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
const errorData = await response.json().catch(() => null)
|
||||
throw new Error(errorData?.error?.message || 'Failed to delete calendar')
|
||||
},
|
||||
|
||||
outputs: {
|
||||
content: { type: 'string', description: 'Calendar deletion confirmation message' },
|
||||
metadata: {
|
||||
type: 'json',
|
||||
description: 'Deletion details including calendar ID',
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
interface GoogleCalendarDeleteCalendarV2Response {
|
||||
success: boolean
|
||||
output: {
|
||||
calendarId: string
|
||||
deleted: boolean
|
||||
}
|
||||
}
|
||||
|
||||
export const deleteCalendarV2Tool: ToolConfig<
|
||||
GoogleCalendarDeleteCalendarParams,
|
||||
GoogleCalendarDeleteCalendarV2Response
|
||||
> = {
|
||||
id: 'google_calendar_delete_calendar_v2',
|
||||
name: 'Google Calendar Delete Calendar',
|
||||
description: 'Permanently delete a secondary calendar. Returns API-aligned fields only.',
|
||||
version: '2.0.0',
|
||||
oauth: deleteCalendarTool.oauth,
|
||||
params: deleteCalendarTool.params,
|
||||
request: deleteCalendarTool.request,
|
||||
transformResponse: async (response: Response, params) => {
|
||||
if (response.status === 204 || response.ok) {
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
calendarId: params?.calendarId || '',
|
||||
deleted: true,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
const errorData = await response.json().catch(() => null)
|
||||
throw new Error(errorData?.error?.message || 'Failed to delete calendar')
|
||||
},
|
||||
outputs: {
|
||||
calendarId: { type: 'string', description: 'Deleted calendar ID' },
|
||||
deleted: { type: 'boolean', description: 'Whether deletion was successful' },
|
||||
},
|
||||
}
|
||||
@@ -92,11 +92,11 @@ interface GoogleCalendarGetV2Response {
|
||||
summary: string | null
|
||||
description: string | null
|
||||
location: string | null
|
||||
start: any
|
||||
end: any
|
||||
attendees: any | null
|
||||
creator: any
|
||||
organizer: any
|
||||
start: GoogleCalendarApiEventResponse['start']
|
||||
end: GoogleCalendarApiEventResponse['end']
|
||||
attendees: GoogleCalendarApiEventResponse['attendees'] | null
|
||||
creator: GoogleCalendarApiEventResponse['creator']
|
||||
organizer: GoogleCalendarApiEventResponse['organizer']
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { createTool, createV2Tool } from '@/tools/google_calendar/create'
|
||||
import { createCalendarTool, createCalendarV2Tool } from '@/tools/google_calendar/create_calendar'
|
||||
import { deleteTool, deleteV2Tool } from '@/tools/google_calendar/delete'
|
||||
import { deleteCalendarTool, deleteCalendarV2Tool } from '@/tools/google_calendar/delete_calendar'
|
||||
import { freebusyTool, freebusyV2Tool } from '@/tools/google_calendar/freebusy'
|
||||
import { getTool, getV2Tool } from '@/tools/google_calendar/get'
|
||||
import { instancesTool, instancesV2Tool } from '@/tools/google_calendar/instances'
|
||||
@@ -16,10 +17,13 @@ import {
|
||||
unshareCalendarV2Tool,
|
||||
} from '@/tools/google_calendar/unshare_calendar'
|
||||
import { updateTool, updateV2Tool } from '@/tools/google_calendar/update'
|
||||
import { updateAclTool, updateAclV2Tool } from '@/tools/google_calendar/update_acl'
|
||||
import { updateCalendarTool, updateCalendarV2Tool } from '@/tools/google_calendar/update_calendar'
|
||||
|
||||
export const googleCalendarCreateTool = createTool
|
||||
export const googleCalendarCreateCalendarTool = createCalendarTool
|
||||
export const googleCalendarDeleteTool = deleteTool
|
||||
export const googleCalendarDeleteCalendarTool = deleteCalendarTool
|
||||
export const googleCalendarFreeBusyTool = freebusyTool
|
||||
export const googleCalendarGetTool = getTool
|
||||
export const googleCalendarInstancesTool = instancesTool
|
||||
@@ -32,10 +36,13 @@ export const googleCalendarQuickAddTool = quickAddTool
|
||||
export const googleCalendarShareCalendarTool = shareCalendarTool
|
||||
export const googleCalendarUnshareCalendarTool = unshareCalendarTool
|
||||
export const googleCalendarUpdateTool = updateTool
|
||||
export const googleCalendarUpdateAclTool = updateAclTool
|
||||
export const googleCalendarUpdateCalendarTool = updateCalendarTool
|
||||
|
||||
export const googleCalendarCreateV2Tool = createV2Tool
|
||||
export const googleCalendarCreateCalendarV2Tool = createCalendarV2Tool
|
||||
export const googleCalendarDeleteV2Tool = deleteV2Tool
|
||||
export const googleCalendarDeleteCalendarV2Tool = deleteCalendarV2Tool
|
||||
export const googleCalendarFreeBusyV2Tool = freebusyV2Tool
|
||||
export const googleCalendarGetV2Tool = getV2Tool
|
||||
export const googleCalendarInstancesV2Tool = instancesV2Tool
|
||||
@@ -48,3 +55,5 @@ export const googleCalendarQuickAddV2Tool = quickAddV2Tool
|
||||
export const googleCalendarShareCalendarV2Tool = shareCalendarV2Tool
|
||||
export const googleCalendarUnshareCalendarV2Tool = unshareCalendarV2Tool
|
||||
export const googleCalendarUpdateV2Tool = updateV2Tool
|
||||
export const googleCalendarUpdateAclV2Tool = updateAclV2Tool
|
||||
export const googleCalendarUpdateCalendarV2Tool = updateCalendarV2Tool
|
||||
|
||||
@@ -212,12 +212,32 @@ export const instancesTool: ToolConfig<
|
||||
},
|
||||
}
|
||||
|
||||
interface GoogleCalendarInstancesV2Instance {
|
||||
id: string
|
||||
htmlLink: string
|
||||
status: string
|
||||
summary: string | null
|
||||
description: string | null
|
||||
location: string | null
|
||||
start: GoogleCalendarApiEventResponse['start']
|
||||
end: GoogleCalendarApiEventResponse['end']
|
||||
attendees: GoogleCalendarApiEventResponse['attendees'] | null
|
||||
creator: GoogleCalendarApiEventResponse['creator']
|
||||
organizer: GoogleCalendarApiEventResponse['organizer']
|
||||
recurringEventId: string
|
||||
originalStartTime: {
|
||||
dateTime?: string
|
||||
date?: string
|
||||
timeZone?: string
|
||||
}
|
||||
}
|
||||
|
||||
interface GoogleCalendarInstancesV2Response {
|
||||
success: boolean
|
||||
output: {
|
||||
nextPageToken: string | null
|
||||
timeZone: string | null
|
||||
instances: Array<Record<string, any>>
|
||||
instances: GoogleCalendarInstancesV2Instance[]
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -157,11 +157,11 @@ interface GoogleCalendarMoveV2Response {
|
||||
summary: string | null
|
||||
description: string | null
|
||||
location: string | null
|
||||
start: any
|
||||
end: any
|
||||
attendees: any | null
|
||||
creator: any
|
||||
organizer: any
|
||||
start: GoogleCalendarApiEventResponse['start']
|
||||
end: GoogleCalendarApiEventResponse['end']
|
||||
attendees: GoogleCalendarApiEventResponse['attendees'] | null
|
||||
creator: GoogleCalendarApiEventResponse['creator']
|
||||
organizer: GoogleCalendarApiEventResponse['organizer']
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { createLogger } from '@sim/logger'
|
||||
import {
|
||||
CALENDAR_API_BASE,
|
||||
type GoogleCalendarApiEventResponse,
|
||||
type GoogleCalendarQuickAddParams,
|
||||
type GoogleCalendarQuickAddResponse,
|
||||
} from '@/tools/google_calendar/types'
|
||||
@@ -77,9 +78,9 @@ export const quickAddTool: ToolConfig<
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response, params) => {
|
||||
const data = await response.json()
|
||||
const data: GoogleCalendarApiEventResponse = await response.json()
|
||||
|
||||
let finalEventData = data
|
||||
let finalEventData: GoogleCalendarApiEventResponse = data
|
||||
if (params?.attendees) {
|
||||
let attendeeList: string[] = []
|
||||
const attendees = params.attendees as string | string[]
|
||||
@@ -181,16 +182,16 @@ interface GoogleCalendarQuickAddV2Response {
|
||||
success: boolean
|
||||
output: {
|
||||
id: string
|
||||
htmlLink?: string
|
||||
status?: string
|
||||
summary?: string
|
||||
description?: string
|
||||
location?: string
|
||||
start?: any
|
||||
end?: any
|
||||
attendees?: any
|
||||
creator?: any
|
||||
organizer?: any
|
||||
htmlLink: string
|
||||
status: string
|
||||
summary: string | null
|
||||
description: string | null
|
||||
location: string | null
|
||||
start: GoogleCalendarApiEventResponse['start']
|
||||
end: GoogleCalendarApiEventResponse['end']
|
||||
attendees: GoogleCalendarApiEventResponse['attendees'] | null
|
||||
creator: GoogleCalendarApiEventResponse['creator']
|
||||
organizer: GoogleCalendarApiEventResponse['organizer']
|
||||
}
|
||||
}
|
||||
|
||||
@@ -206,9 +207,9 @@ export const quickAddV2Tool: ToolConfig<
|
||||
params: quickAddTool.params,
|
||||
request: quickAddTool.request,
|
||||
transformResponse: async (response: Response, params) => {
|
||||
const data = await response.json()
|
||||
const data: GoogleCalendarApiEventResponse = await response.json()
|
||||
|
||||
let finalEventData = data
|
||||
let finalEventData: GoogleCalendarApiEventResponse = data
|
||||
if (params?.attendees) {
|
||||
let attendeeList: string[] = []
|
||||
const attendees = params.attendees as string | string[]
|
||||
|
||||
@@ -120,7 +120,7 @@ export interface GoogleCalendarCreateCalendarParams {
|
||||
timeZone?: string
|
||||
}
|
||||
|
||||
type GoogleCalendarAclRole = 'freeBusyReader' | 'reader' | 'writer' | 'owner'
|
||||
export type GoogleCalendarAclRole = 'freeBusyReader' | 'reader' | 'writer' | 'owner'
|
||||
type GoogleCalendarAclScopeType = 'user' | 'group' | 'domain' | 'default'
|
||||
|
||||
export interface GoogleCalendarShareCalendarParams {
|
||||
|
||||
@@ -0,0 +1,158 @@
|
||||
import {
|
||||
CALENDAR_API_BASE,
|
||||
type GoogleCalendarAclRole,
|
||||
type GoogleCalendarApiAclRule,
|
||||
} from '@/tools/google_calendar/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export interface GoogleCalendarUpdateAclParams {
|
||||
accessToken: string
|
||||
calendarId?: string
|
||||
ruleId: string
|
||||
role: GoogleCalendarAclRole
|
||||
sendNotifications?: boolean
|
||||
}
|
||||
|
||||
export interface GoogleCalendarUpdateAclResponse {
|
||||
success: boolean
|
||||
output: {
|
||||
content: string
|
||||
metadata: {
|
||||
id: string
|
||||
role: string
|
||||
scope: { type: string; value?: string }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const buildUpdateAclUrl = (params: GoogleCalendarUpdateAclParams) => {
|
||||
const calendarId = params.calendarId?.trim() || 'primary'
|
||||
const queryParams = new URLSearchParams()
|
||||
if (params.sendNotifications !== undefined) {
|
||||
queryParams.append('sendNotifications', String(params.sendNotifications))
|
||||
}
|
||||
const queryString = queryParams.toString()
|
||||
return `${CALENDAR_API_BASE}/calendars/${encodeURIComponent(calendarId)}/acl/${encodeURIComponent(params.ruleId.trim())}${queryString ? `?${queryString}` : ''}`
|
||||
}
|
||||
|
||||
export const updateAclTool: ToolConfig<
|
||||
GoogleCalendarUpdateAclParams,
|
||||
GoogleCalendarUpdateAclResponse
|
||||
> = {
|
||||
id: 'google_calendar_update_acl',
|
||||
name: 'Google Calendar Update Sharing',
|
||||
description: 'Change the access role granted by an existing calendar sharing (ACL) rule',
|
||||
version: '1.0.0',
|
||||
|
||||
oauth: {
|
||||
required: true,
|
||||
provider: 'google-calendar',
|
||||
},
|
||||
|
||||
params: {
|
||||
accessToken: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'hidden',
|
||||
description: 'Access token for Google Calendar API',
|
||||
},
|
||||
calendarId: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Calendar ID to modify (e.g., primary or calendar@group.calendar.google.com)',
|
||||
},
|
||||
ruleId: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'ACL rule ID to update (e.g., user:person@example.com)',
|
||||
},
|
||||
role: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'New access role to grant: freeBusyReader, reader, writer, or owner',
|
||||
},
|
||||
sendNotifications: {
|
||||
type: 'boolean',
|
||||
required: false,
|
||||
visibility: 'user-only',
|
||||
description: 'Whether to send a notification email about the change. Defaults to true.',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: buildUpdateAclUrl,
|
||||
method: 'PATCH',
|
||||
headers: (params: GoogleCalendarUpdateAclParams) => ({
|
||||
Authorization: `Bearer ${params.accessToken}`,
|
||||
'Content-Type': 'application/json',
|
||||
}),
|
||||
body: (params: GoogleCalendarUpdateAclParams) => ({ role: params.role }),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data: GoogleCalendarApiAclRule = await response.json()
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
content: `Updated sharing rule for ${data.scope?.value || data.scope?.type} to ${data.role}`,
|
||||
metadata: {
|
||||
id: data.id,
|
||||
role: data.role,
|
||||
scope: data.scope,
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
content: { type: 'string', description: 'Sharing update confirmation message' },
|
||||
metadata: {
|
||||
type: 'json',
|
||||
description: 'Updated ACL rule (id, role, scope)',
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
interface GoogleCalendarUpdateAclV2Response {
|
||||
success: boolean
|
||||
output: {
|
||||
id: string
|
||||
role: string
|
||||
scope: { type: string; value?: string }
|
||||
}
|
||||
}
|
||||
|
||||
export const updateAclV2Tool: ToolConfig<
|
||||
GoogleCalendarUpdateAclParams,
|
||||
GoogleCalendarUpdateAclV2Response
|
||||
> = {
|
||||
id: 'google_calendar_update_acl_v2',
|
||||
name: 'Google Calendar Update Sharing',
|
||||
description:
|
||||
'Change the access role granted by an existing calendar sharing (ACL) rule. Returns API-aligned fields only.',
|
||||
version: '2.0.0',
|
||||
oauth: updateAclTool.oauth,
|
||||
params: updateAclTool.params,
|
||||
request: updateAclTool.request,
|
||||
transformResponse: async (response: Response) => {
|
||||
const data: GoogleCalendarApiAclRule = await response.json()
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
id: data.id,
|
||||
role: data.role,
|
||||
scope: data.scope,
|
||||
},
|
||||
}
|
||||
},
|
||||
outputs: {
|
||||
id: { type: 'string', description: 'ACL rule ID' },
|
||||
role: { type: 'string', description: 'Granted access role' },
|
||||
scope: { type: 'json', description: 'Grantee scope (type and value)' },
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,177 @@
|
||||
import {
|
||||
CALENDAR_API_BASE,
|
||||
type GoogleCalendarApiCalendarResponse,
|
||||
} from '@/tools/google_calendar/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export interface GoogleCalendarUpdateCalendarParams {
|
||||
accessToken: string
|
||||
calendarId?: string
|
||||
summary?: string
|
||||
description?: string
|
||||
location?: string
|
||||
timeZone?: string
|
||||
}
|
||||
|
||||
export interface GoogleCalendarUpdateCalendarResponse {
|
||||
success: boolean
|
||||
output: {
|
||||
content: string
|
||||
metadata: {
|
||||
id: string
|
||||
summary: string
|
||||
description?: string
|
||||
location?: string
|
||||
timeZone?: string
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const buildUpdateCalendarUrl = (params: GoogleCalendarUpdateCalendarParams) => {
|
||||
const calendarId = params.calendarId?.trim() || 'primary'
|
||||
return `${CALENDAR_API_BASE}/calendars/${encodeURIComponent(calendarId)}`
|
||||
}
|
||||
|
||||
const buildUpdateCalendarBody = (params: GoogleCalendarUpdateCalendarParams) => {
|
||||
const body: Record<string, string> = {}
|
||||
if (params.summary !== undefined) body.summary = params.summary
|
||||
if (params.description !== undefined) body.description = params.description
|
||||
if (params.location !== undefined) body.location = params.location
|
||||
if (params.timeZone !== undefined) body.timeZone = params.timeZone
|
||||
return body
|
||||
}
|
||||
|
||||
export const updateCalendarTool: ToolConfig<
|
||||
GoogleCalendarUpdateCalendarParams,
|
||||
GoogleCalendarUpdateCalendarResponse
|
||||
> = {
|
||||
id: 'google_calendar_update_calendar',
|
||||
name: 'Google Calendar Update Calendar',
|
||||
description: "Update a secondary calendar's metadata (title, description, location, time zone)",
|
||||
version: '1.0.0',
|
||||
|
||||
oauth: {
|
||||
required: true,
|
||||
provider: 'google-calendar',
|
||||
},
|
||||
|
||||
params: {
|
||||
accessToken: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'hidden',
|
||||
description: 'Access token for Google Calendar API',
|
||||
},
|
||||
calendarId: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Calendar ID to update (e.g., primary or calendar@group.calendar.google.com)',
|
||||
},
|
||||
summary: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'New title for the calendar',
|
||||
},
|
||||
description: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'New description for the calendar',
|
||||
},
|
||||
location: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'New geographic location of the calendar as free-form text',
|
||||
},
|
||||
timeZone: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'New time zone of the calendar as an IANA name (e.g., America/Los_Angeles)',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: buildUpdateCalendarUrl,
|
||||
method: 'PATCH',
|
||||
headers: (params: GoogleCalendarUpdateCalendarParams) => ({
|
||||
Authorization: `Bearer ${params.accessToken}`,
|
||||
'Content-Type': 'application/json',
|
||||
}),
|
||||
body: buildUpdateCalendarBody,
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data: GoogleCalendarApiCalendarResponse = await response.json()
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
content: `Calendar "${data.summary}" updated successfully`,
|
||||
metadata: {
|
||||
id: data.id,
|
||||
summary: data.summary,
|
||||
description: data.description,
|
||||
location: data.location,
|
||||
timeZone: data.timeZone,
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
content: { type: 'string', description: 'Calendar update confirmation message' },
|
||||
metadata: {
|
||||
type: 'json',
|
||||
description: 'Updated calendar metadata (id, summary, description, location, timeZone)',
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
interface GoogleCalendarUpdateCalendarV2Response {
|
||||
success: boolean
|
||||
output: {
|
||||
id: string
|
||||
summary: string
|
||||
description: string | null
|
||||
location: string | null
|
||||
timeZone: string | null
|
||||
}
|
||||
}
|
||||
|
||||
export const updateCalendarV2Tool: ToolConfig<
|
||||
GoogleCalendarUpdateCalendarParams,
|
||||
GoogleCalendarUpdateCalendarV2Response
|
||||
> = {
|
||||
id: 'google_calendar_update_calendar_v2',
|
||||
name: 'Google Calendar Update Calendar',
|
||||
description: "Update a secondary calendar's metadata. Returns API-aligned fields only.",
|
||||
version: '2.0.0',
|
||||
oauth: updateCalendarTool.oauth,
|
||||
params: updateCalendarTool.params,
|
||||
request: updateCalendarTool.request,
|
||||
transformResponse: async (response: Response) => {
|
||||
const data: GoogleCalendarApiCalendarResponse = await response.json()
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
id: data.id,
|
||||
summary: data.summary,
|
||||
description: data.description ?? null,
|
||||
location: data.location ?? null,
|
||||
timeZone: data.timeZone ?? null,
|
||||
},
|
||||
}
|
||||
},
|
||||
outputs: {
|
||||
id: { type: 'string', description: 'Calendar ID' },
|
||||
summary: { type: 'string', description: 'Calendar title' },
|
||||
description: { type: 'string', description: 'Calendar description', optional: true },
|
||||
location: { type: 'string', description: 'Calendar location', optional: true },
|
||||
timeZone: { type: 'string', description: 'Calendar time zone', optional: true },
|
||||
},
|
||||
}
|
||||
@@ -1322,6 +1322,8 @@ import {
|
||||
googleCalendarCreateCalendarV2Tool,
|
||||
googleCalendarCreateTool,
|
||||
googleCalendarCreateV2Tool,
|
||||
googleCalendarDeleteCalendarTool,
|
||||
googleCalendarDeleteCalendarV2Tool,
|
||||
googleCalendarDeleteTool,
|
||||
googleCalendarDeleteV2Tool,
|
||||
googleCalendarFreeBusyTool,
|
||||
@@ -1346,6 +1348,10 @@ import {
|
||||
googleCalendarShareCalendarV2Tool,
|
||||
googleCalendarUnshareCalendarTool,
|
||||
googleCalendarUnshareCalendarV2Tool,
|
||||
googleCalendarUpdateAclTool,
|
||||
googleCalendarUpdateAclV2Tool,
|
||||
googleCalendarUpdateCalendarTool,
|
||||
googleCalendarUpdateCalendarV2Tool,
|
||||
googleCalendarUpdateTool,
|
||||
googleCalendarUpdateV2Tool,
|
||||
} from '@/tools/google_calendar'
|
||||
@@ -7628,6 +7634,8 @@ export const tools: Record<string, ToolConfig> = {
|
||||
google_calendar_create_calendar_v2: googleCalendarCreateCalendarV2Tool,
|
||||
google_calendar_delete: googleCalendarDeleteTool,
|
||||
google_calendar_delete_v2: googleCalendarDeleteV2Tool,
|
||||
google_calendar_delete_calendar: googleCalendarDeleteCalendarTool,
|
||||
google_calendar_delete_calendar_v2: googleCalendarDeleteCalendarV2Tool,
|
||||
google_calendar_freebusy: googleCalendarFreeBusyTool,
|
||||
google_calendar_freebusy_v2: googleCalendarFreeBusyV2Tool,
|
||||
google_calendar_get: googleCalendarGetTool,
|
||||
@@ -7652,6 +7660,10 @@ export const tools: Record<string, ToolConfig> = {
|
||||
google_calendar_unshare_calendar_v2: googleCalendarUnshareCalendarV2Tool,
|
||||
google_calendar_update: googleCalendarUpdateTool,
|
||||
google_calendar_update_v2: googleCalendarUpdateV2Tool,
|
||||
google_calendar_update_acl: googleCalendarUpdateAclTool,
|
||||
google_calendar_update_acl_v2: googleCalendarUpdateAclV2Tool,
|
||||
google_calendar_update_calendar: googleCalendarUpdateCalendarTool,
|
||||
google_calendar_update_calendar_v2: googleCalendarUpdateCalendarV2Tool,
|
||||
google_contacts_create: googleContactsCreateTool,
|
||||
google_contacts_delete: googleContactsDeleteTool,
|
||||
google_contacts_get: googleContactsGetTool,
|
||||
|
||||
Reference in New Issue
Block a user