diff --git a/desci-server/src/controllers/data/google/import.ts b/desci-server/src/controllers/data/google/import.ts index f77a7c6ca..376f87898 100644 --- a/desci-server/src/controllers/data/google/import.ts +++ b/desci-server/src/controllers/data/google/import.ts @@ -2,7 +2,11 @@ import { Request, Response } from 'express'; import { logger as parentLogger } from '../../../logger.js'; import { processS3DataToIpfs } from '../../../services/data/processing.js'; -import { GoogleApiService } from '../../../services/googleApiService.js'; +import { + GoogleApiService, + googleDocsExportMap, + googleDocsMimeExtensionConversionMap, +} from '../../../services/googleApiService.js'; import { ErrorResponse, UpdateResponse } from '../update.js'; interface GoogleImportReqBody { @@ -34,9 +38,20 @@ export const googleImport = async ( const googleService = new GoogleApiService(gAuthAccessToken); // googleService.exchangeCodeForToken(gAuthAccessToken); const fileMd = await googleService.getFileMetadata(googleFileId); - const fileStream = await googleService.getFileStream(googleFileId); + + const isGoogleDoc = googleDocsExportMap.hasOwnProperty(fileMd.mimeType); + let fileStream; + let fileName = fileMd.name; + + if (isGoogleDoc) { + const exportMimeType = googleDocsExportMap[fileMd.mimeType]; + fileStream = await googleService.exportFile(googleFileId, exportMimeType); + fileName = fileMd.name + '.' + googleDocsMimeExtensionConversionMap[fileMd.mimeType]; + } else { + fileStream = await googleService.getFileStream(googleFileId); + } // debugger; - const files = [{ originalname: '/' + fileMd.name, content: fileStream, size: fileMd.size }]; + const files = [{ originalname: '/' + fileName, content: fileStream, size: fileMd.size }]; const { ok, value } = await processS3DataToIpfs({ files, user: owner, diff --git a/desci-server/src/services/googleApiService.ts b/desci-server/src/services/googleApiService.ts index b160db809..7dd079ca4 100644 --- a/desci-server/src/services/googleApiService.ts +++ b/desci-server/src/services/googleApiService.ts @@ -5,6 +5,16 @@ import { google, drive_v3 } from 'googleapis'; import { logger as parentLogger } from '../logger.js'; +export const googleDocsExportMap = { + 'application/vnd.google-apps.document': 'application/pdf', + 'application/vnd.google-apps.spreadsheet': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', +}; + +export const googleDocsMimeExtensionConversionMap = { + 'application/vnd.google-apps.document': 'pdf', + 'application/vnd.google-apps.spreadsheet': 'xlsx', +}; + export class GoogleApiService { private oauth2Client; private driveClient: drive_v3.Drive; @@ -38,6 +48,26 @@ export class GoogleApiService { return response.data; } catch (error) { this.logger.error({ docId, error }, 'Failed to get file stream'); + + throw error; + } + } + + /** + * Files using googles proprietary document formats need to be exported, so far supports google word docs and sheets. + */ + async exportFile(docId: string, mimeType: string): Promise<Readable> { + try { + const response: GaxiosResponse<Readable> = await this.driveClient.files.export( + { + fileId: docId, + mimeType: mimeType, + }, + { responseType: 'stream' }, + ); + return response.data; + } catch (error) { + this.logger.error({ docId, mimeType, error }, 'Failed to export file'); throw error; } } @@ -58,7 +88,6 @@ export class GoogleApiService { async exchangeCodeForToken(code: string): Promise<void> { try { const { tokens } = await this.oauth2Client.getToken(code); - debugger; this.oauth2Client.setCredentials(tokens); this.logger.info('Successfully exchanged code for tokens'); } catch (error) {