mirror of
https://github.com/farcasclaudiu/Flowise.git
synced 2026-06-28 23:01:09 +03:00
Feature/Add teams, gmail, outlook tools (#4577)
* add teams, gmail, outlook tools * update docs link * update credentials for oauth2 * add jira tool * add google drive, google calendar, google sheets tools, powerpoint, excel, word doc loader * update jira logo * Refactor Gmail and Outlook tools to remove maxOutputLength parameter and enhance request handling. Update response formatting to include parameters in the output. Adjust Google Drive tools to simplify success messages by removing unnecessary parameter details.
This commit is contained in:
@@ -0,0 +1,655 @@
|
||||
import { convertMultiOptionsToStringArray, getCredentialData, getCredentialParam, refreshOAuth2Token } from '../../../src/utils'
|
||||
import { createGoogleCalendarTools } from './core'
|
||||
import type { ICommonObject, INode, INodeData, INodeParams } from '../../../src/Interface'
|
||||
|
||||
class GoogleCalendar_Tools implements INode {
|
||||
label: string
|
||||
name: string
|
||||
version: number
|
||||
type: string
|
||||
icon: string
|
||||
category: string
|
||||
description: string
|
||||
baseClasses: string[]
|
||||
credential: INodeParams
|
||||
inputs: INodeParams[]
|
||||
|
||||
constructor() {
|
||||
this.label = 'Google Calendar'
|
||||
this.name = 'googleCalendarTool'
|
||||
this.version = 1.0
|
||||
this.type = 'GoogleCalendar'
|
||||
this.icon = 'google-calendar.svg'
|
||||
this.category = 'Tools'
|
||||
this.description = 'Perform Google Calendar operations such as managing events, calendars, and checking availability'
|
||||
this.baseClasses = ['Tool']
|
||||
this.credential = {
|
||||
label: 'Connect Credential',
|
||||
name: 'credential',
|
||||
type: 'credential',
|
||||
credentialNames: ['googleCalendarOAuth2']
|
||||
}
|
||||
this.inputs = [
|
||||
{
|
||||
label: 'Type',
|
||||
name: 'calendarType',
|
||||
type: 'options',
|
||||
description: 'Type of Google Calendar operation',
|
||||
options: [
|
||||
{
|
||||
label: 'Event',
|
||||
name: 'event'
|
||||
},
|
||||
{
|
||||
label: 'Calendar',
|
||||
name: 'calendar'
|
||||
},
|
||||
{
|
||||
label: 'Freebusy',
|
||||
name: 'freebusy'
|
||||
}
|
||||
]
|
||||
},
|
||||
// Event Actions
|
||||
{
|
||||
label: 'Event Actions',
|
||||
name: 'eventActions',
|
||||
type: 'multiOptions',
|
||||
description: 'Actions to perform',
|
||||
options: [
|
||||
{
|
||||
label: 'List Events',
|
||||
name: 'listEvents'
|
||||
},
|
||||
{
|
||||
label: 'Create Event',
|
||||
name: 'createEvent'
|
||||
},
|
||||
{
|
||||
label: 'Get Event',
|
||||
name: 'getEvent'
|
||||
},
|
||||
{
|
||||
label: 'Update Event',
|
||||
name: 'updateEvent'
|
||||
},
|
||||
{
|
||||
label: 'Delete Event',
|
||||
name: 'deleteEvent'
|
||||
},
|
||||
{
|
||||
label: 'Quick Add Event',
|
||||
name: 'quickAddEvent'
|
||||
}
|
||||
],
|
||||
show: {
|
||||
calendarType: ['event']
|
||||
}
|
||||
},
|
||||
// Calendar Actions
|
||||
{
|
||||
label: 'Calendar Actions',
|
||||
name: 'calendarActions',
|
||||
type: 'multiOptions',
|
||||
description: 'Actions to perform',
|
||||
options: [
|
||||
{
|
||||
label: 'List Calendars',
|
||||
name: 'listCalendars'
|
||||
},
|
||||
{
|
||||
label: 'Create Calendar',
|
||||
name: 'createCalendar'
|
||||
},
|
||||
{
|
||||
label: 'Get Calendar',
|
||||
name: 'getCalendar'
|
||||
},
|
||||
{
|
||||
label: 'Update Calendar',
|
||||
name: 'updateCalendar'
|
||||
},
|
||||
{
|
||||
label: 'Delete Calendar',
|
||||
name: 'deleteCalendar'
|
||||
},
|
||||
{
|
||||
label: 'Clear Calendar',
|
||||
name: 'clearCalendar'
|
||||
}
|
||||
],
|
||||
show: {
|
||||
calendarType: ['calendar']
|
||||
}
|
||||
},
|
||||
// Freebusy Actions
|
||||
{
|
||||
label: 'Freebusy Actions',
|
||||
name: 'freebusyActions',
|
||||
type: 'multiOptions',
|
||||
description: 'Actions to perform',
|
||||
options: [
|
||||
{
|
||||
label: 'Query Freebusy',
|
||||
name: 'queryFreebusy'
|
||||
}
|
||||
],
|
||||
show: {
|
||||
calendarType: ['freebusy']
|
||||
}
|
||||
},
|
||||
// Event Parameters
|
||||
{
|
||||
label: 'Calendar ID',
|
||||
name: 'calendarId',
|
||||
type: 'string',
|
||||
description: 'Calendar ID (use "primary" for primary calendar)',
|
||||
default: 'primary',
|
||||
show: {
|
||||
calendarType: ['event']
|
||||
},
|
||||
additionalParams: true,
|
||||
optional: true
|
||||
},
|
||||
{
|
||||
label: 'Event ID',
|
||||
name: 'eventId',
|
||||
type: 'string',
|
||||
description: 'Event ID for operations on specific events',
|
||||
show: {
|
||||
eventActions: ['getEvent', 'updateEvent', 'deleteEvent']
|
||||
},
|
||||
additionalParams: true,
|
||||
optional: true
|
||||
},
|
||||
{
|
||||
label: 'Summary',
|
||||
name: 'summary',
|
||||
type: 'string',
|
||||
description: 'Event title/summary',
|
||||
show: {
|
||||
eventActions: ['createEvent', 'updateEvent']
|
||||
},
|
||||
additionalParams: true,
|
||||
optional: true
|
||||
},
|
||||
{
|
||||
label: 'Description',
|
||||
name: 'description',
|
||||
type: 'string',
|
||||
description: 'Event description',
|
||||
show: {
|
||||
eventActions: ['createEvent', 'updateEvent']
|
||||
},
|
||||
additionalParams: true,
|
||||
optional: true
|
||||
},
|
||||
{
|
||||
label: 'Location',
|
||||
name: 'location',
|
||||
type: 'string',
|
||||
description: 'Event location',
|
||||
show: {
|
||||
eventActions: ['createEvent', 'updateEvent']
|
||||
},
|
||||
additionalParams: true,
|
||||
optional: true
|
||||
},
|
||||
{
|
||||
label: 'Start Date Time',
|
||||
name: 'startDateTime',
|
||||
type: 'string',
|
||||
description: 'Event start time (ISO 8601 format: 2023-12-25T10:00:00)',
|
||||
show: {
|
||||
eventActions: ['createEvent', 'updateEvent']
|
||||
},
|
||||
additionalParams: true,
|
||||
optional: true
|
||||
},
|
||||
{
|
||||
label: 'End Date Time',
|
||||
name: 'endDateTime',
|
||||
type: 'string',
|
||||
description: 'Event end time (ISO 8601 format: 2023-12-25T11:00:00)',
|
||||
show: {
|
||||
eventActions: ['createEvent', 'updateEvent']
|
||||
},
|
||||
additionalParams: true,
|
||||
optional: true
|
||||
},
|
||||
{
|
||||
label: 'Time Zone',
|
||||
name: 'timeZone',
|
||||
type: 'string',
|
||||
description: 'Time zone (e.g., America/New_York)',
|
||||
show: {
|
||||
eventActions: ['createEvent', 'updateEvent']
|
||||
},
|
||||
additionalParams: true,
|
||||
optional: true
|
||||
},
|
||||
{
|
||||
label: 'All Day Event',
|
||||
name: 'allDay',
|
||||
type: 'boolean',
|
||||
description: 'Whether this is an all-day event',
|
||||
show: {
|
||||
eventActions: ['createEvent', 'updateEvent']
|
||||
},
|
||||
additionalParams: true,
|
||||
optional: true
|
||||
},
|
||||
{
|
||||
label: 'Start Date',
|
||||
name: 'startDate',
|
||||
type: 'string',
|
||||
description: 'Start date for all-day events (YYYY-MM-DD format)',
|
||||
show: {
|
||||
eventActions: ['createEvent', 'updateEvent']
|
||||
},
|
||||
additionalParams: true,
|
||||
optional: true
|
||||
},
|
||||
{
|
||||
label: 'End Date',
|
||||
name: 'endDate',
|
||||
type: 'string',
|
||||
description: 'End date for all-day events (YYYY-MM-DD format)',
|
||||
show: {
|
||||
eventActions: ['createEvent', 'updateEvent']
|
||||
},
|
||||
additionalParams: true,
|
||||
optional: true
|
||||
},
|
||||
{
|
||||
label: 'Attendees',
|
||||
name: 'attendees',
|
||||
type: 'string',
|
||||
description: 'Comma-separated list of attendee emails',
|
||||
show: {
|
||||
eventActions: ['createEvent', 'updateEvent']
|
||||
},
|
||||
additionalParams: true,
|
||||
optional: true
|
||||
},
|
||||
{
|
||||
label: 'Recurrence Rules',
|
||||
name: 'recurrence',
|
||||
type: 'string',
|
||||
description: 'Recurrence rules (RRULE format)',
|
||||
show: {
|
||||
eventActions: ['createEvent', 'updateEvent']
|
||||
},
|
||||
additionalParams: true,
|
||||
optional: true
|
||||
},
|
||||
{
|
||||
label: 'Reminder Minutes',
|
||||
name: 'reminderMinutes',
|
||||
type: 'number',
|
||||
description: 'Minutes before event to send reminder',
|
||||
show: {
|
||||
eventActions: ['createEvent', 'updateEvent']
|
||||
},
|
||||
additionalParams: true,
|
||||
optional: true
|
||||
},
|
||||
{
|
||||
label: 'Visibility',
|
||||
name: 'visibility',
|
||||
type: 'options',
|
||||
description: 'Event visibility',
|
||||
options: [
|
||||
{ label: 'Default', name: 'default' },
|
||||
{ label: 'Public', name: 'public' },
|
||||
{ label: 'Private', name: 'private' },
|
||||
{ label: 'Confidential', name: 'confidential' }
|
||||
],
|
||||
show: {
|
||||
eventActions: ['createEvent', 'updateEvent']
|
||||
},
|
||||
additionalParams: true,
|
||||
optional: true
|
||||
},
|
||||
{
|
||||
label: 'Quick Add Text',
|
||||
name: 'quickAddText',
|
||||
type: 'string',
|
||||
description: 'Natural language text for quick event creation (e.g., "Lunch with John tomorrow at 12pm")',
|
||||
show: {
|
||||
eventActions: ['quickAddEvent']
|
||||
},
|
||||
additionalParams: true,
|
||||
optional: true
|
||||
},
|
||||
{
|
||||
label: 'Time Min',
|
||||
name: 'timeMin',
|
||||
type: 'string',
|
||||
description: 'Lower bound for event search (ISO 8601 format)',
|
||||
show: {
|
||||
eventActions: ['listEvents']
|
||||
},
|
||||
additionalParams: true,
|
||||
optional: true
|
||||
},
|
||||
{
|
||||
label: 'Time Max',
|
||||
name: 'timeMax',
|
||||
type: 'string',
|
||||
description: 'Upper bound for event search (ISO 8601 format)',
|
||||
show: {
|
||||
eventActions: ['listEvents']
|
||||
},
|
||||
additionalParams: true,
|
||||
optional: true
|
||||
},
|
||||
{
|
||||
label: 'Max Results',
|
||||
name: 'maxResults',
|
||||
type: 'number',
|
||||
description: 'Maximum number of events to return',
|
||||
default: 250,
|
||||
show: {
|
||||
eventActions: ['listEvents']
|
||||
},
|
||||
additionalParams: true,
|
||||
optional: true
|
||||
},
|
||||
{
|
||||
label: 'Single Events',
|
||||
name: 'singleEvents',
|
||||
type: 'boolean',
|
||||
description: 'Whether to expand recurring events into instances',
|
||||
default: true,
|
||||
show: {
|
||||
eventActions: ['listEvents']
|
||||
},
|
||||
additionalParams: true,
|
||||
optional: true
|
||||
},
|
||||
{
|
||||
label: 'Order By',
|
||||
name: 'orderBy',
|
||||
type: 'options',
|
||||
description: 'Order of events returned',
|
||||
options: [
|
||||
{ label: 'Start Time', name: 'startTime' },
|
||||
{ label: 'Updated', name: 'updated' }
|
||||
],
|
||||
show: {
|
||||
eventActions: ['listEvents']
|
||||
},
|
||||
additionalParams: true,
|
||||
optional: true
|
||||
},
|
||||
{
|
||||
label: 'Query',
|
||||
name: 'query',
|
||||
type: 'string',
|
||||
description: 'Free text search terms',
|
||||
show: {
|
||||
eventActions: ['listEvents']
|
||||
},
|
||||
additionalParams: true,
|
||||
optional: true
|
||||
},
|
||||
// Calendar Parameters
|
||||
{
|
||||
label: 'Calendar ID',
|
||||
name: 'calendarIdForCalendar',
|
||||
type: 'string',
|
||||
description: 'Calendar ID for operations on specific calendars',
|
||||
show: {
|
||||
calendarActions: ['getCalendar', 'updateCalendar', 'deleteCalendar', 'clearCalendar']
|
||||
},
|
||||
additionalParams: true,
|
||||
optional: true
|
||||
},
|
||||
{
|
||||
label: 'Calendar Summary',
|
||||
name: 'calendarSummary',
|
||||
type: 'string',
|
||||
description: 'Calendar title/name',
|
||||
show: {
|
||||
calendarActions: ['createCalendar', 'updateCalendar']
|
||||
},
|
||||
additionalParams: true,
|
||||
optional: true
|
||||
},
|
||||
{
|
||||
label: 'Calendar Description',
|
||||
name: 'calendarDescription',
|
||||
type: 'string',
|
||||
description: 'Calendar description',
|
||||
show: {
|
||||
calendarActions: ['createCalendar', 'updateCalendar']
|
||||
},
|
||||
additionalParams: true,
|
||||
optional: true
|
||||
},
|
||||
{
|
||||
label: 'Calendar Location',
|
||||
name: 'calendarLocation',
|
||||
type: 'string',
|
||||
description: 'Calendar location',
|
||||
show: {
|
||||
calendarActions: ['createCalendar', 'updateCalendar']
|
||||
},
|
||||
additionalParams: true,
|
||||
optional: true
|
||||
},
|
||||
{
|
||||
label: 'Calendar Time Zone',
|
||||
name: 'calendarTimeZone',
|
||||
type: 'string',
|
||||
description: 'Calendar time zone (e.g., America/New_York)',
|
||||
show: {
|
||||
calendarActions: ['createCalendar', 'updateCalendar']
|
||||
},
|
||||
additionalParams: true,
|
||||
optional: true
|
||||
},
|
||||
{
|
||||
label: 'Show Hidden',
|
||||
name: 'showHidden',
|
||||
type: 'boolean',
|
||||
description: 'Whether to show hidden calendars',
|
||||
show: {
|
||||
calendarActions: ['listCalendars']
|
||||
},
|
||||
additionalParams: true,
|
||||
optional: true
|
||||
},
|
||||
{
|
||||
label: 'Min Access Role',
|
||||
name: 'minAccessRole',
|
||||
type: 'options',
|
||||
description: 'Minimum access role for calendar list',
|
||||
options: [
|
||||
{ label: 'Free/Busy Reader', name: 'freeBusyReader' },
|
||||
{ label: 'Reader', name: 'reader' },
|
||||
{ label: 'Writer', name: 'writer' },
|
||||
{ label: 'Owner', name: 'owner' }
|
||||
],
|
||||
show: {
|
||||
calendarActions: ['listCalendars']
|
||||
},
|
||||
additionalParams: true,
|
||||
optional: true
|
||||
},
|
||||
// Freebusy Parameters
|
||||
{
|
||||
label: 'Time Min',
|
||||
name: 'freebusyTimeMin',
|
||||
type: 'string',
|
||||
description: 'Lower bound for freebusy query (ISO 8601 format)',
|
||||
show: {
|
||||
freebusyActions: ['queryFreebusy']
|
||||
},
|
||||
additionalParams: true,
|
||||
optional: true
|
||||
},
|
||||
{
|
||||
label: 'Time Max',
|
||||
name: 'freebusyTimeMax',
|
||||
type: 'string',
|
||||
description: 'Upper bound for freebusy query (ISO 8601 format)',
|
||||
show: {
|
||||
freebusyActions: ['queryFreebusy']
|
||||
},
|
||||
additionalParams: true,
|
||||
optional: true
|
||||
},
|
||||
{
|
||||
label: 'Calendar IDs',
|
||||
name: 'calendarIds',
|
||||
type: 'string',
|
||||
description: 'Comma-separated list of calendar IDs to check for free/busy info',
|
||||
show: {
|
||||
freebusyActions: ['queryFreebusy']
|
||||
},
|
||||
additionalParams: true,
|
||||
optional: true
|
||||
},
|
||||
{
|
||||
label: 'Group Expansion Max',
|
||||
name: 'groupExpansionMax',
|
||||
type: 'number',
|
||||
description: 'Maximum number of calendars for which FreeBusy information is to be provided',
|
||||
show: {
|
||||
freebusyActions: ['queryFreebusy']
|
||||
},
|
||||
additionalParams: true,
|
||||
optional: true
|
||||
},
|
||||
{
|
||||
label: 'Calendar Expansion Max',
|
||||
name: 'calendarExpansionMax',
|
||||
type: 'number',
|
||||
description: 'Maximum number of events that can be expanded for each calendar',
|
||||
show: {
|
||||
freebusyActions: ['queryFreebusy']
|
||||
},
|
||||
additionalParams: true,
|
||||
optional: true
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
async init(nodeData: INodeData, _: string, options: ICommonObject): Promise<any> {
|
||||
const calendarType = nodeData.inputs?.calendarType as string
|
||||
|
||||
let credentialData = await getCredentialData(nodeData.credential ?? '', options)
|
||||
credentialData = await refreshOAuth2Token(nodeData.credential ?? '', credentialData, options)
|
||||
const accessToken = getCredentialParam('access_token', credentialData, nodeData)
|
||||
|
||||
if (!accessToken) {
|
||||
throw new Error('No access token found in credential')
|
||||
}
|
||||
|
||||
// Get all actions based on type
|
||||
let actions: string[] = []
|
||||
|
||||
if (calendarType === 'event') {
|
||||
actions = convertMultiOptionsToStringArray(nodeData.inputs?.eventActions)
|
||||
} else if (calendarType === 'calendar') {
|
||||
actions = convertMultiOptionsToStringArray(nodeData.inputs?.calendarActions)
|
||||
} else if (calendarType === 'freebusy') {
|
||||
actions = convertMultiOptionsToStringArray(nodeData.inputs?.freebusyActions)
|
||||
}
|
||||
|
||||
// Create default params object based on inputs
|
||||
const defaultParams: any = {}
|
||||
|
||||
// Event-specific default params
|
||||
if (calendarType === 'event') {
|
||||
actions.forEach((action) => {
|
||||
const params: any = {}
|
||||
|
||||
if (nodeData.inputs?.calendarId) params.calendarId = nodeData.inputs.calendarId
|
||||
if (action === 'getEvent' || action === 'updateEvent' || action === 'deleteEvent') {
|
||||
if (nodeData.inputs?.eventId) params.eventId = nodeData.inputs.eventId
|
||||
}
|
||||
if (action === 'createEvent' || action === 'updateEvent') {
|
||||
if (nodeData.inputs?.summary) params.summary = nodeData.inputs.summary
|
||||
if (nodeData.inputs?.description) params.description = nodeData.inputs.description
|
||||
if (nodeData.inputs?.location) params.location = nodeData.inputs.location
|
||||
if (nodeData.inputs?.startDateTime) params.startDateTime = nodeData.inputs.startDateTime
|
||||
if (nodeData.inputs?.endDateTime) params.endDateTime = nodeData.inputs.endDateTime
|
||||
if (nodeData.inputs?.timeZone) params.timeZone = nodeData.inputs.timeZone
|
||||
if (nodeData.inputs?.allDay !== undefined) params.allDay = nodeData.inputs.allDay
|
||||
if (nodeData.inputs?.startDate) params.startDate = nodeData.inputs.startDate
|
||||
if (nodeData.inputs?.endDate) params.endDate = nodeData.inputs.endDate
|
||||
if (nodeData.inputs?.attendees) params.attendees = nodeData.inputs.attendees
|
||||
if (nodeData.inputs?.recurrence) params.recurrence = nodeData.inputs.recurrence
|
||||
if (nodeData.inputs?.reminderMinutes) params.reminderMinutes = nodeData.inputs.reminderMinutes
|
||||
if (nodeData.inputs?.visibility) params.visibility = nodeData.inputs.visibility
|
||||
}
|
||||
if (action === 'quickAddEvent') {
|
||||
if (nodeData.inputs?.quickAddText) params.quickAddText = nodeData.inputs.quickAddText
|
||||
}
|
||||
if (action === 'listEvents') {
|
||||
if (nodeData.inputs?.timeMin) params.timeMin = nodeData.inputs.timeMin
|
||||
if (nodeData.inputs?.timeMax) params.timeMax = nodeData.inputs.timeMax
|
||||
if (nodeData.inputs?.maxResults) params.maxResults = nodeData.inputs.maxResults
|
||||
if (nodeData.inputs?.singleEvents !== undefined) params.singleEvents = nodeData.inputs.singleEvents
|
||||
if (nodeData.inputs?.orderBy) params.orderBy = nodeData.inputs.orderBy
|
||||
if (nodeData.inputs?.query) params.query = nodeData.inputs.query
|
||||
}
|
||||
|
||||
defaultParams[action] = params
|
||||
})
|
||||
}
|
||||
|
||||
// Calendar-specific default params
|
||||
if (calendarType === 'calendar') {
|
||||
actions.forEach((action) => {
|
||||
const params: any = {}
|
||||
|
||||
if (['getCalendar', 'updateCalendar', 'deleteCalendar', 'clearCalendar'].includes(action)) {
|
||||
if (nodeData.inputs?.calendarIdForCalendar) params.calendarId = nodeData.inputs.calendarIdForCalendar
|
||||
}
|
||||
if (action === 'createCalendar' || action === 'updateCalendar') {
|
||||
if (nodeData.inputs?.calendarSummary) params.summary = nodeData.inputs.calendarSummary
|
||||
if (nodeData.inputs?.calendarDescription) params.description = nodeData.inputs.calendarDescription
|
||||
if (nodeData.inputs?.calendarLocation) params.location = nodeData.inputs.calendarLocation
|
||||
if (nodeData.inputs?.calendarTimeZone) params.timeZone = nodeData.inputs.calendarTimeZone
|
||||
}
|
||||
if (action === 'listCalendars') {
|
||||
if (nodeData.inputs?.showHidden !== undefined) params.showHidden = nodeData.inputs.showHidden
|
||||
if (nodeData.inputs?.minAccessRole) params.minAccessRole = nodeData.inputs.minAccessRole
|
||||
}
|
||||
|
||||
defaultParams[action] = params
|
||||
})
|
||||
}
|
||||
|
||||
// Freebusy-specific default params
|
||||
if (calendarType === 'freebusy') {
|
||||
actions.forEach((action) => {
|
||||
const params: any = {}
|
||||
|
||||
if (action === 'queryFreebusy') {
|
||||
if (nodeData.inputs?.freebusyTimeMin) params.timeMin = nodeData.inputs.freebusyTimeMin
|
||||
if (nodeData.inputs?.freebusyTimeMax) params.timeMax = nodeData.inputs.freebusyTimeMax
|
||||
if (nodeData.inputs?.calendarIds) params.calendarIds = nodeData.inputs.calendarIds
|
||||
if (nodeData.inputs?.groupExpansionMax) params.groupExpansionMax = nodeData.inputs.groupExpansionMax
|
||||
if (nodeData.inputs?.calendarExpansionMax) params.calendarExpansionMax = nodeData.inputs.calendarExpansionMax
|
||||
}
|
||||
|
||||
defaultParams[action] = params
|
||||
})
|
||||
}
|
||||
|
||||
const tools = createGoogleCalendarTools({
|
||||
accessToken,
|
||||
actions,
|
||||
defaultParams
|
||||
})
|
||||
|
||||
return tools
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = { nodeClass: GoogleCalendar_Tools }
|
||||
@@ -0,0 +1,864 @@
|
||||
import { z } from 'zod'
|
||||
import fetch from 'node-fetch'
|
||||
import { DynamicStructuredTool } from '../OpenAPIToolkit/core'
|
||||
import { TOOL_ARGS_PREFIX } from '../../../src/agents'
|
||||
|
||||
export const desc = `Use this when you want to access Google Calendar API for managing events and calendars`
|
||||
|
||||
export interface Headers {
|
||||
[key: string]: string
|
||||
}
|
||||
|
||||
export interface Body {
|
||||
[key: string]: any
|
||||
}
|
||||
|
||||
export interface RequestParameters {
|
||||
headers?: Headers
|
||||
body?: Body
|
||||
url?: string
|
||||
description?: string
|
||||
name?: string
|
||||
actions?: string[]
|
||||
accessToken?: string
|
||||
defaultParams?: any
|
||||
}
|
||||
|
||||
// Define schemas for different Google Calendar operations
|
||||
|
||||
// Event Schemas
|
||||
const ListEventsSchema = z.object({
|
||||
calendarId: z.string().default('primary').describe('Calendar ID (use "primary" for primary calendar)'),
|
||||
timeMin: z.string().optional().describe('Lower bound for event search (RFC3339 timestamp)'),
|
||||
timeMax: z.string().optional().describe('Upper bound for event search (RFC3339 timestamp)'),
|
||||
maxResults: z.number().optional().default(250).describe('Maximum number of events to return'),
|
||||
singleEvents: z.boolean().optional().default(true).describe('Whether to expand recurring events into instances'),
|
||||
orderBy: z.enum(['startTime', 'updated']).optional().describe('Order of events returned'),
|
||||
query: z.string().optional().describe('Free text search terms')
|
||||
})
|
||||
|
||||
const CreateEventSchema = z.object({
|
||||
calendarId: z.string().default('primary').describe('Calendar ID where the event will be created'),
|
||||
summary: z.string().describe('Event title/summary'),
|
||||
description: z.string().optional().describe('Event description'),
|
||||
location: z.string().optional().describe('Event location'),
|
||||
startDateTime: z.string().optional().describe('Event start time (ISO 8601 format)'),
|
||||
endDateTime: z.string().optional().describe('Event end time (ISO 8601 format)'),
|
||||
startDate: z.string().optional().describe('Start date for all-day events (YYYY-MM-DD)'),
|
||||
endDate: z.string().optional().describe('End date for all-day events (YYYY-MM-DD)'),
|
||||
timeZone: z.string().optional().describe('Time zone (e.g., America/New_York)'),
|
||||
attendees: z.string().optional().describe('Comma-separated list of attendee emails'),
|
||||
recurrence: z.string().optional().describe('Recurrence rules (RRULE format)'),
|
||||
reminderMinutes: z.number().optional().describe('Minutes before event to send reminder'),
|
||||
visibility: z.enum(['default', 'public', 'private', 'confidential']).optional().describe('Event visibility')
|
||||
})
|
||||
|
||||
const GetEventSchema = z.object({
|
||||
calendarId: z.string().default('primary').describe('Calendar ID'),
|
||||
eventId: z.string().describe('Event ID')
|
||||
})
|
||||
|
||||
const UpdateEventSchema = z.object({
|
||||
calendarId: z.string().default('primary').describe('Calendar ID'),
|
||||
eventId: z.string().describe('Event ID'),
|
||||
summary: z.string().optional().describe('Updated event title/summary'),
|
||||
description: z.string().optional().describe('Updated event description'),
|
||||
location: z.string().optional().describe('Updated event location'),
|
||||
startDateTime: z.string().optional().describe('Updated event start time (ISO 8601 format)'),
|
||||
endDateTime: z.string().optional().describe('Updated event end time (ISO 8601 format)'),
|
||||
startDate: z.string().optional().describe('Updated start date for all-day events (YYYY-MM-DD)'),
|
||||
endDate: z.string().optional().describe('Updated end date for all-day events (YYYY-MM-DD)'),
|
||||
timeZone: z.string().optional().describe('Updated time zone'),
|
||||
attendees: z.string().optional().describe('Updated comma-separated list of attendee emails'),
|
||||
recurrence: z.string().optional().describe('Updated recurrence rules'),
|
||||
reminderMinutes: z.number().optional().describe('Updated reminder minutes'),
|
||||
visibility: z.enum(['default', 'public', 'private', 'confidential']).optional().describe('Updated event visibility')
|
||||
})
|
||||
|
||||
const DeleteEventSchema = z.object({
|
||||
calendarId: z.string().default('primary').describe('Calendar ID'),
|
||||
eventId: z.string().describe('Event ID to delete')
|
||||
})
|
||||
|
||||
const QuickAddEventSchema = z.object({
|
||||
calendarId: z.string().default('primary').describe('Calendar ID'),
|
||||
quickAddText: z.string().describe('Natural language text for quick event creation')
|
||||
})
|
||||
|
||||
// Calendar Schemas
|
||||
const ListCalendarsSchema = z.object({
|
||||
showHidden: z.boolean().optional().describe('Whether to show hidden calendars'),
|
||||
minAccessRole: z.enum(['freeBusyReader', 'reader', 'writer', 'owner']).optional().describe('Minimum access role')
|
||||
})
|
||||
|
||||
const CreateCalendarSchema = z.object({
|
||||
summary: z.string().describe('Calendar title/name'),
|
||||
description: z.string().optional().describe('Calendar description'),
|
||||
location: z.string().optional().describe('Calendar location'),
|
||||
timeZone: z.string().optional().describe('Calendar time zone (e.g., America/New_York)')
|
||||
})
|
||||
|
||||
const GetCalendarSchema = z.object({
|
||||
calendarId: z.string().describe('Calendar ID')
|
||||
})
|
||||
|
||||
const UpdateCalendarSchema = z.object({
|
||||
calendarId: z.string().describe('Calendar ID'),
|
||||
summary: z.string().optional().describe('Updated calendar title/name'),
|
||||
description: z.string().optional().describe('Updated calendar description'),
|
||||
location: z.string().optional().describe('Updated calendar location'),
|
||||
timeZone: z.string().optional().describe('Updated calendar time zone')
|
||||
})
|
||||
|
||||
const DeleteCalendarSchema = z.object({
|
||||
calendarId: z.string().describe('Calendar ID to delete')
|
||||
})
|
||||
|
||||
const ClearCalendarSchema = z.object({
|
||||
calendarId: z.string().describe('Calendar ID to clear (removes all events)')
|
||||
})
|
||||
|
||||
// Freebusy Schemas
|
||||
const QueryFreebusySchema = z.object({
|
||||
timeMin: z.string().describe('Lower bound for freebusy query (RFC3339 timestamp)'),
|
||||
timeMax: z.string().describe('Upper bound for freebusy query (RFC3339 timestamp)'),
|
||||
calendarIds: z.string().describe('Comma-separated list of calendar IDs to check for free/busy info'),
|
||||
groupExpansionMax: z.number().optional().describe('Maximum number of calendars for which FreeBusy information is to be provided'),
|
||||
calendarExpansionMax: z.number().optional().describe('Maximum number of events that can be expanded for each calendar')
|
||||
})
|
||||
|
||||
class BaseGoogleCalendarTool extends DynamicStructuredTool {
|
||||
protected accessToken: string = ''
|
||||
|
||||
constructor(args: any) {
|
||||
super(args)
|
||||
this.accessToken = args.accessToken ?? ''
|
||||
}
|
||||
|
||||
async makeGoogleCalendarRequest({
|
||||
endpoint,
|
||||
method = 'GET',
|
||||
body,
|
||||
params
|
||||
}: {
|
||||
endpoint: string
|
||||
method?: string
|
||||
body?: any
|
||||
params?: any
|
||||
}): Promise<string> {
|
||||
const url = `https://www.googleapis.com/calendar/v3/${endpoint}`
|
||||
|
||||
const headers = {
|
||||
Authorization: `Bearer ${this.accessToken}`,
|
||||
'Content-Type': 'application/json',
|
||||
Accept: 'application/json',
|
||||
...this.headers
|
||||
}
|
||||
|
||||
const response = await fetch(url, {
|
||||
method,
|
||||
headers,
|
||||
body: body ? JSON.stringify(body) : undefined
|
||||
})
|
||||
|
||||
if (!response.ok) {
|
||||
const errorText = await response.text()
|
||||
throw new Error(`Google Calendar API Error ${response.status}: ${response.statusText} - ${errorText}`)
|
||||
}
|
||||
|
||||
const data = await response.text()
|
||||
return data + TOOL_ARGS_PREFIX + JSON.stringify(params)
|
||||
}
|
||||
}
|
||||
|
||||
// Event Tools
|
||||
class ListEventsTool extends BaseGoogleCalendarTool {
|
||||
defaultParams: any
|
||||
|
||||
constructor(args: any) {
|
||||
const toolInput = {
|
||||
name: 'list_events',
|
||||
description: 'List events from Google Calendar',
|
||||
schema: ListEventsSchema,
|
||||
baseUrl: '',
|
||||
method: 'GET',
|
||||
headers: {}
|
||||
}
|
||||
super({
|
||||
...toolInput,
|
||||
accessToken: args.accessToken
|
||||
})
|
||||
this.defaultParams = args.defaultParams || {}
|
||||
}
|
||||
|
||||
async _call(arg: any): Promise<string> {
|
||||
const params = { ...arg, ...this.defaultParams }
|
||||
const queryParams = new URLSearchParams()
|
||||
|
||||
if (params.timeMin) queryParams.append('timeMin', params.timeMin)
|
||||
if (params.timeMax) queryParams.append('timeMax', params.timeMax)
|
||||
if (params.maxResults) queryParams.append('maxResults', params.maxResults.toString())
|
||||
if (params.singleEvents !== undefined) queryParams.append('singleEvents', params.singleEvents.toString())
|
||||
if (params.orderBy) queryParams.append('orderBy', params.orderBy)
|
||||
if (params.query) queryParams.append('q', params.query)
|
||||
|
||||
const endpoint = `calendars/${encodeURIComponent(params.calendarId)}/events?${queryParams.toString()}`
|
||||
|
||||
try {
|
||||
const response = await this.makeGoogleCalendarRequest({ endpoint, params })
|
||||
return response
|
||||
} catch (error) {
|
||||
return `Error listing events: ${error}`
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class CreateEventTool extends BaseGoogleCalendarTool {
|
||||
defaultParams: any
|
||||
|
||||
constructor(args: any) {
|
||||
const toolInput = {
|
||||
name: 'create_event',
|
||||
description: 'Create a new event in Google Calendar',
|
||||
schema: CreateEventSchema,
|
||||
baseUrl: '',
|
||||
method: 'POST',
|
||||
headers: {}
|
||||
}
|
||||
super({
|
||||
...toolInput,
|
||||
accessToken: args.accessToken
|
||||
})
|
||||
this.defaultParams = args.defaultParams || {}
|
||||
}
|
||||
|
||||
async _call(arg: any): Promise<string> {
|
||||
const params = { ...arg, ...this.defaultParams }
|
||||
|
||||
try {
|
||||
const eventData: any = {
|
||||
summary: params.summary
|
||||
}
|
||||
|
||||
if (params.description) eventData.description = params.description
|
||||
if (params.location) eventData.location = params.location
|
||||
|
||||
// Handle date/time
|
||||
if (params.startDate && params.endDate) {
|
||||
// All-day event
|
||||
eventData.start = { date: params.startDate }
|
||||
eventData.end = { date: params.endDate }
|
||||
} else if (params.startDateTime && params.endDateTime) {
|
||||
// Timed event
|
||||
eventData.start = {
|
||||
dateTime: params.startDateTime,
|
||||
timeZone: params.timeZone || 'UTC'
|
||||
}
|
||||
eventData.end = {
|
||||
dateTime: params.endDateTime,
|
||||
timeZone: params.timeZone || 'UTC'
|
||||
}
|
||||
}
|
||||
|
||||
// Handle attendees
|
||||
if (params.attendees) {
|
||||
eventData.attendees = params.attendees.split(',').map((email: string) => ({
|
||||
email: email.trim()
|
||||
}))
|
||||
}
|
||||
|
||||
// Handle recurrence
|
||||
if (params.recurrence) {
|
||||
eventData.recurrence = [params.recurrence]
|
||||
}
|
||||
|
||||
// Handle reminders
|
||||
if (params.reminderMinutes !== undefined) {
|
||||
eventData.reminders = {
|
||||
useDefault: false,
|
||||
overrides: [
|
||||
{
|
||||
method: 'popup',
|
||||
minutes: params.reminderMinutes
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
if (params.visibility) eventData.visibility = params.visibility
|
||||
|
||||
const endpoint = `calendars/${encodeURIComponent(params.calendarId)}/events`
|
||||
const response = await this.makeGoogleCalendarRequest({ endpoint, method: 'POST', body: eventData, params })
|
||||
return response
|
||||
} catch (error) {
|
||||
return `Error creating event: ${error}`
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class GetEventTool extends BaseGoogleCalendarTool {
|
||||
defaultParams: any
|
||||
|
||||
constructor(args: any) {
|
||||
const toolInput = {
|
||||
name: 'get_event',
|
||||
description: 'Get a specific event from Google Calendar',
|
||||
schema: GetEventSchema,
|
||||
baseUrl: '',
|
||||
method: 'GET',
|
||||
headers: {}
|
||||
}
|
||||
super({
|
||||
...toolInput,
|
||||
accessToken: args.accessToken
|
||||
})
|
||||
this.defaultParams = args.defaultParams || {}
|
||||
}
|
||||
|
||||
async _call(arg: any): Promise<string> {
|
||||
const params = { ...arg, ...this.defaultParams }
|
||||
|
||||
try {
|
||||
const endpoint = `calendars/${encodeURIComponent(params.calendarId)}/events/${encodeURIComponent(params.eventId)}`
|
||||
const response = await this.makeGoogleCalendarRequest({ endpoint, params })
|
||||
return response
|
||||
} catch (error) {
|
||||
return `Error getting event: ${error}`
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class UpdateEventTool extends BaseGoogleCalendarTool {
|
||||
defaultParams: any
|
||||
|
||||
constructor(args: any) {
|
||||
const toolInput = {
|
||||
name: 'update_event',
|
||||
description: 'Update an existing event in Google Calendar',
|
||||
schema: UpdateEventSchema,
|
||||
baseUrl: '',
|
||||
method: 'PUT',
|
||||
headers: {}
|
||||
}
|
||||
super({
|
||||
...toolInput,
|
||||
accessToken: args.accessToken
|
||||
})
|
||||
this.defaultParams = args.defaultParams || {}
|
||||
}
|
||||
|
||||
async _call(arg: any): Promise<string> {
|
||||
const params = { ...arg, ...this.defaultParams }
|
||||
|
||||
try {
|
||||
const updateData: any = {}
|
||||
|
||||
if (params.summary) updateData.summary = params.summary
|
||||
if (params.description) updateData.description = params.description
|
||||
if (params.location) updateData.location = params.location
|
||||
|
||||
// Handle date/time updates
|
||||
if (params.startDate && params.endDate) {
|
||||
updateData.start = { date: params.startDate }
|
||||
updateData.end = { date: params.endDate }
|
||||
} else if (params.startDateTime && params.endDateTime) {
|
||||
updateData.start = {
|
||||
dateTime: params.startDateTime,
|
||||
timeZone: params.timeZone || 'UTC'
|
||||
}
|
||||
updateData.end = {
|
||||
dateTime: params.endDateTime,
|
||||
timeZone: params.timeZone || 'UTC'
|
||||
}
|
||||
}
|
||||
|
||||
if (params.attendees) {
|
||||
updateData.attendees = params.attendees.split(',').map((email: string) => ({
|
||||
email: email.trim()
|
||||
}))
|
||||
}
|
||||
|
||||
if (params.recurrence) {
|
||||
updateData.recurrence = [params.recurrence]
|
||||
}
|
||||
|
||||
if (params.reminderMinutes !== undefined) {
|
||||
updateData.reminders = {
|
||||
useDefault: false,
|
||||
overrides: [
|
||||
{
|
||||
method: 'popup',
|
||||
minutes: params.reminderMinutes
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
if (params.visibility) updateData.visibility = params.visibility
|
||||
|
||||
const endpoint = `calendars/${encodeURIComponent(params.calendarId)}/events/${encodeURIComponent(params.eventId)}`
|
||||
const response = await this.makeGoogleCalendarRequest({ endpoint, method: 'PUT', body: updateData, params })
|
||||
return response
|
||||
} catch (error) {
|
||||
return `Error updating event: ${error}`
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class DeleteEventTool extends BaseGoogleCalendarTool {
|
||||
defaultParams: any
|
||||
|
||||
constructor(args: any) {
|
||||
const toolInput = {
|
||||
name: 'delete_event',
|
||||
description: 'Delete an event from Google Calendar',
|
||||
schema: DeleteEventSchema,
|
||||
baseUrl: '',
|
||||
method: 'DELETE',
|
||||
headers: {}
|
||||
}
|
||||
super({
|
||||
...toolInput,
|
||||
accessToken: args.accessToken
|
||||
})
|
||||
this.defaultParams = args.defaultParams || {}
|
||||
}
|
||||
|
||||
async _call(arg: any): Promise<string> {
|
||||
const params = { ...arg, ...this.defaultParams }
|
||||
|
||||
try {
|
||||
const endpoint = `calendars/${encodeURIComponent(params.calendarId)}/events/${encodeURIComponent(params.eventId)}`
|
||||
const response = await this.makeGoogleCalendarRequest({ endpoint, method: 'DELETE', params })
|
||||
return response || 'Event deleted successfully'
|
||||
} catch (error) {
|
||||
return `Error deleting event: ${error}`
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class QuickAddEventTool extends BaseGoogleCalendarTool {
|
||||
defaultParams: any
|
||||
|
||||
constructor(args: any) {
|
||||
const toolInput = {
|
||||
name: 'quick_add_event',
|
||||
description: 'Quick add event to Google Calendar using natural language',
|
||||
schema: QuickAddEventSchema,
|
||||
baseUrl: '',
|
||||
method: 'POST',
|
||||
headers: {}
|
||||
}
|
||||
super({
|
||||
...toolInput,
|
||||
accessToken: args.accessToken
|
||||
})
|
||||
this.defaultParams = args.defaultParams || {}
|
||||
}
|
||||
|
||||
async _call(arg: any): Promise<string> {
|
||||
const params = { ...arg, ...this.defaultParams }
|
||||
|
||||
try {
|
||||
const queryParams = new URLSearchParams()
|
||||
queryParams.append('text', params.quickAddText)
|
||||
|
||||
const endpoint = `calendars/${encodeURIComponent(params.calendarId)}/events/quickAdd?${queryParams.toString()}`
|
||||
const response = await this.makeGoogleCalendarRequest({ endpoint, method: 'POST', params })
|
||||
return response
|
||||
} catch (error) {
|
||||
return `Error quick adding event: ${error}`
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Calendar Tools
|
||||
class ListCalendarsTool extends BaseGoogleCalendarTool {
|
||||
defaultParams: any
|
||||
|
||||
constructor(args: any) {
|
||||
const toolInput = {
|
||||
name: 'list_calendars',
|
||||
description: 'List calendars from Google Calendar',
|
||||
schema: ListCalendarsSchema,
|
||||
baseUrl: '',
|
||||
method: 'GET',
|
||||
headers: {}
|
||||
}
|
||||
super({
|
||||
...toolInput,
|
||||
accessToken: args.accessToken
|
||||
})
|
||||
this.defaultParams = args.defaultParams || {}
|
||||
}
|
||||
|
||||
async _call(arg: any): Promise<string> {
|
||||
const params = { ...arg, ...this.defaultParams }
|
||||
const queryParams = new URLSearchParams()
|
||||
|
||||
if (params.showHidden !== undefined) queryParams.append('showHidden', params.showHidden.toString())
|
||||
if (params.minAccessRole) queryParams.append('minAccessRole', params.minAccessRole)
|
||||
|
||||
const endpoint = `users/me/calendarList?${queryParams.toString()}`
|
||||
|
||||
try {
|
||||
const response = await this.makeGoogleCalendarRequest({ endpoint, params })
|
||||
return response
|
||||
} catch (error) {
|
||||
return `Error listing calendars: ${error}`
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class CreateCalendarTool extends BaseGoogleCalendarTool {
|
||||
defaultParams: any
|
||||
|
||||
constructor(args: any) {
|
||||
const toolInput = {
|
||||
name: 'create_calendar',
|
||||
description: 'Create a new calendar in Google Calendar',
|
||||
schema: CreateCalendarSchema,
|
||||
baseUrl: '',
|
||||
method: 'POST',
|
||||
headers: {}
|
||||
}
|
||||
super({
|
||||
...toolInput,
|
||||
accessToken: args.accessToken
|
||||
})
|
||||
this.defaultParams = args.defaultParams || {}
|
||||
}
|
||||
|
||||
async _call(arg: any): Promise<string> {
|
||||
const params = { ...arg, ...this.defaultParams }
|
||||
|
||||
try {
|
||||
const calendarData: any = {
|
||||
summary: params.summary
|
||||
}
|
||||
|
||||
if (params.description) calendarData.description = params.description
|
||||
if (params.location) calendarData.location = params.location
|
||||
if (params.timeZone) calendarData.timeZone = params.timeZone
|
||||
|
||||
const endpoint = 'calendars'
|
||||
const response = await this.makeGoogleCalendarRequest({ endpoint, method: 'POST', body: calendarData, params })
|
||||
return response
|
||||
} catch (error) {
|
||||
return `Error creating calendar: ${error}`
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class GetCalendarTool extends BaseGoogleCalendarTool {
|
||||
defaultParams: any
|
||||
|
||||
constructor(args: any) {
|
||||
const toolInput = {
|
||||
name: 'get_calendar',
|
||||
description: 'Get a specific calendar from Google Calendar',
|
||||
schema: GetCalendarSchema,
|
||||
baseUrl: '',
|
||||
method: 'GET',
|
||||
headers: {}
|
||||
}
|
||||
super({
|
||||
...toolInput,
|
||||
accessToken: args.accessToken
|
||||
})
|
||||
this.defaultParams = args.defaultParams || {}
|
||||
}
|
||||
|
||||
async _call(arg: any): Promise<string> {
|
||||
const params = { ...arg, ...this.defaultParams }
|
||||
|
||||
try {
|
||||
const endpoint = `calendars/${encodeURIComponent(params.calendarId)}`
|
||||
const response = await this.makeGoogleCalendarRequest({ endpoint, params })
|
||||
return response
|
||||
} catch (error) {
|
||||
return `Error getting calendar: ${error}`
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class UpdateCalendarTool extends BaseGoogleCalendarTool {
|
||||
defaultParams: any
|
||||
|
||||
constructor(args: any) {
|
||||
const toolInput = {
|
||||
name: 'update_calendar',
|
||||
description: 'Update an existing calendar in Google Calendar',
|
||||
schema: UpdateCalendarSchema,
|
||||
baseUrl: '',
|
||||
method: 'PUT',
|
||||
headers: {}
|
||||
}
|
||||
super({
|
||||
...toolInput,
|
||||
accessToken: args.accessToken
|
||||
})
|
||||
this.defaultParams = args.defaultParams || {}
|
||||
}
|
||||
|
||||
async _call(arg: any): Promise<string> {
|
||||
const params = { ...arg, ...this.defaultParams }
|
||||
|
||||
try {
|
||||
const updateData: any = {}
|
||||
|
||||
if (params.summary) updateData.summary = params.summary
|
||||
if (params.description) updateData.description = params.description
|
||||
if (params.location) updateData.location = params.location
|
||||
if (params.timeZone) updateData.timeZone = params.timeZone
|
||||
|
||||
const endpoint = `calendars/${encodeURIComponent(params.calendarId)}`
|
||||
const response = await this.makeGoogleCalendarRequest({ endpoint, method: 'PUT', body: updateData, params })
|
||||
return response
|
||||
} catch (error) {
|
||||
return `Error updating calendar: ${error}`
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class DeleteCalendarTool extends BaseGoogleCalendarTool {
|
||||
defaultParams: any
|
||||
|
||||
constructor(args: any) {
|
||||
const toolInput = {
|
||||
name: 'delete_calendar',
|
||||
description: 'Delete a calendar from Google Calendar',
|
||||
schema: DeleteCalendarSchema,
|
||||
baseUrl: '',
|
||||
method: 'DELETE',
|
||||
headers: {}
|
||||
}
|
||||
super({
|
||||
...toolInput,
|
||||
accessToken: args.accessToken
|
||||
})
|
||||
this.defaultParams = args.defaultParams || {}
|
||||
}
|
||||
|
||||
async _call(arg: any): Promise<string> {
|
||||
const params = { ...arg, ...this.defaultParams }
|
||||
|
||||
try {
|
||||
const endpoint = `calendars/${encodeURIComponent(params.calendarId)}`
|
||||
const response = await this.makeGoogleCalendarRequest({ endpoint, method: 'DELETE', params })
|
||||
return response || 'Calendar deleted successfully'
|
||||
} catch (error) {
|
||||
return `Error deleting calendar: ${error}`
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class ClearCalendarTool extends BaseGoogleCalendarTool {
|
||||
defaultParams: any
|
||||
|
||||
constructor(args: any) {
|
||||
const toolInput = {
|
||||
name: 'clear_calendar',
|
||||
description: 'Clear all events from a Google Calendar',
|
||||
schema: ClearCalendarSchema,
|
||||
baseUrl: '',
|
||||
method: 'POST',
|
||||
headers: {}
|
||||
}
|
||||
super({
|
||||
...toolInput,
|
||||
accessToken: args.accessToken
|
||||
})
|
||||
this.defaultParams = args.defaultParams || {}
|
||||
}
|
||||
|
||||
async _call(arg: any): Promise<string> {
|
||||
const params = { ...arg, ...this.defaultParams }
|
||||
|
||||
try {
|
||||
const endpoint = `calendars/${encodeURIComponent(params.calendarId)}/clear`
|
||||
const response = await this.makeGoogleCalendarRequest({ endpoint, method: 'POST', params })
|
||||
return response || 'Calendar cleared successfully'
|
||||
} catch (error) {
|
||||
return `Error clearing calendar: ${error}`
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Freebusy Tools
|
||||
class QueryFreebusyTool extends BaseGoogleCalendarTool {
|
||||
defaultParams: any
|
||||
|
||||
constructor(args: any) {
|
||||
const toolInput = {
|
||||
name: 'query_freebusy',
|
||||
description: 'Query free/busy information for a set of calendars',
|
||||
schema: QueryFreebusySchema,
|
||||
baseUrl: '',
|
||||
method: 'POST',
|
||||
headers: {}
|
||||
}
|
||||
super({
|
||||
...toolInput,
|
||||
accessToken: args.accessToken
|
||||
})
|
||||
this.defaultParams = args.defaultParams || {}
|
||||
}
|
||||
|
||||
async _call(arg: any): Promise<string> {
|
||||
const params = { ...arg, ...this.defaultParams }
|
||||
|
||||
try {
|
||||
const freebusyData: any = {
|
||||
timeMin: params.timeMin,
|
||||
timeMax: params.timeMax,
|
||||
items: params.calendarIds.split(',').map((id: string) => ({
|
||||
id: id.trim()
|
||||
}))
|
||||
}
|
||||
|
||||
if (params.groupExpansionMax !== undefined) {
|
||||
freebusyData.groupExpansionMax = params.groupExpansionMax
|
||||
}
|
||||
|
||||
if (params.calendarExpansionMax !== undefined) {
|
||||
freebusyData.calendarExpansionMax = params.calendarExpansionMax
|
||||
}
|
||||
|
||||
const endpoint = 'freeBusy'
|
||||
const response = await this.makeGoogleCalendarRequest({ endpoint, method: 'POST', body: freebusyData, params })
|
||||
return response
|
||||
} catch (error) {
|
||||
return `Error querying freebusy: ${error}`
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const createGoogleCalendarTools = (args?: RequestParameters): DynamicStructuredTool[] => {
|
||||
const tools: DynamicStructuredTool[] = []
|
||||
const actions = args?.actions || []
|
||||
const accessToken = args?.accessToken || ''
|
||||
const defaultParams = args?.defaultParams || {}
|
||||
|
||||
// Event tools
|
||||
if (actions.includes('listEvents')) {
|
||||
tools.push(
|
||||
new ListEventsTool({
|
||||
accessToken,
|
||||
defaultParams: defaultParams.listEvents
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
if (actions.includes('createEvent')) {
|
||||
tools.push(
|
||||
new CreateEventTool({
|
||||
accessToken,
|
||||
defaultParams: defaultParams.createEvent
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
if (actions.includes('getEvent')) {
|
||||
tools.push(
|
||||
new GetEventTool({
|
||||
accessToken,
|
||||
defaultParams: defaultParams.getEvent
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
if (actions.includes('updateEvent')) {
|
||||
tools.push(
|
||||
new UpdateEventTool({
|
||||
accessToken,
|
||||
defaultParams: defaultParams.updateEvent
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
if (actions.includes('deleteEvent')) {
|
||||
tools.push(
|
||||
new DeleteEventTool({
|
||||
accessToken,
|
||||
defaultParams: defaultParams.deleteEvent
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
if (actions.includes('quickAddEvent')) {
|
||||
tools.push(
|
||||
new QuickAddEventTool({
|
||||
accessToken,
|
||||
defaultParams: defaultParams.quickAddEvent
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
// Calendar tools
|
||||
if (actions.includes('listCalendars')) {
|
||||
tools.push(
|
||||
new ListCalendarsTool({
|
||||
accessToken,
|
||||
defaultParams: defaultParams.listCalendars
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
if (actions.includes('createCalendar')) {
|
||||
tools.push(
|
||||
new CreateCalendarTool({
|
||||
accessToken,
|
||||
defaultParams: defaultParams.createCalendar
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
if (actions.includes('getCalendar')) {
|
||||
tools.push(
|
||||
new GetCalendarTool({
|
||||
accessToken,
|
||||
defaultParams: defaultParams.getCalendar
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
if (actions.includes('updateCalendar')) {
|
||||
tools.push(
|
||||
new UpdateCalendarTool({
|
||||
accessToken,
|
||||
defaultParams: defaultParams.updateCalendar
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
if (actions.includes('deleteCalendar')) {
|
||||
tools.push(
|
||||
new DeleteCalendarTool({
|
||||
accessToken,
|
||||
defaultParams: defaultParams.deleteCalendar
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
if (actions.includes('clearCalendar')) {
|
||||
tools.push(
|
||||
new ClearCalendarTool({
|
||||
accessToken,
|
||||
defaultParams: defaultParams.clearCalendar
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
// Freebusy tools
|
||||
if (actions.includes('queryFreebusy')) {
|
||||
tools.push(
|
||||
new QueryFreebusyTool({
|
||||
accessToken,
|
||||
defaultParams: defaultParams.queryFreebusy
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
return tools
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48" width="96px" height="96px"><rect width="22" height="22" x="13" y="13" fill="#fff"/><polygon fill="#1e88e5" points="25.68,20.92 26.688,22.36 28.272,21.208 28.272,29.56 30,29.56 30,18.616 28.56,18.616"/><path fill="#1e88e5" d="M22.943,23.745c0.625-0.574,1.013-1.37,1.013-2.249c0-1.747-1.533-3.168-3.417-3.168 c-1.602,0-2.972,1.009-3.33,2.453l1.657,0.421c0.165-0.664,0.868-1.146,1.673-1.146c0.942,0,1.709,0.646,1.709,1.44 c0,0.794-0.767,1.44-1.709,1.44h-0.997v1.728h0.997c1.081,0,1.993,0.751,1.993,1.64c0,0.904-0.866,1.64-1.931,1.64 c-0.962,0-1.784-0.61-1.914-1.418L17,26.802c0.262,1.636,1.81,2.87,3.6,2.87c2.007,0,3.64-1.511,3.64-3.368 C24.24,25.281,23.736,24.363,22.943,23.745z"/><polygon fill="#fbc02d" points="34,42 14,42 13,38 14,34 34,34 35,38"/><polygon fill="#4caf50" points="38,35 42,34 42,14 38,13 34,14 34,34"/><path fill="#1e88e5" d="M34,14l1-4l-1-4H9C7.343,6,6,7.343,6,9v25l4,1l4-1V14H34z"/><polygon fill="#e53935" points="34,34 34,42 42,34"/><path fill="#1565c0" d="M39,6h-5v8h8V9C42,7.343,40.657,6,39,6z"/><path fill="#1565c0" d="M9,42h5v-8H6v5C6,40.657,7.343,42,9,42z"/></svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
Reference in New Issue
Block a user