Skip to content
23 changes: 22 additions & 1 deletion apps/sim/app/api/tools/google_drive/download/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
ALL_REVISION_FIELDS,
DEFAULT_EXPORT_FORMATS,
GOOGLE_WORKSPACE_MIME_TYPES,
VALID_EXPORT_FORMATS,
} from '@/tools/google_drive/utils'

export const dynamic = 'force-dynamic'
Expand Down Expand Up @@ -65,10 +66,12 @@ export async function POST(request: NextRequest) {
const {
accessToken,
fileId,
mimeType: exportMimeType,
mimeType: rawExportMimeType,
fileName,
includeRevisions,
} = validatedData
const exportMimeType =
rawExportMimeType && rawExportMimeType !== 'auto' ? rawExportMimeType : null
const authHeader = `Bearer ${accessToken}`

logger.info(`[${requestId}] Getting file metadata from Google Drive`, { fileId })
Expand Down Expand Up @@ -112,6 +115,24 @@ export async function POST(request: NextRequest) {

if (GOOGLE_WORKSPACE_MIME_TYPES.includes(fileMimeType)) {
const exportFormat = exportMimeType || DEFAULT_EXPORT_FORMATS[fileMimeType] || 'text/plain'

const validFormats = VALID_EXPORT_FORMATS[fileMimeType]
if (validFormats && !validFormats.includes(exportFormat)) {
logger.warn(`[${requestId}] Unsupported export format requested`, {
fileId,
fileMimeType,
requestedFormat: exportFormat,
validFormats,
})
return NextResponse.json(
{
success: false,
error: `Export format "${exportFormat}" is not supported for this file type. Supported formats: ${validFormats.join(', ')}`,
},
{ status: 400 }
)
}

finalMimeType = exportFormat

logger.info(`[${requestId}] Exporting Google Workspace file`, {
Expand Down
6 changes: 4 additions & 2 deletions apps/sim/blocks/blocks/google_drive.ts
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,7 @@ Return ONLY the query string - no explanations, no quotes around the whole thing
title: 'Export Format',
type: 'dropdown',
options: [
{ label: 'Auto (best format for file type)', id: 'auto' },
{ label: 'Plain Text (text/plain)', id: 'text/plain' },
{ label: 'HTML (text/html)', id: 'text/html' },
{ label: 'PDF (application/pdf)', id: 'application/pdf' },
Expand All @@ -333,7 +334,8 @@ Return ONLY the query string - no explanations, no quotes around the whole thing
},
{ label: 'CSV (text/csv)', id: 'text/csv' },
],
placeholder: 'Optional: Choose export format for Google Docs/Sheets/Slides',
value: () => 'auto',
placeholder: 'Export format for Google Docs/Sheets/Slides',
condition: { field: 'operation', value: 'download' },
},
{
Expand Down Expand Up @@ -867,7 +869,7 @@ Return ONLY the message text - no subject line, no greetings/signatures, no extr
destinationFolderId: effectiveDestinationFolderId,
file: normalizedFile,
pageSize: rest.pageSize ? Number.parseInt(rest.pageSize as string, 10) : undefined,
mimeType: mimeType,
mimeType: mimeType === 'auto' ? undefined : mimeType,
type: shareType, // Map shareType to type for share tool
starred: starredValue,
sendNotification: sendNotificationValue,
Expand Down
46 changes: 44 additions & 2 deletions apps/sim/tools/google_drive/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,8 +111,50 @@ export const DEFAULT_EXPORT_FORMATS: Record<string, string> = {
'application/vnd.google-apps.spreadsheet': 'text/csv',
'application/vnd.google-apps.presentation': 'text/plain',
'application/vnd.google-apps.drawing': 'image/png',
'application/vnd.google-apps.form': 'application/pdf',
'application/vnd.google-apps.script': 'application/json',
'application/vnd.google-apps.form': 'application/zip',
'application/vnd.google-apps.script': 'application/vnd.google-apps.script+json',
}

/**
* Valid export formats per Google Workspace file type.
* See: https://developers.google.com/drive/api/guides/ref-export-formats
*/
export const VALID_EXPORT_FORMATS: Record<string, string[]> = {
'application/vnd.google-apps.document': [
'text/plain',
'text/html',
'application/pdf',
'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
'application/vnd.oasis.opendocument.text',
'application/rtf',
'application/epub+zip',
'text/markdown',
],
'application/vnd.google-apps.spreadsheet': [
'text/csv',
'text/tab-separated-values',
'application/pdf',
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
'application/vnd.oasis.opendocument.spreadsheet',
'application/zip',
],
'application/vnd.google-apps.presentation': [
'text/plain',
'application/pdf',
'application/vnd.openxmlformats-officedocument.presentationml.presentation',
'application/vnd.oasis.opendocument.presentation',
'image/jpeg',
'image/png',
'image/svg+xml',
],
'application/vnd.google-apps.drawing': [
'application/pdf',
'image/jpeg',
'image/png',
'image/svg+xml',
],
'application/vnd.google-apps.form': ['application/zip'],
'application/vnd.google-apps.script': ['application/vnd.google-apps.script+json'],
}

export const SOURCE_MIME_TYPES: Record<string, string> = {
Expand Down
Loading