Flowise/packages/components/nodes/tools/Gmail/core.ts

1080 lines
35 KiB
TypeScript

import { z } from 'zod'
import fetch from 'node-fetch'
import { DynamicStructuredTool } from '../OpenAPIToolkit/core'
import { TOOL_ARGS_PREFIX, formatToolError } from '../../../src/agents'
export const desc = `Use this when you want to access Gmail API for managing drafts, messages, labels, and threads`
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 Gmail operations
const ListSchema = z.object({
maxResults: z.number().optional().default(100).describe('Maximum number of results to return'),
query: z.string().optional().describe('Query string for filtering results (Gmail search syntax)')
})
const CreateDraftSchema = z.object({
to: z.string().describe('Recipient email address(es), comma-separated'),
subject: z.string().optional().describe('Email subject'),
body: z.string().optional().describe('Email body content'),
cc: z.string().optional().describe('CC email address(es), comma-separated'),
bcc: z.string().optional().describe('BCC email address(es), comma-separated')
})
const SendMessageSchema = z.object({
to: z.string().describe('Recipient email address(es), comma-separated'),
subject: z.string().optional().describe('Email subject'),
body: z.string().optional().describe('Email body content'),
cc: z.string().optional().describe('CC email address(es), comma-separated'),
bcc: z.string().optional().describe('BCC email address(es), comma-separated')
})
const GetByIdSchema = z.object({
id: z.string().describe('ID of the resource')
})
const ModifySchema = z.object({
id: z.string().describe('ID of the resource'),
addLabelIds: z.array(z.string()).optional().describe('Label IDs to add'),
removeLabelIds: z.array(z.string()).optional().describe('Label IDs to remove')
})
const CreateLabelSchema = z.object({
labelName: z.string().describe('Name of the label'),
labelColor: z.string().optional().describe('Color of the label (hex color code)')
})
class BaseGmailTool extends DynamicStructuredTool {
protected accessToken: string = ''
constructor(args: any) {
super(args)
this.accessToken = args.accessToken ?? ''
}
async makeGmailRequest(url: string, method: string = 'GET', body?: any, params?: any): Promise<string> {
const headers = {
Authorization: `Bearer ${this.accessToken}`,
'Content-Type': '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(`Gmail API Error ${response.status}: ${response.statusText} - ${errorText}`)
}
const data = await response.text()
return data + TOOL_ARGS_PREFIX + JSON.stringify(params)
}
createMimeMessage(to: string, subject?: string, body?: string, cc?: string, bcc?: string): string {
let message = ''
message += `To: ${to}\r\n`
if (cc) message += `Cc: ${cc}\r\n`
if (bcc) message += `Bcc: ${bcc}\r\n`
if (subject) message += `Subject: ${subject}\r\n`
message += `MIME-Version: 1.0\r\n`
message += `Content-Type: text/html; charset=utf-8\r\n`
message += `Content-Transfer-Encoding: base64\r\n\r\n`
if (body) {
message += Buffer.from(body, 'utf-8').toString('base64')
}
return Buffer.from(message).toString('base64').replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '')
}
}
// Draft Tools
class ListDraftsTool extends BaseGmailTool {
defaultParams: any
constructor(args: any) {
const toolInput = {
name: 'list_drafts',
description: 'List drafts in Gmail mailbox',
schema: ListSchema,
baseUrl: 'https://gmail.googleapis.com/gmail/v1/users/me/drafts',
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.maxResults) queryParams.append('maxResults', params.maxResults.toString())
if (params.query) queryParams.append('q', params.query)
const url = `https://gmail.googleapis.com/gmail/v1/users/me/drafts?${queryParams.toString()}`
try {
const response = await this.makeGmailRequest(url, 'GET', undefined, params)
return response
} catch (error) {
return formatToolError(`Error listing drafts: ${error}`, params)
}
}
}
class CreateDraftTool extends BaseGmailTool {
defaultParams: any
constructor(args: any) {
const toolInput = {
name: 'create_draft',
description: 'Create a new draft in Gmail',
schema: CreateDraftSchema,
baseUrl: 'https://gmail.googleapis.com/gmail/v1/users/me/drafts',
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 raw = this.createMimeMessage(params.to, params.subject, params.body, params.cc, params.bcc)
const draftData = {
message: {
raw: raw
}
}
const url = 'https://gmail.googleapis.com/gmail/v1/users/me/drafts'
const response = await this.makeGmailRequest(url, 'POST', draftData, params)
return response
} catch (error) {
return formatToolError(`Error creating draft: ${error}`, params)
}
}
}
class GetDraftTool extends BaseGmailTool {
defaultParams: any
constructor(args: any) {
const toolInput = {
name: 'get_draft',
description: 'Get a specific draft from Gmail',
schema: GetByIdSchema,
baseUrl: 'https://gmail.googleapis.com/gmail/v1/users/me/drafts',
method: 'GET',
headers: {}
}
super({ ...toolInput, accessToken: args.accessToken })
this.defaultParams = args.defaultParams || {}
}
async _call(arg: any): Promise<string> {
const params = { ...arg, ...this.defaultParams }
const draftId = params.draftId || params.id
if (!draftId) {
return 'Error: Draft ID is required'
}
try {
const url = `https://gmail.googleapis.com/gmail/v1/users/me/drafts/${draftId}`
const response = await this.makeGmailRequest(url, 'GET', undefined, params)
return response
} catch (error) {
return formatToolError(`Error getting draft: ${error}`, params)
}
}
}
class UpdateDraftTool extends BaseGmailTool {
defaultParams: any
constructor(args: any) {
const toolInput = {
name: 'update_draft',
description: 'Update a specific draft in Gmail',
schema: CreateDraftSchema,
baseUrl: 'https://gmail.googleapis.com/gmail/v1/users/me/drafts',
method: 'PUT',
headers: {}
}
super({ ...toolInput, accessToken: args.accessToken })
this.defaultParams = args.defaultParams || {}
}
async _call(arg: any): Promise<string> {
const params = { ...arg, ...this.defaultParams }
const draftId = params.draftId || params.id
if (!draftId) {
return 'Error: Draft ID is required'
}
try {
const raw = this.createMimeMessage(params.to, params.subject, params.body, params.cc, params.bcc)
const draftData = {
message: {
raw: raw
}
}
const url = `https://gmail.googleapis.com/gmail/v1/users/me/drafts/${draftId}`
const response = await this.makeGmailRequest(url, 'PUT', draftData, params)
return response
} catch (error) {
return formatToolError(`Error updating draft: ${error}`, params)
}
}
}
class SendDraftTool extends BaseGmailTool {
defaultParams: any
constructor(args: any) {
const toolInput = {
name: 'send_draft',
description: 'Send a specific draft from Gmail',
schema: GetByIdSchema,
baseUrl: 'https://gmail.googleapis.com/gmail/v1/users/me/drafts/send',
method: 'POST',
headers: {}
}
super({ ...toolInput, accessToken: args.accessToken })
this.defaultParams = args.defaultParams || {}
}
async _call(arg: any): Promise<string> {
const params = { ...arg, ...this.defaultParams }
const draftId = params.draftId || params.id
if (!draftId) {
return 'Error: Draft ID is required'
}
try {
const url = 'https://gmail.googleapis.com/gmail/v1/users/me/drafts/send'
const response = await this.makeGmailRequest(url, 'POST', { id: draftId }, params)
return response
} catch (error) {
return formatToolError(`Error sending draft: ${error}`, params)
}
}
}
class DeleteDraftTool extends BaseGmailTool {
defaultParams: any
constructor(args: any) {
const toolInput = {
name: 'delete_draft',
description: 'Delete a specific draft from Gmail',
schema: GetByIdSchema,
baseUrl: 'https://gmail.googleapis.com/gmail/v1/users/me/drafts',
method: 'DELETE',
headers: {}
}
super({ ...toolInput, accessToken: args.accessToken })
this.defaultParams = args.defaultParams || {}
}
async _call(arg: any): Promise<string> {
const params = { ...arg, ...this.defaultParams }
const draftId = params.draftId || params.id
if (!draftId) {
return 'Error: Draft ID is required'
}
try {
const url = `https://gmail.googleapis.com/gmail/v1/users/me/drafts/${draftId}`
await this.makeGmailRequest(url, 'DELETE', undefined, params)
return `Draft ${draftId} deleted successfully`
} catch (error) {
return formatToolError(`Error deleting draft: ${error}`, params)
}
}
}
// Message Tools
class ListMessagesTool extends BaseGmailTool {
defaultParams: any
constructor(args: any) {
const toolInput = {
name: 'list_messages',
description: 'List messages in Gmail mailbox',
schema: ListSchema,
baseUrl: 'https://gmail.googleapis.com/gmail/v1/users/me/messages',
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.maxResults) queryParams.append('maxResults', params.maxResults.toString())
if (params.query) queryParams.append('q', params.query)
const url = `https://gmail.googleapis.com/gmail/v1/users/me/messages?${queryParams.toString()}`
try {
const response = await this.makeGmailRequest(url, 'GET', undefined, params)
return response
} catch (error) {
return formatToolError(`Error listing messages: ${error}`, params)
}
}
}
class GetMessageTool extends BaseGmailTool {
defaultParams: any
constructor(args: any) {
const toolInput = {
name: 'get_message',
description: 'Get a specific message from Gmail',
schema: GetByIdSchema,
baseUrl: 'https://gmail.googleapis.com/gmail/v1/users/me/messages',
method: 'GET',
headers: {}
}
super({ ...toolInput, accessToken: args.accessToken })
this.defaultParams = args.defaultParams || {}
}
async _call(arg: any): Promise<string> {
const params = { ...arg, ...this.defaultParams }
const messageId = params.messageId || params.id
if (!messageId) {
return 'Error: Message ID is required'
}
try {
const url = `https://gmail.googleapis.com/gmail/v1/users/me/messages/${messageId}`
const response = await this.makeGmailRequest(url, 'GET', undefined, params)
return response
} catch (error) {
return formatToolError(`Error getting message: ${error}`, params)
}
}
}
class SendMessageTool extends BaseGmailTool {
defaultParams: any
constructor(args: any) {
const toolInput = {
name: 'send_message',
description: 'Send a new message via Gmail',
schema: SendMessageSchema,
baseUrl: 'https://gmail.googleapis.com/gmail/v1/users/me/messages/send',
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 raw = this.createMimeMessage(params.to, params.subject, params.body, params.cc, params.bcc)
const messageData = {
raw: raw
}
const url = 'https://gmail.googleapis.com/gmail/v1/users/me/messages/send'
const response = await this.makeGmailRequest(url, 'POST', messageData, params)
return response
} catch (error) {
return formatToolError(`Error sending message: ${error}`, params)
}
}
}
class ModifyMessageTool extends BaseGmailTool {
defaultParams: any
constructor(args: any) {
const toolInput = {
name: 'modify_message',
description: 'Modify labels on a message in Gmail',
schema: ModifySchema,
baseUrl: 'https://gmail.googleapis.com/gmail/v1/users/me/messages',
method: 'POST',
headers: {}
}
super({ ...toolInput, accessToken: args.accessToken })
this.defaultParams = args.defaultParams || {}
}
async _call(arg: any): Promise<string> {
const params = { ...arg, ...this.defaultParams }
const messageId = params.messageId || params.id
if (!messageId) {
return 'Error: Message ID is required'
}
try {
const modifyData: any = {}
if (params.addLabelIds && params.addLabelIds.length > 0) {
modifyData.addLabelIds = params.addLabelIds
}
if (params.removeLabelIds && params.removeLabelIds.length > 0) {
modifyData.removeLabelIds = params.removeLabelIds
}
const url = `https://gmail.googleapis.com/gmail/v1/users/me/messages/${messageId}/modify`
const response = await this.makeGmailRequest(url, 'POST', modifyData, params)
return response
} catch (error) {
return formatToolError(`Error modifying message: ${error}`, params)
}
}
}
class TrashMessageTool extends BaseGmailTool {
defaultParams: any
constructor(args: any) {
const toolInput = {
name: 'trash_message',
description: 'Move a message to trash in Gmail',
schema: GetByIdSchema,
baseUrl: 'https://gmail.googleapis.com/gmail/v1/users/me/messages',
method: 'POST',
headers: {}
}
super({ ...toolInput, accessToken: args.accessToken })
this.defaultParams = args.defaultParams || {}
}
async _call(arg: any): Promise<string> {
const params = { ...arg, ...this.defaultParams }
const messageId = params.messageId || params.id
if (!messageId) {
return 'Error: Message ID is required'
}
try {
const url = `https://gmail.googleapis.com/gmail/v1/users/me/messages/${messageId}/trash`
const response = await this.makeGmailRequest(url, 'POST', undefined, params)
return response
} catch (error) {
return formatToolError(`Error moving message to trash: ${error}`, params)
}
}
}
class UntrashMessageTool extends BaseGmailTool {
defaultParams: any
constructor(args: any) {
const toolInput = {
name: 'untrash_message',
description: 'Remove a message from trash in Gmail',
schema: GetByIdSchema,
baseUrl: 'https://gmail.googleapis.com/gmail/v1/users/me/messages',
method: 'POST',
headers: {}
}
super({ ...toolInput, accessToken: args.accessToken })
this.defaultParams = args.defaultParams || {}
}
async _call(arg: any): Promise<string> {
const params = { ...arg, ...this.defaultParams }
const messageId = params.messageId || params.id
if (!messageId) {
return 'Error: Message ID is required'
}
try {
const url = `https://gmail.googleapis.com/gmail/v1/users/me/messages/${messageId}/untrash`
const response = await this.makeGmailRequest(url, 'POST', undefined, params)
return response
} catch (error) {
return formatToolError(`Error removing message from trash: ${error}`, params)
}
}
}
class DeleteMessageTool extends BaseGmailTool {
defaultParams: any
constructor(args: any) {
const toolInput = {
name: 'delete_message',
description: 'Permanently delete a message from Gmail',
schema: GetByIdSchema,
baseUrl: 'https://gmail.googleapis.com/gmail/v1/users/me/messages',
method: 'DELETE',
headers: {}
}
super({ ...toolInput, accessToken: args.accessToken })
this.defaultParams = args.defaultParams || {}
}
async _call(arg: any): Promise<string> {
const params = { ...arg, ...this.defaultParams }
const messageId = params.messageId || params.id
if (!messageId) {
return 'Error: Message ID is required'
}
try {
const url = `https://gmail.googleapis.com/gmail/v1/users/me/messages/${messageId}`
await this.makeGmailRequest(url, 'DELETE', undefined, params)
return `Message ${messageId} deleted successfully`
} catch (error) {
return formatToolError(`Error deleting message: ${error}`, params)
}
}
}
// Label Tools
class ListLabelsTool extends BaseGmailTool {
defaultParams: any
constructor(args: any) {
const toolInput = {
name: 'list_labels',
description: 'List labels in Gmail mailbox',
schema: z.object({}),
baseUrl: 'https://gmail.googleapis.com/gmail/v1/users/me/labels',
method: 'GET',
headers: {}
}
super({ ...toolInput, accessToken: args.accessToken })
this.defaultParams = args.defaultParams || {}
}
async _call(): Promise<string> {
try {
const url = 'https://gmail.googleapis.com/gmail/v1/users/me/labels'
const response = await this.makeGmailRequest(url, 'GET', undefined, {})
return response
} catch (error) {
return formatToolError(`Error listing labels: ${error}`, {})
}
}
}
class GetLabelTool extends BaseGmailTool {
defaultParams: any
constructor(args: any) {
const toolInput = {
name: 'get_label',
description: 'Get a specific label from Gmail',
schema: GetByIdSchema,
baseUrl: 'https://gmail.googleapis.com/gmail/v1/users/me/labels',
method: 'GET',
headers: {}
}
super({ ...toolInput, accessToken: args.accessToken })
this.defaultParams = args.defaultParams || {}
}
async _call(arg: any): Promise<string> {
const params = { ...arg, ...this.defaultParams }
const labelId = params.labelId || params.id
if (!labelId) {
return 'Error: Label ID is required'
}
try {
const url = `https://gmail.googleapis.com/gmail/v1/users/me/labels/${labelId}`
const response = await this.makeGmailRequest(url, 'GET', undefined, params)
return response
} catch (error) {
return formatToolError(`Error getting label: ${error}`, params)
}
}
}
class CreateLabelTool extends BaseGmailTool {
defaultParams: any
constructor(args: any) {
const toolInput = {
name: 'create_label',
description: 'Create a new label in Gmail',
schema: CreateLabelSchema,
baseUrl: 'https://gmail.googleapis.com/gmail/v1/users/me/labels',
method: 'POST',
headers: {}
}
super({ ...toolInput, accessToken: args.accessToken })
this.defaultParams = args.defaultParams || {}
}
async _call(arg: any): Promise<string> {
const params = { ...arg, ...this.defaultParams }
if (!params.labelName) {
return 'Error: Label name is required'
}
try {
const labelData: any = {
name: params.labelName,
labelListVisibility: 'labelShow',
messageListVisibility: 'show'
}
if (params.labelColor) {
labelData.color = {
backgroundColor: params.labelColor
}
}
const url = 'https://gmail.googleapis.com/gmail/v1/users/me/labels'
const response = await this.makeGmailRequest(url, 'POST', labelData, params)
return response
} catch (error) {
return formatToolError(`Error creating label: ${error}`, params)
}
}
}
class UpdateLabelTool extends BaseGmailTool {
defaultParams: any
constructor(args: any) {
const toolInput = {
name: 'update_label',
description: 'Update a label in Gmail',
schema: CreateLabelSchema,
baseUrl: 'https://gmail.googleapis.com/gmail/v1/users/me/labels',
method: 'PUT',
headers: {}
}
super({ ...toolInput, accessToken: args.accessToken })
this.defaultParams = args.defaultParams || {}
}
async _call(arg: any): Promise<string> {
const params = { ...arg, ...this.defaultParams }
const labelId = params.labelId || params.id
if (!labelId) {
return 'Error: Label ID is required'
}
try {
const labelData: any = {}
if (params.labelName) {
labelData.name = params.labelName
}
if (params.labelColor) {
labelData.color = {
backgroundColor: params.labelColor
}
}
const url = `https://gmail.googleapis.com/gmail/v1/users/me/labels/${labelId}`
const response = await this.makeGmailRequest(url, 'PUT', labelData, params)
return response
} catch (error) {
return formatToolError(`Error updating label: ${error}`, params)
}
}
}
class DeleteLabelTool extends BaseGmailTool {
defaultParams: any
constructor(args: any) {
const toolInput = {
name: 'delete_label',
description: 'Delete a label from Gmail',
schema: GetByIdSchema,
baseUrl: 'https://gmail.googleapis.com/gmail/v1/users/me/labels',
method: 'DELETE',
headers: {}
}
super({ ...toolInput, accessToken: args.accessToken })
this.defaultParams = args.defaultParams || {}
}
async _call(arg: any): Promise<string> {
const params = { ...arg, ...this.defaultParams }
const labelId = params.labelId || params.id
if (!labelId) {
return 'Error: Label ID is required'
}
try {
const url = `https://gmail.googleapis.com/gmail/v1/users/me/labels/${labelId}`
await this.makeGmailRequest(url, 'DELETE', undefined, params)
return `Label ${labelId} deleted successfully`
} catch (error) {
return formatToolError(`Error deleting label: ${error}`, params)
}
}
}
// Thread Tools
class ListThreadsTool extends BaseGmailTool {
defaultParams: any
constructor(args: any) {
const toolInput = {
name: 'list_threads',
description: 'List threads in Gmail mailbox',
schema: ListSchema,
baseUrl: 'https://gmail.googleapis.com/gmail/v1/users/me/threads',
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.maxResults) queryParams.append('maxResults', params.maxResults.toString())
if (params.query) queryParams.append('q', params.query)
const url = `https://gmail.googleapis.com/gmail/v1/users/me/threads?${queryParams.toString()}`
try {
const response = await this.makeGmailRequest(url, 'GET', undefined, params)
return response
} catch (error) {
return formatToolError(`Error listing threads: ${error}`, params)
}
}
}
class GetThreadTool extends BaseGmailTool {
defaultParams: any
constructor(args: any) {
const toolInput = {
name: 'get_thread',
description: 'Get a specific thread from Gmail',
schema: GetByIdSchema,
baseUrl: 'https://gmail.googleapis.com/gmail/v1/users/me/threads',
method: 'GET',
headers: {}
}
super({ ...toolInput, accessToken: args.accessToken })
this.defaultParams = args.defaultParams || {}
}
async _call(arg: any): Promise<string> {
const params = { ...arg, ...this.defaultParams }
const threadId = params.threadId || params.id
if (!threadId) {
return 'Error: Thread ID is required'
}
try {
const url = `https://gmail.googleapis.com/gmail/v1/users/me/threads/${threadId}`
const response = await this.makeGmailRequest(url, 'GET', undefined, params)
return response
} catch (error) {
return formatToolError(`Error getting thread: ${error}`, params)
}
}
}
class ModifyThreadTool extends BaseGmailTool {
defaultParams: any
constructor(args: any) {
const toolInput = {
name: 'modify_thread',
description: 'Modify labels on a thread in Gmail',
schema: ModifySchema,
baseUrl: 'https://gmail.googleapis.com/gmail/v1/users/me/threads',
method: 'POST',
headers: {}
}
super({ ...toolInput, accessToken: args.accessToken })
this.defaultParams = args.defaultParams || {}
}
async _call(arg: any): Promise<string> {
const params = { ...arg, ...this.defaultParams }
const threadId = params.threadId || params.id
if (!threadId) {
return 'Error: Thread ID is required'
}
try {
const modifyData: any = {}
if (params.addLabelIds && params.addLabelIds.length > 0) {
modifyData.addLabelIds = params.addLabelIds
}
if (params.removeLabelIds && params.removeLabelIds.length > 0) {
modifyData.removeLabelIds = params.removeLabelIds
}
const url = `https://gmail.googleapis.com/gmail/v1/users/me/threads/${threadId}/modify`
const response = await this.makeGmailRequest(url, 'POST', modifyData, params)
return response
} catch (error) {
return formatToolError(`Error modifying thread: ${error}`, params)
}
}
}
class TrashThreadTool extends BaseGmailTool {
defaultParams: any
constructor(args: any) {
const toolInput = {
name: 'trash_thread',
description: 'Move a thread to trash in Gmail',
schema: GetByIdSchema,
baseUrl: 'https://gmail.googleapis.com/gmail/v1/users/me/threads',
method: 'POST',
headers: {}
}
super({ ...toolInput, accessToken: args.accessToken })
this.defaultParams = args.defaultParams || {}
}
async _call(arg: any): Promise<string> {
const params = { ...arg, ...this.defaultParams }
const threadId = params.threadId || params.id
if (!threadId) {
return 'Error: Thread ID is required'
}
try {
const url = `https://gmail.googleapis.com/gmail/v1/users/me/threads/${threadId}/trash`
const response = await this.makeGmailRequest(url, 'POST', undefined, params)
return response
} catch (error) {
return formatToolError(`Error moving thread to trash: ${error}`, params)
}
}
}
class UntrashThreadTool extends BaseGmailTool {
defaultParams: any
constructor(args: any) {
const toolInput = {
name: 'untrash_thread',
description: 'Remove a thread from trash in Gmail',
schema: GetByIdSchema,
baseUrl: 'https://gmail.googleapis.com/gmail/v1/users/me/threads',
method: 'POST',
headers: {}
}
super({ ...toolInput, accessToken: args.accessToken })
this.defaultParams = args.defaultParams || {}
}
async _call(arg: any): Promise<string> {
const params = { ...arg, ...this.defaultParams }
const threadId = params.threadId || params.id
if (!threadId) {
return 'Error: Thread ID is required'
}
try {
const url = `https://gmail.googleapis.com/gmail/v1/users/me/threads/${threadId}/untrash`
const response = await this.makeGmailRequest(url, 'POST', undefined, params)
return response
} catch (error) {
return formatToolError(`Error removing thread from trash: ${error}`, params)
}
}
}
class DeleteThreadTool extends BaseGmailTool {
defaultParams: any
constructor(args: any) {
const toolInput = {
name: 'delete_thread',
description: 'Permanently delete a thread from Gmail',
schema: GetByIdSchema,
baseUrl: 'https://gmail.googleapis.com/gmail/v1/users/me/threads',
method: 'DELETE',
headers: {}
}
super({ ...toolInput, accessToken: args.accessToken })
this.defaultParams = args.defaultParams || {}
}
async _call(arg: any): Promise<string> {
const params = { ...arg, ...this.defaultParams }
const threadId = params.threadId || params.id
if (!threadId) {
return 'Error: Thread ID is required'
}
try {
const url = `https://gmail.googleapis.com/gmail/v1/users/me/threads/${threadId}`
await this.makeGmailRequest(url, 'DELETE', undefined, params)
return `Thread ${threadId} deleted successfully`
} catch (error) {
return formatToolError(`Error deleting thread: ${error}`, params)
}
}
}
export const createGmailTools = (args?: RequestParameters): DynamicStructuredTool[] => {
const tools: DynamicStructuredTool[] = []
const actions = args?.actions || []
const accessToken = args?.accessToken || ''
const defaultParams = args?.defaultParams || {}
// Draft tools
if (actions.includes('listDrafts')) {
tools.push(new ListDraftsTool({ accessToken, defaultParams }))
}
if (actions.includes('createDraft')) {
tools.push(new CreateDraftTool({ accessToken, defaultParams }))
}
if (actions.includes('getDraft')) {
tools.push(new GetDraftTool({ accessToken, defaultParams }))
}
if (actions.includes('updateDraft')) {
tools.push(new UpdateDraftTool({ accessToken, defaultParams }))
}
if (actions.includes('sendDraft')) {
tools.push(new SendDraftTool({ accessToken, defaultParams }))
}
if (actions.includes('deleteDraft')) {
tools.push(new DeleteDraftTool({ accessToken, defaultParams }))
}
// Message tools
if (actions.includes('listMessages')) {
tools.push(new ListMessagesTool({ accessToken, defaultParams }))
}
if (actions.includes('getMessage')) {
tools.push(new GetMessageTool({ accessToken, defaultParams }))
}
if (actions.includes('sendMessage')) {
tools.push(new SendMessageTool({ accessToken, defaultParams }))
}
if (actions.includes('modifyMessage')) {
tools.push(new ModifyMessageTool({ accessToken, defaultParams }))
}
if (actions.includes('trashMessage')) {
tools.push(new TrashMessageTool({ accessToken, defaultParams }))
}
if (actions.includes('untrashMessage')) {
tools.push(new UntrashMessageTool({ accessToken, defaultParams }))
}
if (actions.includes('deleteMessage')) {
tools.push(new DeleteMessageTool({ accessToken, defaultParams }))
}
// Label tools
if (actions.includes('listLabels')) {
tools.push(new ListLabelsTool({ accessToken, defaultParams }))
}
if (actions.includes('getLabel')) {
tools.push(new GetLabelTool({ accessToken, defaultParams }))
}
if (actions.includes('createLabel')) {
tools.push(new CreateLabelTool({ accessToken, defaultParams }))
}
if (actions.includes('updateLabel')) {
tools.push(new UpdateLabelTool({ accessToken, defaultParams }))
}
if (actions.includes('deleteLabel')) {
tools.push(new DeleteLabelTool({ accessToken, defaultParams }))
}
// Thread tools
if (actions.includes('listThreads')) {
tools.push(new ListThreadsTool({ accessToken, defaultParams }))
}
if (actions.includes('getThread')) {
tools.push(new GetThreadTool({ accessToken, defaultParams }))
}
if (actions.includes('modifyThread')) {
tools.push(new ModifyThreadTool({ accessToken, defaultParams }))
}
if (actions.includes('trashThread')) {
tools.push(new TrashThreadTool({ accessToken, defaultParams }))
}
if (actions.includes('untrashThread')) {
tools.push(new UntrashThreadTool({ accessToken, defaultParams }))
}
if (actions.includes('deleteThread')) {
tools.push(new DeleteThreadTool({ accessToken, defaultParams }))
}
return tools
}