diff --git a/packages/@uppy/companion/src/server/provider/drive/index.js b/packages/@uppy/companion/src/server/provider/drive/index.js index 384a86b4ed..e17e067c5e 100644 --- a/packages/@uppy/companion/src/server/provider/drive/index.js +++ b/packages/@uppy/companion/src/server/provider/drive/index.js @@ -17,7 +17,7 @@ const mockAccessTokenExpiredError = undefined // const mockAccessTokenExpiredError = true // const mockAccessTokenExpiredError = '' -const DRIVE_FILE_FIELDS = 'kind,id,imageMediaMetadata,name,mimeType,ownedByMe,size,modifiedTime,iconLink,thumbnailLink,teamDriveId,videoMediaMetadata,shortcutDetails(targetId,targetMimeType)' +const DRIVE_FILE_FIELDS = 'kind,id,imageMediaMetadata,name,mimeType,ownedByMe,size,modifiedTime,iconLink,thumbnailLink,teamDriveId,videoMediaMetadata,exportLinks,shortcutDetails(targetId,targetMimeType)' const DRIVE_FILES_FIELDS = `kind,nextPageToken,incompleteSearch,files(${DRIVE_FILE_FIELDS})` // using wildcard to get all 'drive' fields because specifying fields seems no to work for the /drives endpoint const SHARED_DRIVE_FIELDS = '*' @@ -139,14 +139,29 @@ class Drive extends Provider { return this.#withErrorHandling('provider.drive.download.error', async () => { const client = getClient({ token }) - const { mimeType, id } = await getStats({ id: idIn, token }) + const { mimeType, id, exportLinks } = await getStats({ id: idIn, token }) let stream if (isGsuiteFile(mimeType)) { const mimeType2 = getGsuiteExportType(mimeType) logger.info(`calling google file export for ${id} to ${mimeType2}`, 'provider.drive.export') - stream = client.stream.get(`files/${encodeURIComponent(id)}/export`, { searchParams: { supportsAllDrives: true, mimeType: mimeType2 }, responseType: 'json' }) + + // GSuite files exported with large converted size results in error using standard export method. + // Error message: "This file is too large to be exported.". + // Issue logged in Google APIs: https://github.com/googleapis/google-api-nodejs-client/issues/3446 + // Implemented based on the answer from StackOverflow: https://stackoverflow.com/a/59168288 + const mimeTypeExportLink = exportLinks?.[mimeType2] + if (mimeTypeExportLink) { + const gSuiteFilesClient = got.extend({ + headers: { + authorization: `Bearer ${token}`, + }, + }) + stream = gSuiteFilesClient.stream.get(mimeTypeExportLink, { responseType: 'json' }) + } else { + stream = client.stream.get(`files/${encodeURIComponent(id)}/export`, { searchParams: { supportsAllDrives: true, mimeType: mimeType2 }, responseType: 'json' }) + } } else { stream = client.stream.get(`files/${encodeURIComponent(id)}`, { searchParams: { alt: 'media', supportsAllDrives: true }, responseType: 'json' }) } diff --git a/packages/@uppy/companion/test/__tests__/providers.js b/packages/@uppy/companion/test/__tests__/providers.js index 98c472e55e..bd1c31ae8c 100644 --- a/packages/@uppy/companion/test/__tests__/providers.js +++ b/packages/@uppy/companion/test/__tests__/providers.js @@ -157,7 +157,7 @@ describe('list provider files', () => { kind: 'drive#driveList', drives: [], }) - nock('https://www.googleapis.com').get('/drive/v3/files?fields=kind%2CnextPageToken%2CincompleteSearch%2Cfiles%28kind%2Cid%2CimageMediaMetadata%2Cname%2CmimeType%2CownedByMe%2Csize%2CmodifiedTime%2CiconLink%2CthumbnailLink%2CteamDriveId%2CvideoMediaMetadata%2CshortcutDetails%28targetId%2CtargetMimeType%29%29&q=%28%27root%27+in+parents%29+and+trashed%3Dfalse&pageSize=1000&orderBy=folder%2Cname&includeItemsFromAllDrives=true&supportsAllDrives=true').reply(200, { + nock('https://www.googleapis.com').get('/drive/v3/files?fields=kind%2CnextPageToken%2CincompleteSearch%2Cfiles%28kind%2Cid%2CimageMediaMetadata%2Cname%2CmimeType%2CownedByMe%2Csize%2CmodifiedTime%2CiconLink%2CthumbnailLink%2CteamDriveId%2CvideoMediaMetadata%2CexportLinks%2CshortcutDetails%28targetId%2CtargetMimeType%29%29&q=%28%27root%27+in+parents%29+and+trashed%3Dfalse&pageSize=1000&orderBy=folder%2Cname&includeItemsFromAllDrives=true&supportsAllDrives=true').reply(200, { kind: 'drive#fileList', nextPageToken: defaults.NEXT_PAGE_TOKEN, files: [ diff --git a/packages/@uppy/companion/test/fixtures/drive.js b/packages/@uppy/companion/test/fixtures/drive.js index 094c1ee4ef..8b136f3a1a 100644 --- a/packages/@uppy/companion/test/fixtures/drive.js +++ b/packages/@uppy/companion/test/fixtures/drive.js @@ -6,7 +6,7 @@ module.exports.expects = {} module.exports.nockGoogleDriveAboutCall = () => nock('https://www.googleapis.com').get((uri) => uri.includes('about')).reply(200, { user: { emailAddress: 'john.doe@transloadit.com' } }) module.exports.nockGoogleDownloadFile = ({ times = 1 } = {}) => { - nock('https://www.googleapis.com').get(`/drive/v3/files/${defaults.ITEM_ID}?fields=kind%2Cid%2CimageMediaMetadata%2Cname%2CmimeType%2CownedByMe%2Csize%2CmodifiedTime%2CiconLink%2CthumbnailLink%2CteamDriveId%2CvideoMediaMetadata%2CshortcutDetails%28targetId%2CtargetMimeType%29&supportsAllDrives=true`).times(times).reply(200, { + nock('https://www.googleapis.com').get(`/drive/v3/files/${defaults.ITEM_ID}?fields=kind%2Cid%2CimageMediaMetadata%2Cname%2CmimeType%2CownedByMe%2Csize%2CmodifiedTime%2CiconLink%2CthumbnailLink%2CteamDriveId%2CvideoMediaMetadata%2CexportLinks%2CshortcutDetails%28targetId%2CtargetMimeType%29&supportsAllDrives=true`).times(times).reply(200, { kind: 'drive#file', id: defaults.ITEM_ID, name: 'MY DUMMY FILE NAME.mp4',