mirror of
https://github.com/simstudioai/sim.git
synced 2026-09-24 15:45:35 +08:00
fix(tools): fixed docs create & write tools
This commit is contained in:
+41
-93
@@ -21,16 +21,8 @@ export const createTool: ToolConfig<GoogleDocsToolParams, GoogleDocsCreateRespon
|
||||
folderId: { type: 'string', required: false },
|
||||
},
|
||||
request: {
|
||||
url: (params) => {
|
||||
// Build URL with query parameters to pass content and folderId
|
||||
const url = new URL('https://docs.googleapis.com/v1/documents')
|
||||
if (params.content) {
|
||||
url.searchParams.append('content', params.content)
|
||||
}
|
||||
if (params.folderId) {
|
||||
url.searchParams.append('folderId', params.folderId)
|
||||
}
|
||||
return url.toString()
|
||||
url: () => {
|
||||
return 'https://docs.googleapis.com/v1/documents'
|
||||
},
|
||||
method: 'POST',
|
||||
headers: (params) => {
|
||||
@@ -42,7 +34,6 @@ export const createTool: ToolConfig<GoogleDocsToolParams, GoogleDocsCreateRespon
|
||||
return {
|
||||
Authorization: `Bearer ${params.accessToken}`,
|
||||
'Content-Type': 'application/json',
|
||||
'X-Access-Token': params.accessToken, // Store access token in a custom header for later use
|
||||
}
|
||||
},
|
||||
body: (params) => {
|
||||
@@ -52,105 +43,62 @@ export const createTool: ToolConfig<GoogleDocsToolParams, GoogleDocsCreateRespon
|
||||
}
|
||||
|
||||
// Create a new document with the specified title
|
||||
return {
|
||||
const requestBody = {
|
||||
title: params.title,
|
||||
}
|
||||
|
||||
return requestBody
|
||||
},
|
||||
},
|
||||
transformResponse: async (response: Response) => {
|
||||
if (!response.ok) {
|
||||
const errorText = await response.text()
|
||||
throw new Error(`Failed to create Google Docs document: ${errorText}`)
|
||||
}
|
||||
|
||||
const data = await response.json()
|
||||
const documentId = data.documentId
|
||||
|
||||
// Get access token from the custom header we set in the request
|
||||
const accessToken = response.headers.get('X-Access-Token') || ''
|
||||
|
||||
// Extract content and folderId from the request URL query parameters
|
||||
const requestUrl = new URL(response.url)
|
||||
const content = requestUrl.searchParams.get('content') || ''
|
||||
const folderId = requestUrl.searchParams.get('folderId') || ''
|
||||
|
||||
// If content was provided, we need to update the document with content
|
||||
if (documentId && content) {
|
||||
let errorText = ''
|
||||
try {
|
||||
// Make a second request to update the document with content
|
||||
const updateResponse = await fetch(
|
||||
`https://docs.googleapis.com/v1/documents/${documentId}:batchUpdate`,
|
||||
{
|
||||
method: 'POST',
|
||||
headers: {
|
||||
Authorization: `Bearer ${accessToken}`,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
requests: [
|
||||
{
|
||||
insertText: {
|
||||
location: {
|
||||
index: 1,
|
||||
},
|
||||
text: content,
|
||||
},
|
||||
},
|
||||
],
|
||||
}),
|
||||
}
|
||||
)
|
||||
|
||||
if (!updateResponse.ok) {
|
||||
console.warn('Failed to update document with content, but document was created')
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn('Error updating document with content:', error)
|
||||
const responseClone = response.clone()
|
||||
const responseText = await responseClone.text()
|
||||
errorText = responseText
|
||||
} catch (e) {
|
||||
errorText = 'Unable to read error response'
|
||||
}
|
||||
|
||||
throw new Error(`Failed to create Google Docs document (${response.status}): ${errorText}`)
|
||||
}
|
||||
|
||||
// If folderId was provided, we need to move the document to that folder
|
||||
if (documentId && folderId) {
|
||||
try {
|
||||
// Make a request to the Drive API to move the file
|
||||
const moveResponse = await fetch(
|
||||
`https://www.googleapis.com/drive/v3/files/${documentId}?addParents=${folderId}`,
|
||||
{
|
||||
method: 'PATCH',
|
||||
headers: {
|
||||
Authorization: `Bearer ${accessToken}`,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
}
|
||||
)
|
||||
try {
|
||||
// Get the response data
|
||||
const responseText = await response.text()
|
||||
const data = JSON.parse(responseText)
|
||||
const documentId = data.documentId
|
||||
const title = data.title
|
||||
|
||||
if (!moveResponse.ok) {
|
||||
console.warn('Failed to move document to specified folder, but document was created')
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn('Error moving document to folder:', error)
|
||||
// Create document metadata
|
||||
const metadata = {
|
||||
documentId,
|
||||
title: title || 'Untitled Document',
|
||||
mimeType: 'application/vnd.google-apps.document',
|
||||
url: `https://docs.google.com/document/d/${documentId}/edit`,
|
||||
}
|
||||
}
|
||||
|
||||
// Create document metadata
|
||||
const metadata = {
|
||||
documentId: data.documentId,
|
||||
title: data.title || 'Untitled Document',
|
||||
mimeType: 'application/vnd.google-apps.document',
|
||||
url: `https://docs.google.com/document/d/${data.documentId}/edit`,
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
metadata,
|
||||
},
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
metadata,
|
||||
},
|
||||
}
|
||||
} catch (error) {
|
||||
throw error
|
||||
}
|
||||
},
|
||||
transformError: (error) => {
|
||||
if (typeof error === 'object' && error !== null) {
|
||||
return JSON.stringify(error) || 'An error occurred while creating Google Docs document'
|
||||
if (error.message) {
|
||||
return error.message
|
||||
}
|
||||
return (
|
||||
JSON.stringify(error, null, 2) || 'An error occurred while creating Google Docs document'
|
||||
)
|
||||
}
|
||||
return error.message || 'An error occurred while creating Google Docs document'
|
||||
|
||||
return error.toString() || 'An error occurred while creating Google Docs document'
|
||||
},
|
||||
}
|
||||
|
||||
+55
-34
@@ -47,63 +47,84 @@ export const writeTool: ToolConfig<GoogleDocsToolParams, GoogleDocsWriteResponse
|
||||
throw new Error('Content is required')
|
||||
}
|
||||
|
||||
// Create a batch update request to replace all content
|
||||
return {
|
||||
// Following the exact format from the Google Docs API examples
|
||||
// Note: We're not including tabId since it's optional for the main document body
|
||||
const requestBody = {
|
||||
requests: [
|
||||
{
|
||||
// First, delete all existing content
|
||||
deleteContentRange: {
|
||||
range: {
|
||||
startIndex: 1, // Start after the initial paragraph marker
|
||||
endIndex: 999999, // A large number to ensure all content is deleted
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
// Then insert the new content
|
||||
insertText: {
|
||||
location: {
|
||||
index: 1, // Insert after the initial paragraph marker
|
||||
index: 1,
|
||||
},
|
||||
text: params.content,
|
||||
},
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
return requestBody
|
||||
},
|
||||
},
|
||||
transformResponse: async (response: Response) => {
|
||||
if (!response.ok) {
|
||||
const errorText = await response.text()
|
||||
throw new Error(`Failed to write to Google Docs document: ${errorText}`)
|
||||
let errorText = ''
|
||||
try {
|
||||
const responseClone = response.clone()
|
||||
const responseText = await responseClone.text()
|
||||
errorText = responseText
|
||||
} catch (e) {
|
||||
errorText = 'Unable to read error response'
|
||||
}
|
||||
|
||||
throw new Error(`Failed to write to Google Docs document (${response.status}): ${errorText}`)
|
||||
}
|
||||
|
||||
const data = await response.json()
|
||||
try {
|
||||
const responseText = await response.text()
|
||||
|
||||
// Get the document ID from the URL
|
||||
const urlParts = response.url.split('/')
|
||||
const documentId = urlParts[urlParts.length - 2].split(':')[0]
|
||||
// Parse the response if it's not empty
|
||||
let data = {}
|
||||
if (responseText.trim()) {
|
||||
data = JSON.parse(responseText)
|
||||
}
|
||||
|
||||
// Create document metadata
|
||||
const metadata = {
|
||||
documentId,
|
||||
title: 'Updated Document', // We don't get the title back from the batchUpdate endpoint
|
||||
mimeType: 'application/vnd.google-apps.document',
|
||||
url: `https://docs.google.com/document/d/${documentId}/edit`,
|
||||
}
|
||||
// Get the document ID from the URL
|
||||
const urlParts = response.url.split('/')
|
||||
let documentId = ''
|
||||
for (let i = 0; i < urlParts.length; i++) {
|
||||
if (urlParts[i] === 'documents' && i + 1 < urlParts.length) {
|
||||
documentId = urlParts[i + 1].split(':')[0]
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
updatedContent: true,
|
||||
metadata,
|
||||
},
|
||||
// Create document metadata
|
||||
const metadata = {
|
||||
documentId,
|
||||
title: 'Updated Document',
|
||||
mimeType: 'application/vnd.google-apps.document',
|
||||
url: `https://docs.google.com/document/d/${documentId}/edit`,
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
updatedContent: true,
|
||||
metadata,
|
||||
},
|
||||
}
|
||||
} catch (error) {
|
||||
throw error
|
||||
}
|
||||
},
|
||||
transformError: (error) => {
|
||||
if (typeof error === 'object' && error !== null) {
|
||||
return JSON.stringify(error) || 'An error occurred while writing to Google Docs'
|
||||
if (error.message) {
|
||||
return error.message
|
||||
}
|
||||
return JSON.stringify(error, null, 2) || 'An error occurred while writing to Google Docs'
|
||||
}
|
||||
return error.message || 'An error occurred while writing to Google Docs'
|
||||
|
||||
return error.toString() || 'An error occurred while writing to Google Docs'
|
||||
},
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user