mirror of
https://github.com/farcasclaudiu/Flowise.git
synced 2026-06-24 13:00:45 +03:00
30c4180d97
* 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.
632 lines
20 KiB
TypeScript
632 lines
20 KiB
TypeScript
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 Sheets API for managing spreadsheets and values`
|
|
|
|
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 Sheets operations
|
|
|
|
// Spreadsheet Schemas
|
|
const CreateSpreadsheetSchema = z.object({
|
|
title: z.string().describe('The title of the spreadsheet'),
|
|
sheetCount: z.number().optional().default(1).describe('Number of sheets to create'),
|
|
locale: z.string().optional().describe('The locale of the spreadsheet (e.g., en_US)'),
|
|
timeZone: z.string().optional().describe('The time zone of the spreadsheet (e.g., America/New_York)')
|
|
})
|
|
|
|
const GetSpreadsheetSchema = z.object({
|
|
spreadsheetId: z.string().describe('The ID of the spreadsheet to retrieve'),
|
|
ranges: z.string().optional().describe('Comma-separated list of ranges to retrieve'),
|
|
includeGridData: z.boolean().optional().default(false).describe('True if grid data should be returned')
|
|
})
|
|
|
|
const UpdateSpreadsheetSchema = z.object({
|
|
spreadsheetId: z.string().describe('The ID of the spreadsheet to update'),
|
|
title: z.string().optional().describe('New title for the spreadsheet'),
|
|
locale: z.string().optional().describe('New locale for the spreadsheet'),
|
|
timeZone: z.string().optional().describe('New time zone for the spreadsheet')
|
|
})
|
|
|
|
// Values Schemas
|
|
const GetValuesSchema = z.object({
|
|
spreadsheetId: z.string().describe('The ID of the spreadsheet'),
|
|
range: z.string().describe('The A1 notation of the range to retrieve values from'),
|
|
valueRenderOption: z
|
|
.enum(['FORMATTED_VALUE', 'UNFORMATTED_VALUE', 'FORMULA'])
|
|
.optional()
|
|
.default('FORMATTED_VALUE')
|
|
.describe('How values should be represented'),
|
|
dateTimeRenderOption: z
|
|
.enum(['SERIAL_NUMBER', 'FORMATTED_STRING'])
|
|
.optional()
|
|
.default('FORMATTED_STRING')
|
|
.describe('How dates should be represented'),
|
|
majorDimension: z.enum(['ROWS', 'COLUMNS']).optional().default('ROWS').describe('The major dimension that results should use')
|
|
})
|
|
|
|
const UpdateValuesSchema = z.object({
|
|
spreadsheetId: z.string().describe('The ID of the spreadsheet'),
|
|
range: z.string().describe('The A1 notation of the range to update'),
|
|
values: z.string().describe('JSON array of values to write (e.g., [["A1", "B1"], ["A2", "B2"]])'),
|
|
valueInputOption: z.enum(['RAW', 'USER_ENTERED']).optional().default('USER_ENTERED').describe('How input data should be interpreted'),
|
|
majorDimension: z.enum(['ROWS', 'COLUMNS']).optional().default('ROWS').describe('The major dimension of the values')
|
|
})
|
|
|
|
const AppendValuesSchema = z.object({
|
|
spreadsheetId: z.string().describe('The ID of the spreadsheet'),
|
|
range: z.string().describe('The A1 notation of the range to append to'),
|
|
values: z.string().describe('JSON array of values to append'),
|
|
valueInputOption: z.enum(['RAW', 'USER_ENTERED']).optional().default('USER_ENTERED').describe('How input data should be interpreted'),
|
|
insertDataOption: z.enum(['OVERWRITE', 'INSERT_ROWS']).optional().default('OVERWRITE').describe('How data should be inserted'),
|
|
majorDimension: z.enum(['ROWS', 'COLUMNS']).optional().default('ROWS').describe('The major dimension of the values')
|
|
})
|
|
|
|
const ClearValuesSchema = z.object({
|
|
spreadsheetId: z.string().describe('The ID of the spreadsheet'),
|
|
range: z.string().describe('The A1 notation of the range to clear')
|
|
})
|
|
|
|
const BatchGetValuesSchema = z.object({
|
|
spreadsheetId: z.string().describe('The ID of the spreadsheet'),
|
|
ranges: z.string().describe('Comma-separated list of ranges to retrieve'),
|
|
valueRenderOption: z
|
|
.enum(['FORMATTED_VALUE', 'UNFORMATTED_VALUE', 'FORMULA'])
|
|
.optional()
|
|
.default('FORMATTED_VALUE')
|
|
.describe('How values should be represented'),
|
|
dateTimeRenderOption: z
|
|
.enum(['SERIAL_NUMBER', 'FORMATTED_STRING'])
|
|
.optional()
|
|
.default('FORMATTED_STRING')
|
|
.describe('How dates should be represented'),
|
|
majorDimension: z.enum(['ROWS', 'COLUMNS']).optional().default('ROWS').describe('The major dimension that results should use')
|
|
})
|
|
|
|
const BatchUpdateValuesSchema = z.object({
|
|
spreadsheetId: z.string().describe('The ID of the spreadsheet'),
|
|
valueInputOption: z.enum(['RAW', 'USER_ENTERED']).optional().default('USER_ENTERED').describe('How input data should be interpreted'),
|
|
values: z
|
|
.string()
|
|
.describe('JSON array of value ranges to update (e.g., [{"range": "A1:B2", "values": [["A1", "B1"], ["A2", "B2"]]}])'),
|
|
includeValuesInResponse: z.boolean().optional().default(false).describe('Whether to return the updated values in the response')
|
|
})
|
|
|
|
const BatchClearValuesSchema = z.object({
|
|
spreadsheetId: z.string().describe('The ID of the spreadsheet'),
|
|
ranges: z.string().describe('Comma-separated list of ranges to clear')
|
|
})
|
|
|
|
class BaseGoogleSheetsTool extends DynamicStructuredTool {
|
|
protected accessToken: string = ''
|
|
|
|
constructor(args: any) {
|
|
super(args)
|
|
this.accessToken = args.accessToken ?? ''
|
|
}
|
|
|
|
async makeGoogleSheetsRequest({
|
|
endpoint,
|
|
method = 'GET',
|
|
body,
|
|
params
|
|
}: {
|
|
endpoint: string
|
|
method?: string
|
|
body?: any
|
|
params?: any
|
|
}): Promise<string> {
|
|
const url = `https://sheets.googleapis.com/v4/${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 Sheets API Error ${response.status}: ${response.statusText} - ${errorText}`)
|
|
}
|
|
|
|
const data = await response.text()
|
|
return data + TOOL_ARGS_PREFIX + JSON.stringify(params)
|
|
}
|
|
}
|
|
|
|
// Spreadsheet Tools
|
|
class CreateSpreadsheetTool extends BaseGoogleSheetsTool {
|
|
defaultParams: any
|
|
|
|
constructor(args: any) {
|
|
const toolInput = {
|
|
name: 'create_spreadsheet',
|
|
description: 'Create a new Google Spreadsheet',
|
|
schema: CreateSpreadsheetSchema,
|
|
baseUrl: '',
|
|
method: 'POST',
|
|
headers: {}
|
|
}
|
|
super({
|
|
...toolInput,
|
|
accessToken: args.accessToken
|
|
})
|
|
this.defaultParams = args.defaultParams || {}
|
|
}
|
|
|
|
async _call(arg: any): Promise<string> {
|
|
const params = { ...arg, ...this.defaultParams }
|
|
|
|
const body: any = {
|
|
properties: {
|
|
title: params.title
|
|
}
|
|
}
|
|
|
|
if (params.locale) body.properties.locale = params.locale
|
|
if (params.timeZone) body.properties.timeZone = params.timeZone
|
|
|
|
// Add sheets if specified
|
|
if (params.sheetCount && params.sheetCount > 1) {
|
|
body.sheets = []
|
|
for (let i = 0; i < params.sheetCount; i++) {
|
|
body.sheets.push({
|
|
properties: {
|
|
title: i === 0 ? 'Sheet1' : `Sheet${i + 1}`
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
return await this.makeGoogleSheetsRequest({
|
|
endpoint: 'spreadsheets',
|
|
method: 'POST',
|
|
body,
|
|
params
|
|
})
|
|
}
|
|
}
|
|
|
|
class GetSpreadsheetTool extends BaseGoogleSheetsTool {
|
|
defaultParams: any
|
|
|
|
constructor(args: any) {
|
|
const toolInput = {
|
|
name: 'get_spreadsheet',
|
|
description: 'Get a Google Spreadsheet by ID',
|
|
schema: GetSpreadsheetSchema,
|
|
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.ranges) {
|
|
params.ranges.split(',').forEach((range: string) => {
|
|
queryParams.append('ranges', range.trim())
|
|
})
|
|
}
|
|
if (params.includeGridData) queryParams.append('includeGridData', 'true')
|
|
|
|
const queryString = queryParams.toString()
|
|
const endpoint = `spreadsheets/${params.spreadsheetId}${queryString ? `?${queryString}` : ''}`
|
|
|
|
return await this.makeGoogleSheetsRequest({
|
|
endpoint,
|
|
method: 'GET',
|
|
params
|
|
})
|
|
}
|
|
}
|
|
|
|
class UpdateSpreadsheetTool extends BaseGoogleSheetsTool {
|
|
defaultParams: any
|
|
|
|
constructor(args: any) {
|
|
const toolInput = {
|
|
name: 'update_spreadsheet',
|
|
description: 'Update a Google Spreadsheet properties',
|
|
schema: UpdateSpreadsheetSchema,
|
|
baseUrl: '',
|
|
method: 'POST',
|
|
headers: {}
|
|
}
|
|
super({
|
|
...toolInput,
|
|
accessToken: args.accessToken
|
|
})
|
|
this.defaultParams = args.defaultParams || {}
|
|
}
|
|
|
|
async _call(arg: any): Promise<string> {
|
|
const params = { ...arg, ...this.defaultParams }
|
|
|
|
const requests = []
|
|
if (params.title || params.locale || params.timeZone) {
|
|
const updateProperties: any = {}
|
|
if (params.title) updateProperties.title = params.title
|
|
if (params.locale) updateProperties.locale = params.locale
|
|
if (params.timeZone) updateProperties.timeZone = params.timeZone
|
|
|
|
requests.push({
|
|
updateSpreadsheetProperties: {
|
|
properties: updateProperties,
|
|
fields: Object.keys(updateProperties).join(',')
|
|
}
|
|
})
|
|
}
|
|
|
|
const body = { requests }
|
|
|
|
return await this.makeGoogleSheetsRequest({
|
|
endpoint: `spreadsheets/${params.spreadsheetId}:batchUpdate`,
|
|
method: 'POST',
|
|
body,
|
|
params
|
|
})
|
|
}
|
|
}
|
|
|
|
// Values Tools
|
|
class GetValuesTool extends BaseGoogleSheetsTool {
|
|
defaultParams: any
|
|
|
|
constructor(args: any) {
|
|
const toolInput = {
|
|
name: 'get_values',
|
|
description: 'Get values from a Google Spreadsheet range',
|
|
schema: GetValuesSchema,
|
|
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.valueRenderOption) queryParams.append('valueRenderOption', params.valueRenderOption)
|
|
if (params.dateTimeRenderOption) queryParams.append('dateTimeRenderOption', params.dateTimeRenderOption)
|
|
if (params.majorDimension) queryParams.append('majorDimension', params.majorDimension)
|
|
|
|
const queryString = queryParams.toString()
|
|
const encodedRange = encodeURIComponent(params.range)
|
|
const endpoint = `spreadsheets/${params.spreadsheetId}/values/${encodedRange}${queryString ? `?${queryString}` : ''}`
|
|
|
|
return await this.makeGoogleSheetsRequest({
|
|
endpoint,
|
|
method: 'GET',
|
|
params
|
|
})
|
|
}
|
|
}
|
|
|
|
class UpdateValuesTool extends BaseGoogleSheetsTool {
|
|
defaultParams: any
|
|
|
|
constructor(args: any) {
|
|
const toolInput = {
|
|
name: 'update_values',
|
|
description: 'Update values in a Google Spreadsheet range',
|
|
schema: UpdateValuesSchema,
|
|
baseUrl: '',
|
|
method: 'PUT',
|
|
headers: {}
|
|
}
|
|
super({
|
|
...toolInput,
|
|
accessToken: args.accessToken
|
|
})
|
|
this.defaultParams = args.defaultParams || {}
|
|
}
|
|
|
|
async _call(arg: any): Promise<string> {
|
|
const params = { ...arg, ...this.defaultParams }
|
|
|
|
let values
|
|
try {
|
|
values = JSON.parse(params.values)
|
|
} catch (error) {
|
|
throw new Error('Values must be a valid JSON array')
|
|
}
|
|
|
|
const body = {
|
|
values,
|
|
majorDimension: params.majorDimension || 'ROWS'
|
|
}
|
|
|
|
const queryParams = new URLSearchParams()
|
|
queryParams.append('valueInputOption', params.valueInputOption || 'USER_ENTERED')
|
|
|
|
const encodedRange = encodeURIComponent(params.range)
|
|
const endpoint = `spreadsheets/${params.spreadsheetId}/values/${encodedRange}?${queryParams.toString()}`
|
|
|
|
return await this.makeGoogleSheetsRequest({
|
|
endpoint,
|
|
method: 'PUT',
|
|
body,
|
|
params
|
|
})
|
|
}
|
|
}
|
|
|
|
class AppendValuesTool extends BaseGoogleSheetsTool {
|
|
defaultParams: any
|
|
|
|
constructor(args: any) {
|
|
const toolInput = {
|
|
name: 'append_values',
|
|
description: 'Append values to a Google Spreadsheet range',
|
|
schema: AppendValuesSchema,
|
|
baseUrl: '',
|
|
method: 'POST',
|
|
headers: {}
|
|
}
|
|
super({
|
|
...toolInput,
|
|
accessToken: args.accessToken
|
|
})
|
|
this.defaultParams = args.defaultParams || {}
|
|
}
|
|
|
|
async _call(arg: any): Promise<string> {
|
|
const params = { ...arg, ...this.defaultParams }
|
|
|
|
let values
|
|
try {
|
|
values = JSON.parse(params.values)
|
|
} catch (error) {
|
|
throw new Error('Values must be a valid JSON array')
|
|
}
|
|
|
|
const body = {
|
|
values,
|
|
majorDimension: params.majorDimension || 'ROWS'
|
|
}
|
|
|
|
const queryParams = new URLSearchParams()
|
|
queryParams.append('valueInputOption', params.valueInputOption || 'USER_ENTERED')
|
|
queryParams.append('insertDataOption', params.insertDataOption || 'OVERWRITE')
|
|
|
|
const encodedRange = encodeURIComponent(params.range)
|
|
const endpoint = `spreadsheets/${params.spreadsheetId}/values/${encodedRange}:append?${queryParams.toString()}`
|
|
|
|
return await this.makeGoogleSheetsRequest({
|
|
endpoint,
|
|
method: 'POST',
|
|
body,
|
|
params
|
|
})
|
|
}
|
|
}
|
|
|
|
class ClearValuesTool extends BaseGoogleSheetsTool {
|
|
defaultParams: any
|
|
|
|
constructor(args: any) {
|
|
const toolInput = {
|
|
name: 'clear_values',
|
|
description: 'Clear values from a Google Spreadsheet range',
|
|
schema: ClearValuesSchema,
|
|
baseUrl: '',
|
|
method: 'POST',
|
|
headers: {}
|
|
}
|
|
super({
|
|
...toolInput,
|
|
accessToken: args.accessToken
|
|
})
|
|
this.defaultParams = args.defaultParams || {}
|
|
}
|
|
|
|
async _call(arg: any): Promise<string> {
|
|
const params = { ...arg, ...this.defaultParams }
|
|
|
|
const encodedRange = encodeURIComponent(params.range)
|
|
const endpoint = `spreadsheets/${params.spreadsheetId}/values/${encodedRange}:clear`
|
|
|
|
return await this.makeGoogleSheetsRequest({
|
|
endpoint,
|
|
method: 'POST',
|
|
body: {},
|
|
params
|
|
})
|
|
}
|
|
}
|
|
|
|
class BatchGetValuesTool extends BaseGoogleSheetsTool {
|
|
defaultParams: any
|
|
|
|
constructor(args: any) {
|
|
const toolInput = {
|
|
name: 'batch_get_values',
|
|
description: 'Get values from multiple Google Spreadsheet ranges',
|
|
schema: BatchGetValuesSchema,
|
|
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()
|
|
|
|
// Add ranges
|
|
params.ranges.split(',').forEach((range: string) => {
|
|
queryParams.append('ranges', range.trim())
|
|
})
|
|
|
|
if (params.valueRenderOption) queryParams.append('valueRenderOption', params.valueRenderOption)
|
|
if (params.dateTimeRenderOption) queryParams.append('dateTimeRenderOption', params.dateTimeRenderOption)
|
|
if (params.majorDimension) queryParams.append('majorDimension', params.majorDimension)
|
|
|
|
const endpoint = `spreadsheets/${params.spreadsheetId}/values:batchGet?${queryParams.toString()}`
|
|
|
|
return await this.makeGoogleSheetsRequest({
|
|
endpoint,
|
|
method: 'GET',
|
|
params
|
|
})
|
|
}
|
|
}
|
|
|
|
class BatchUpdateValuesTool extends BaseGoogleSheetsTool {
|
|
defaultParams: any
|
|
|
|
constructor(args: any) {
|
|
const toolInput = {
|
|
name: 'batch_update_values',
|
|
description: 'Update values in multiple Google Spreadsheet ranges',
|
|
schema: BatchUpdateValuesSchema,
|
|
baseUrl: '',
|
|
method: 'POST',
|
|
headers: {}
|
|
}
|
|
super({
|
|
...toolInput,
|
|
accessToken: args.accessToken
|
|
})
|
|
this.defaultParams = args.defaultParams || {}
|
|
}
|
|
|
|
async _call(arg: any): Promise<string> {
|
|
const params = { ...arg, ...this.defaultParams }
|
|
|
|
let valueRanges
|
|
try {
|
|
valueRanges = JSON.parse(params.values)
|
|
} catch (error) {
|
|
throw new Error('Values must be a valid JSON array of value ranges')
|
|
}
|
|
|
|
const body = {
|
|
valueInputOption: params.valueInputOption || 'USER_ENTERED',
|
|
data: valueRanges,
|
|
includeValuesInResponse: params.includeValuesInResponse || false
|
|
}
|
|
|
|
const endpoint = `spreadsheets/${params.spreadsheetId}/values:batchUpdate`
|
|
|
|
return await this.makeGoogleSheetsRequest({
|
|
endpoint,
|
|
method: 'POST',
|
|
body,
|
|
params
|
|
})
|
|
}
|
|
}
|
|
|
|
class BatchClearValuesTool extends BaseGoogleSheetsTool {
|
|
defaultParams: any
|
|
|
|
constructor(args: any) {
|
|
const toolInput = {
|
|
name: 'batch_clear_values',
|
|
description: 'Clear values from multiple Google Spreadsheet ranges',
|
|
schema: BatchClearValuesSchema,
|
|
baseUrl: '',
|
|
method: 'POST',
|
|
headers: {}
|
|
}
|
|
super({
|
|
...toolInput,
|
|
accessToken: args.accessToken
|
|
})
|
|
this.defaultParams = args.defaultParams || {}
|
|
}
|
|
|
|
async _call(arg: any): Promise<string> {
|
|
const params = { ...arg, ...this.defaultParams }
|
|
|
|
const ranges = params.ranges.split(',').map((range: string) => range.trim())
|
|
const body = { ranges }
|
|
|
|
const endpoint = `spreadsheets/${params.spreadsheetId}/values:batchClear`
|
|
|
|
return await this.makeGoogleSheetsRequest({
|
|
endpoint,
|
|
method: 'POST',
|
|
body,
|
|
params
|
|
})
|
|
}
|
|
}
|
|
|
|
export const createGoogleSheetsTools = (args?: RequestParameters): DynamicStructuredTool[] => {
|
|
const { actions = [], accessToken, defaultParams } = args || {}
|
|
const tools: DynamicStructuredTool[] = []
|
|
|
|
// Define all available tools
|
|
const toolClasses = {
|
|
// Spreadsheet tools
|
|
createSpreadsheet: CreateSpreadsheetTool,
|
|
getSpreadsheet: GetSpreadsheetTool,
|
|
updateSpreadsheet: UpdateSpreadsheetTool,
|
|
// Values tools
|
|
getValues: GetValuesTool,
|
|
updateValues: UpdateValuesTool,
|
|
appendValues: AppendValuesTool,
|
|
clearValues: ClearValuesTool,
|
|
batchGetValues: BatchGetValuesTool,
|
|
batchUpdateValues: BatchUpdateValuesTool,
|
|
batchClearValues: BatchClearValuesTool
|
|
}
|
|
|
|
// Create tools based on requested actions
|
|
actions.forEach((action) => {
|
|
const ToolClass = toolClasses[action as keyof typeof toolClasses]
|
|
if (ToolClass) {
|
|
tools.push(new ToolClass({ accessToken, defaultParams }))
|
|
}
|
|
})
|
|
|
|
return tools
|
|
}
|