mirror of
https://github.com/simstudioai/sim.git
synced 2026-01-10 07:27:57 -05:00
fix(google-drive): added support for shared drive (#2232)
* added param for shared drive * removed comments --------- Co-authored-by: aadamgough <adam@sim.ai>
This commit is contained in:
@@ -57,6 +57,35 @@ export async function GET(request: NextRequest) {
|
||||
}
|
||||
)
|
||||
|
||||
if (!response.ok && response.status === 404) {
|
||||
logger.info(`[${requestId}] File not found, checking if it's a shared drive`)
|
||||
const driveResponse = await fetch(
|
||||
`https://www.googleapis.com/drive/v3/drives/${fileId}?fields=id,name`,
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${accessToken}`,
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
if (driveResponse.ok) {
|
||||
const driveData = await driveResponse.json()
|
||||
logger.info(`[${requestId}] Found shared drive: ${driveData.name}`)
|
||||
return NextResponse.json(
|
||||
{
|
||||
file: {
|
||||
id: driveData.id,
|
||||
name: driveData.name,
|
||||
mimeType: 'application/vnd.google-apps.folder',
|
||||
iconLink:
|
||||
'https://ssl.gstatic.com/docs/doclist/images/icon_11_shared_collection_list_1.png',
|
||||
},
|
||||
},
|
||||
{ status: 200 }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json().catch(() => ({ error: { message: 'Unknown error' } }))
|
||||
logger.error(`[${requestId}] Google Drive API error`, {
|
||||
@@ -112,12 +141,12 @@ export async function GET(request: NextRequest) {
|
||||
if (!file.exportLinks) {
|
||||
file.downloadUrl = `https://www.googleapis.com/drive/v3/files/${file.id}/export?mimeType=${encodeURIComponent(
|
||||
format
|
||||
)}`
|
||||
)}&supportsAllDrives=true`
|
||||
} else {
|
||||
file.downloadUrl = file.exportLinks[format]
|
||||
}
|
||||
} else {
|
||||
file.downloadUrl = `https://www.googleapis.com/drive/v3/files/${file.id}?alt=media`
|
||||
file.downloadUrl = `https://www.googleapis.com/drive/v3/files/${file.id}?alt=media&supportsAllDrives=true`
|
||||
}
|
||||
|
||||
return NextResponse.json({ file }, { status: 200 })
|
||||
|
||||
@@ -12,6 +12,62 @@ function escapeForDriveQuery(value: string): string {
|
||||
return value.replace(/\\/g, '\\\\').replace(/'/g, "\\'")
|
||||
}
|
||||
|
||||
interface SharedDrive {
|
||||
id: string
|
||||
name: string
|
||||
kind: string
|
||||
}
|
||||
|
||||
interface DriveFile {
|
||||
id: string
|
||||
name: string
|
||||
mimeType: string
|
||||
iconLink?: string
|
||||
webViewLink?: string
|
||||
thumbnailLink?: string
|
||||
createdTime?: string
|
||||
modifiedTime?: string
|
||||
size?: string
|
||||
owners?: any[]
|
||||
parents?: string[]
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches shared drives the user has access to
|
||||
*/
|
||||
async function fetchSharedDrives(accessToken: string, requestId: string): Promise<DriveFile[]> {
|
||||
try {
|
||||
const response = await fetch(
|
||||
'https://www.googleapis.com/drive/v3/drives?pageSize=100&fields=drives(id,name)',
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${accessToken}`,
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
if (!response.ok) {
|
||||
logger.warn(`[${requestId}] Failed to fetch shared drives`, {
|
||||
status: response.status,
|
||||
})
|
||||
return []
|
||||
}
|
||||
|
||||
const data = await response.json()
|
||||
const drives: SharedDrive[] = data.drives || []
|
||||
|
||||
return drives.map((drive) => ({
|
||||
id: drive.id,
|
||||
name: drive.name,
|
||||
mimeType: 'application/vnd.google-apps.folder',
|
||||
iconLink: 'https://ssl.gstatic.com/docs/doclist/images/icon_11_shared_collection_list_1.png',
|
||||
}))
|
||||
} catch (error) {
|
||||
logger.error(`[${requestId}] Error fetching shared drives`, error)
|
||||
return []
|
||||
}
|
||||
}
|
||||
|
||||
export async function GET(request: NextRequest) {
|
||||
const requestId = generateRequestId()
|
||||
logger.info(`[${requestId}] Google Drive files request received`)
|
||||
@@ -65,7 +121,7 @@ export async function GET(request: NextRequest) {
|
||||
const q = encodeURIComponent(qParts.join(' and '))
|
||||
|
||||
const response = await fetch(
|
||||
`https://www.googleapis.com/drive/v3/files?q=${q}&supportsAllDrives=true&includeItemsFromAllDrives=true&spaces=drive&fields=files(id,name,mimeType,iconLink,webViewLink,thumbnailLink,createdTime,modifiedTime,size,owners,parents)`,
|
||||
`https://www.googleapis.com/drive/v3/files?q=${q}&corpora=allDrives&supportsAllDrives=true&includeItemsFromAllDrives=true&fields=files(id,name,mimeType,iconLink,webViewLink,thumbnailLink,createdTime,modifiedTime,size,owners,parents)`,
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${accessToken}`,
|
||||
@@ -88,14 +144,26 @@ export async function GET(request: NextRequest) {
|
||||
}
|
||||
|
||||
const data = await response.json()
|
||||
let files = data.files || []
|
||||
let files: DriveFile[] = data.files || []
|
||||
|
||||
if (mimeType === 'application/vnd.google-apps.spreadsheet') {
|
||||
files = files.filter(
|
||||
(file: any) => file.mimeType === 'application/vnd.google-apps.spreadsheet'
|
||||
(file: DriveFile) => file.mimeType === 'application/vnd.google-apps.spreadsheet'
|
||||
)
|
||||
} else if (mimeType === 'application/vnd.google-apps.document') {
|
||||
files = files.filter((file: any) => file.mimeType === 'application/vnd.google-apps.document')
|
||||
files = files.filter(
|
||||
(file: DriveFile) => file.mimeType === 'application/vnd.google-apps.document'
|
||||
)
|
||||
}
|
||||
|
||||
const isRootFolderListing =
|
||||
!folderId && mimeType === 'application/vnd.google-apps.folder' && !query
|
||||
if (isRootFolderListing) {
|
||||
const sharedDrives = await fetchSharedDrives(accessToken, requestId)
|
||||
if (sharedDrives.length > 0) {
|
||||
logger.info(`[${requestId}] Found ${sharedDrives.length} shared drives`)
|
||||
files = [...sharedDrives, ...files]
|
||||
}
|
||||
}
|
||||
|
||||
return NextResponse.json({ files }, { status: 200 })
|
||||
|
||||
@@ -50,7 +50,7 @@ export const createTool: ToolConfig<GoogleDocsToolParams, GoogleDocsCreateRespon
|
||||
|
||||
request: {
|
||||
url: () => {
|
||||
return 'https://www.googleapis.com/drive/v3/files'
|
||||
return 'https://www.googleapis.com/drive/v3/files?supportsAllDrives=true'
|
||||
},
|
||||
method: 'POST',
|
||||
headers: (params) => {
|
||||
|
||||
@@ -45,7 +45,7 @@ export const downloadTool: ToolConfig<GoogleDriveToolParams, GoogleDriveDownload
|
||||
|
||||
request: {
|
||||
url: (params) =>
|
||||
`https://www.googleapis.com/drive/v3/files/${params.fileId}?fields=id,name,mimeType`,
|
||||
`https://www.googleapis.com/drive/v3/files/${params.fileId}?fields=id,name,mimeType&supportsAllDrives=true`,
|
||||
method: 'GET',
|
||||
headers: (params) => ({
|
||||
Authorization: `Bearer ${params.accessToken}`,
|
||||
@@ -83,7 +83,7 @@ export const downloadTool: ToolConfig<GoogleDriveToolParams, GoogleDriveDownload
|
||||
})
|
||||
|
||||
const exportResponse = await fetch(
|
||||
`https://www.googleapis.com/drive/v3/files/${fileId}/export?mimeType=${encodeURIComponent(exportFormat)}`,
|
||||
`https://www.googleapis.com/drive/v3/files/${fileId}/export?mimeType=${encodeURIComponent(exportFormat)}&supportsAllDrives=true`,
|
||||
{
|
||||
headers: {
|
||||
Authorization: authHeader,
|
||||
@@ -110,7 +110,7 @@ export const downloadTool: ToolConfig<GoogleDriveToolParams, GoogleDriveDownload
|
||||
})
|
||||
|
||||
const downloadResponse = await fetch(
|
||||
`https://www.googleapis.com/drive/v3/files/${fileId}?alt=media`,
|
||||
`https://www.googleapis.com/drive/v3/files/${fileId}?alt=media&supportsAllDrives=true`,
|
||||
{
|
||||
headers: {
|
||||
Authorization: authHeader,
|
||||
|
||||
@@ -43,7 +43,7 @@ export const getContentTool: ToolConfig<GoogleDriveToolParams, GoogleDriveGetCon
|
||||
|
||||
request: {
|
||||
url: (params) =>
|
||||
`https://www.googleapis.com/drive/v3/files/${params.fileId}?fields=id,name,mimeType`,
|
||||
`https://www.googleapis.com/drive/v3/files/${params.fileId}?fields=id,name,mimeType&supportsAllDrives=true`,
|
||||
method: 'GET',
|
||||
headers: (params) => ({
|
||||
Authorization: `Bearer ${params.accessToken}`,
|
||||
@@ -77,7 +77,7 @@ export const getContentTool: ToolConfig<GoogleDriveToolParams, GoogleDriveGetCon
|
||||
})
|
||||
|
||||
const exportResponse = await fetch(
|
||||
`https://www.googleapis.com/drive/v3/files/${fileId}/export?mimeType=${encodeURIComponent(exportFormat)}`,
|
||||
`https://www.googleapis.com/drive/v3/files/${fileId}/export?mimeType=${encodeURIComponent(exportFormat)}&supportsAllDrives=true`,
|
||||
{
|
||||
headers: {
|
||||
Authorization: authHeader,
|
||||
@@ -103,7 +103,7 @@ export const getContentTool: ToolConfig<GoogleDriveToolParams, GoogleDriveGetCon
|
||||
})
|
||||
|
||||
const downloadResponse = await fetch(
|
||||
`https://www.googleapis.com/drive/v3/files/${fileId}?alt=media`,
|
||||
`https://www.googleapis.com/drive/v3/files/${fileId}?alt=media&supportsAllDrives=true`,
|
||||
{
|
||||
headers: {
|
||||
Authorization: authHeader,
|
||||
@@ -125,7 +125,7 @@ export const getContentTool: ToolConfig<GoogleDriveToolParams, GoogleDriveGetCon
|
||||
}
|
||||
|
||||
const metadataResponse = await fetch(
|
||||
`https://www.googleapis.com/drive/v3/files/${fileId}?fields=id,name,mimeType,webViewLink,webContentLink,size,createdTime,modifiedTime,parents`,
|
||||
`https://www.googleapis.com/drive/v3/files/${fileId}?fields=id,name,mimeType,webViewLink,webContentLink,size,createdTime,modifiedTime,parents&supportsAllDrives=true`,
|
||||
{
|
||||
headers: {
|
||||
Authorization: authHeader,
|
||||
|
||||
@@ -59,10 +59,10 @@ export const listTool: ToolConfig<GoogleDriveToolParams, GoogleDriveListResponse
|
||||
'fields',
|
||||
'files(id,name,mimeType,webViewLink,webContentLink,size,createdTime,modifiedTime,parents),nextPageToken'
|
||||
)
|
||||
// Ensure shared drives support
|
||||
// Ensure shared drives support - corpora=allDrives is critical for searching across shared drives
|
||||
url.searchParams.append('corpora', 'allDrives')
|
||||
url.searchParams.append('supportsAllDrives', 'true')
|
||||
url.searchParams.append('includeItemsFromAllDrives', 'true')
|
||||
url.searchParams.append('spaces', 'drive')
|
||||
|
||||
// Build the query conditions
|
||||
const conditions = ['trashed = false'] // Always exclude trashed files
|
||||
|
||||
@@ -53,7 +53,7 @@ export const createTool: ToolConfig<GoogleSlidesToolParams, GoogleSlidesCreateRe
|
||||
|
||||
request: {
|
||||
url: () => {
|
||||
return 'https://www.googleapis.com/drive/v3/files'
|
||||
return 'https://www.googleapis.com/drive/v3/files?supportsAllDrives=true'
|
||||
},
|
||||
method: 'POST',
|
||||
headers: (params) => {
|
||||
|
||||
Reference in New Issue
Block a user