diff --git a/docs/content/docs/tools/clay.mdx b/docs/content/docs/tools/clay.mdx index 8af82db83..f86b24ce6 100644 --- a/docs/content/docs/tools/clay.mdx +++ b/docs/content/docs/tools/clay.mdx @@ -1,6 +1,6 @@ --- title: Clay -description: Populate Clay with data +description: Populate Clay workbook with data --- import { BlockInfoCard } from "@/components/ui/block-info-card" @@ -197,7 +197,8 @@ In Sim Studio, the Clay integration allows your agents to push structured data i ## Usage Instructions -Populate Clay with data from a JSON file. Enables direct communication and notifications with timestamp tracking and channel confirmation. +Populate Clay workbook with data using a JSON or plain text. Enables direct communication and notifications with channel confirmation. + ## Tools @@ -210,7 +211,7 @@ Populate Clay with data from a JSON file. Enables direct communication and notif | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | -| `webhookId` | string | Yes | The webhook ID to populate | +| `webhookURL` | string | Yes | The webhook URL to populate | | `data` | json | Yes | The data to populate | | `authToken` | string | No | Optional auth token for WebhookURL | @@ -228,7 +229,7 @@ Populate Clay with data from a JSON file. Enables direct communication and notif | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | -| `apiKey` | string | No | Auth Token - Enter your Clay Auth token | +| `authToken` | string | Yes | Auth Token - Enter your Clay Auth token | diff --git a/docs/content/docs/tools/google_sheets.mdx b/docs/content/docs/tools/google_sheets.mdx index 4d79ed690..fdf43c68b 100644 --- a/docs/content/docs/tools/google_sheets.mdx +++ b/docs/content/docs/tools/google_sheets.mdx @@ -48,7 +48,7 @@ In Sim Studio, the Google Sheets integration enables your agents to interact dir ## Usage Instructions -Integrate Google Sheets functionality to manage spreadsheet data. Read data from specific ranges, write new data, and update existing cells using OAuth authentication. Supports various input and output formats for flexible data handling. +Integrate Google Sheets functionality to manage spreadsheet data. Read data from specific ranges, write new data, update existing cells, and append data to the end of sheets using OAuth authentication. Supports various input and output formats for flexible data handling. @@ -126,6 +126,28 @@ Update data in a Google Sheets spreadsheet | `spreadsheetId` | string | | `spreadsheetUrl` | string | +### `google_sheets_append` + +Append data to the end of a Google Sheets spreadsheet + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `accessToken` | string | Yes | The access token for the Google Sheets API | +| `spreadsheetId` | string | Yes | The ID of the spreadsheet to append to | +| `range` | string | No | The range of cells to append after | +| `values` | array | Yes | The data to append to the spreadsheet | +| `valueInputOption` | string | No | The format of the data to append | +| `insertDataOption` | string | No | How to insert the data \(OVERWRITE or INSERT_ROWS\) | +| `includeValuesInResponse` | boolean | No | Whether to include the appended values in the response | + +#### Output + +| Parameter | Type | +| --------- | ---- | +| `data` | json | + ## Block Configuration @@ -149,6 +171,7 @@ Update data in a Google Sheets spreadsheet | ↳ `updatedRows` | number | updatedRows of the response | | ↳ `updatedColumns` | number | updatedColumns of the response | | ↳ `updatedCells` | number | updatedCells of the response | +| ↳ `tableRange` | string | tableRange of the response | ## Notes diff --git a/docs/content/docs/tools/jira.mdx b/docs/content/docs/tools/jira.mdx index 1e2022074..ddd5f834c 100644 --- a/docs/content/docs/tools/jira.mdx +++ b/docs/content/docs/tools/jira.mdx @@ -25,6 +25,7 @@ import { BlockInfoCard } from "@/components/ui/block-info-card" `} /> +{/* MANUAL-CONTENT-START:intro */} [Jira](https://www.atlassian.com/jira) is a leading project management and issue tracking platform that helps teams plan, track, and manage agile software development projects effectively. As part of the Atlassian suite, Jira has become the industry standard for software development teams and project management professionals worldwide. Jira provides a comprehensive set of tools for managing complex projects through its flexible and customizable workflow system. With its robust API and integration capabilities, Jira enables teams to streamline their development processes and maintain clear visibility of project progress. @@ -37,6 +38,8 @@ Key features of Jira include: - Advanced Search: JQL (Jira Query Language) for complex issue filtering and reporting In Sim Studio, the Jira integration allows your agents to seamlessly interact with your project management workflow. This creates opportunities for automated issue creation, updates, and tracking as part of your AI workflows. The integration enables agents to create, retrieve, and update Jira issues programmatically, facilitating automated project management tasks and ensuring that important information is properly tracked and documented. By connecting Sim Studio with Jira, you can build intelligent agents that maintain project visibility while automating routine project management tasks, enhancing team productivity and ensuring consistent project tracking. +{/* MANUAL-CONTENT-END */} + ## Usage Instructions diff --git a/docs/content/docs/tools/meta.json b/docs/content/docs/tools/meta.json index 06c72df2b..ffafb325a 100644 --- a/docs/content/docs/tools/meta.json +++ b/docs/content/docs/tools/meta.json @@ -34,6 +34,7 @@ "stagehand_agent", "supabase", "tavily", + "telegram", "thinking", "translate", "twilio_sms", diff --git a/docs/content/docs/tools/slack.mdx b/docs/content/docs/tools/slack.mdx index 54ebb99ea..e7961d142 100644 --- a/docs/content/docs/tools/slack.mdx +++ b/docs/content/docs/tools/slack.mdx @@ -3,9 +3,9 @@ title: Slack description: Send a message to Slack --- -import { BlockInfoCard } from '@/components/ui/block-info-card' +import { BlockInfoCard } from "@/components/ui/block-info-card" -`} /> +{/* MANUAL-CONTENT-START:intro */} [Telegram](https://telegram.org) is a secure, cloud-based messaging platform that enables fast and reliable communication across devices and platforms. With over 700 million monthly active users, Telegram has established itself as one of the world's leading messaging services, known for its security, speed, and powerful API capabilities. @@ -45,6 +46,7 @@ Key features of Telegram include: - Global Reach: Connect with users worldwide with support for multiple languages and platforms In Sim Studio, the Telegram integration enables your agents to leverage these powerful messaging capabilities as part of their workflows. This creates opportunities for automated notifications, alerts, and interactive conversations through Telegram's secure messaging platform. The integration allows agents to send messages programmatically to individuals or channels, enabling timely communication and updates. By connecting Sim Studio with Telegram, you can build intelligent agents that engage users through a secure and widely-adopted messaging platform, perfect for delivering notifications, updates, and interactive communications. +{/* MANUAL-CONTENT-END */} ## Usage Instructions diff --git a/sim/blocks/blocks/drive.ts b/sim/blocks/blocks/google_drive.ts similarity index 100% rename from sim/blocks/blocks/drive.ts rename to sim/blocks/blocks/google_drive.ts diff --git a/sim/blocks/blocks/google_sheets.ts b/sim/blocks/blocks/google_sheets.ts index ff92ef147..3da55297b 100644 --- a/sim/blocks/blocks/google_sheets.ts +++ b/sim/blocks/blocks/google_sheets.ts @@ -1,5 +1,6 @@ import { GoogleSheetsIcon } from '@/components/icons' import { + GoogleSheetsAppendResponse, GoogleSheetsReadResponse, GoogleSheetsUpdateResponse, GoogleSheetsWriteResponse, @@ -10,13 +11,14 @@ type GoogleSheetsResponse = | GoogleSheetsReadResponse | GoogleSheetsWriteResponse | GoogleSheetsUpdateResponse + | GoogleSheetsAppendResponse export const GoogleSheetsBlock: BlockConfig = { type: 'google_sheets', name: 'Google Sheets', description: 'Read, write, and update data', longDescription: - 'Integrate Google Sheets functionality to manage spreadsheet data. Read data from specific ranges, write new data, and update existing cells using OAuth authentication. Supports various input and output formats for flexible data handling.', + 'Integrate Google Sheets functionality to manage spreadsheet data. Read data from specific ranges, write new data, update existing cells, and append data to the end of sheets using OAuth authentication. Supports various input and output formats for flexible data handling.', category: 'tools', bgColor: '#E0E0E0', icon: GoogleSheetsIcon, @@ -31,6 +33,7 @@ export const GoogleSheetsBlock: BlockConfig = { { label: 'Read Data', id: 'read' }, { label: 'Write Data', id: 'write' }, { label: 'Update Data', id: 'update' }, + { label: 'Append Data', id: 'append' }, ], }, // Google Sheets Credentials @@ -113,9 +116,40 @@ export const GoogleSheetsBlock: BlockConfig = { ], condition: { field: 'operation', value: 'update' }, }, + // Append-specific Fields + { + id: 'values', + title: 'Values', + type: 'long-input', + layout: 'full', + placeholder: 'Enter values as JSON array of arrays (e.g., [["A1", "B1"], ["A2", "B2"]])', + condition: { field: 'operation', value: 'append' }, + }, + { + id: 'valueInputOption', + title: 'Value Input Option', + type: 'dropdown', + layout: 'full', + options: [ + { label: 'User Entered (Parse formulas)', id: 'USER_ENTERED' }, + { label: "Raw (Don't parse formulas)", id: 'RAW' }, + ], + condition: { field: 'operation', value: 'append' }, + }, + { + id: 'insertDataOption', + title: 'Insert Data Option', + type: 'dropdown', + layout: 'full', + options: [ + { label: 'Insert Rows (Add new rows)', id: 'INSERT_ROWS' }, + { label: 'Overwrite (Add to existing data)', id: 'OVERWRITE' }, + ], + condition: { field: 'operation', value: 'append' }, + }, ], tools: { - access: ['google_sheets_read', 'google_sheets_write', 'google_sheets_update'], + access: ['google_sheets_read', 'google_sheets_write', 'google_sheets_update', 'google_sheets_append'], config: { tool: (params) => { switch (params.operation) { @@ -125,6 +159,8 @@ export const GoogleSheetsBlock: BlockConfig = { return 'google_sheets_write' case 'update': return 'google_sheets_update' + case 'append': + return 'google_sheets_append' default: throw new Error(`Invalid Google Sheets operation: ${params.operation}`) } @@ -163,6 +199,7 @@ export const GoogleSheetsBlock: BlockConfig = { range: { type: 'string', required: false }, values: { type: 'string', required: false }, valueInputOption: { type: 'string', required: false }, + insertDataOption: { type: 'string', required: false }, }, outputs: { response: { @@ -173,6 +210,7 @@ export const GoogleSheetsBlock: BlockConfig = { updatedRows: 'number', updatedColumns: 'number', updatedCells: 'number', + tableRange: 'string', }, }, }, diff --git a/sim/blocks/registry.ts b/sim/blocks/registry.ts index bac32c3ac..50cb66149 100644 --- a/sim/blocks/registry.ts +++ b/sim/blocks/registry.ts @@ -15,7 +15,7 @@ import { ClayBlock } from './blocks/clay' import { ConditionBlock } from './blocks/condition' import { ConfluenceBlock } from './blocks/confluence' import { GoogleDocsBlock } from './blocks/google_docs' -import { GoogleDriveBlock } from './blocks/drive' +import { GoogleDriveBlock } from './blocks/google_drive' import { ElevenLabsBlock } from './blocks/elevenlabs' import { EvaluatorBlock } from './blocks/evaluator' import { ExaBlock } from './blocks/exa' diff --git a/sim/tools/google_sheets/append.ts b/sim/tools/google_sheets/append.ts new file mode 100644 index 000000000..27aad3d0f --- /dev/null +++ b/sim/tools/google_sheets/append.ts @@ -0,0 +1,121 @@ +import { ToolConfig } from '../types' +import { GoogleSheetsAppendResponse, GoogleSheetsToolParams } from './types' + +export const appendTool: ToolConfig = { + id: 'google_sheets_append', + name: 'Append to Google Sheets', + description: 'Append data to the end of a Google Sheets spreadsheet', + version: '1.0', + oauth: { + required: true, + provider: 'google-sheets', + additionalScopes: ['https://www.googleapis.com/auth/spreadsheets'], + }, + params: { + accessToken: { type: 'string', required: true, description: 'The access token for the Google Sheets API' }, + spreadsheetId: { type: 'string', required: true, description: 'The ID of the spreadsheet to append to' }, + range: { type: 'string', required: false, description: 'The range of cells to append after' }, + values: { type: 'array', required: true, description: 'The data to append to the spreadsheet' }, + valueInputOption: { type: 'string', required: false, description: 'The format of the data to append' }, + insertDataOption: { type: 'string', required: false, description: 'How to insert the data (OVERWRITE or INSERT_ROWS)' }, + includeValuesInResponse: { type: 'boolean', required: false, description: 'Whether to include the appended values in the response' }, + }, + request: { + url: (params) => { + // If range is not provided, use a default range for the first sheet + const range = params.range || 'Sheet1' + + const url = new URL( + `https://sheets.googleapis.com/v4/spreadsheets/${params.spreadsheetId}/values/${encodeURIComponent(range)}:append` + ) + + // Default to USER_ENTERED if not specified + const valueInputOption = params.valueInputOption || 'USER_ENTERED' + url.searchParams.append('valueInputOption', valueInputOption) + + // Default to INSERT_ROWS if not specified + if (params.insertDataOption) { + url.searchParams.append('insertDataOption', params.insertDataOption) + } + + if (params.includeValuesInResponse) { + url.searchParams.append('includeValuesInResponse', 'true') + } + + return url.toString() + }, + method: 'POST', + headers: (params) => ({ + Authorization: `Bearer ${params.accessToken}`, + 'Content-Type': 'application/json', + }), + body: (params) => { + const body: Record = { + majorDimension: params.majorDimension || 'ROWS', + values: params.values || [], + } + + // Only include range if it's provided + if (params.range) { + body.range = params.range + } + + return body + }, + }, + transformResponse: async (response: Response) => { + if (!response.ok) { + const errorText = await response.text() + throw new Error(`Failed to append data to Google Sheets: ${errorText}`) + } + + const data = await response.json() + + // Extract spreadsheet ID from the URL + const urlParts = response.url.split('/spreadsheets/') + const spreadsheetId = urlParts[1]?.split('/')[0] || '' + + // Create a simple metadata object with just the ID and URL + const metadata = { + spreadsheetId, + properties: {}, + spreadsheetUrl: `https://docs.google.com/spreadsheets/d/${spreadsheetId}`, + } + + const result = { + success: true, + output: { + tableRange: data.tableRange || '', + updatedRange: data.updates?.updatedRange || '', + updatedRows: data.updates?.updatedRows || 0, + updatedColumns: data.updates?.updatedColumns || 0, + updatedCells: data.updates?.updatedCells || 0, + metadata: { + spreadsheetId: metadata.spreadsheetId, + spreadsheetUrl: metadata.spreadsheetUrl, + }, + }, + } + + return result + }, + transformError: (error) => { + // If it's an Error instance with a message, use that + if (error instanceof Error) { + return error.message + } + + // If it's an object with an error or message property + if (typeof error === 'object' && error !== null) { + if (error.error) { + return typeof error.error === 'string' ? error.error : JSON.stringify(error.error) + } + if (error.message) { + return error.message + } + } + + // Default fallback message + return 'An error occurred while appending to Google Sheets' + }, +} \ No newline at end of file diff --git a/sim/tools/google_sheets/index.ts b/sim/tools/google_sheets/index.ts index a63c21f2d..a8d2990db 100644 --- a/sim/tools/google_sheets/index.ts +++ b/sim/tools/google_sheets/index.ts @@ -1,3 +1,4 @@ +import { appendTool } from './append' import { readTool } from './read' import { updateTool } from './update' import { writeTool } from './write' @@ -5,3 +6,4 @@ import { writeTool } from './write' export const sheetsReadTool = readTool export const sheetsWriteTool = writeTool export const sheetsUpdateTool = updateTool +export const sheetsAppendTool = appendTool diff --git a/sim/tools/google_sheets/types.ts b/sim/tools/google_sheets/types.ts index 979482708..847853564 100644 --- a/sim/tools/google_sheets/types.ts +++ b/sim/tools/google_sheets/types.ts @@ -47,12 +47,24 @@ export interface GoogleSheetsUpdateResponse extends ToolResponse { } } +export interface GoogleSheetsAppendResponse extends ToolResponse { + output: { + tableRange: string + updatedRange: string + updatedRows: number + updatedColumns: number + updatedCells: number + metadata: GoogleSheetsMetadata + } +} + export interface GoogleSheetsToolParams { accessToken: string spreadsheetId: string range?: string values?: any[][] valueInputOption?: 'RAW' | 'USER_ENTERED' + insertDataOption?: 'OVERWRITE' | 'INSERT_ROWS' includeValuesInResponse?: boolean responseValueRenderOption?: 'FORMATTED_VALUE' | 'UNFORMATTED_VALUE' | 'FORMULA' majorDimension?: 'ROWS' | 'COLUMNS' diff --git a/sim/tools/registry.ts b/sim/tools/registry.ts index 4b572ff60..6e27ca3ca 100644 --- a/sim/tools/registry.ts +++ b/sim/tools/registry.ts @@ -25,7 +25,7 @@ import { pineconeFetchTool, pineconeGenerateEmbeddingsTool, pineconeSearchTextTo import { redditHotPostsTool, redditGetPostsTool, redditGetCommentsTool } from './reddit' import { opportunitiesTool as salesforceOpportunities } from './salesforce/opportunities' import { searchTool as serperSearch } from './serper' -import { sheetsReadTool, sheetsUpdateTool, sheetsWriteTool } from './google_sheets' +import { sheetsReadTool, sheetsUpdateTool, sheetsWriteTool, sheetsAppendTool } from './google_sheets' import { slackMessageTool } from './slack' import { stagehandAgentTool, stagehandExtractTool } from './stagehand' import { supabaseInsertTool, supabaseQueryTool } from './supabase' @@ -108,6 +108,7 @@ export const tools: Record = { google_sheets_read: sheetsReadTool, google_sheets_write: sheetsWriteTool, google_sheets_update: sheetsUpdateTool, + google_sheets_append: sheetsAppendTool, guesty_reservation: guestyReservationTool, guesty_guest: guestyGuestTool, perplexity_chat: perplexityChatTool,