uppy icon indicating copy to clipboard operation
uppy copied to clipboard

@uppy/companion: fix google drive gsuite export large size

Open milannakum opened this issue 1 year ago • 2 comments

Fix for GSuite exporting large file based on the StackOverflow answer is working, just have to use the specific export link provided by API based on the mimeType.

milannakum avatar May 03 '24 23:05 milannakum

Diff output files
diff --git a/packages/@uppy/companion/lib/server/provider/drive/index.js b/packages/@uppy/companion/lib/server/provider/drive/index.js
index 872cf5c..02359f6 100644
--- a/packages/@uppy/companion/lib/server/provider/drive/index.js
+++ b/packages/@uppy/companion/lib/server/provider/drive/index.js
@@ -24,7 +24,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)";
+  "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 = "*";
@@ -149,15 +149,29 @@ class Drive extends Provider {
       "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 === null || exportLinks === void 0 ? void 0 : 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 },

github-actions[bot] avatar May 03 '24 23:05 github-actions[bot]

thanks for your pr. Tests and linters are failing

mifi avatar May 08 '24 20:05 mifi

Done, all checks should be passing now.

milannakum avatar May 18 '24 12:05 milannakum

Thanks!

Murderlon avatar May 21 '24 14:05 Murderlon