【问题标题】:Download file from Google Drive and upload to S3 using NodeJS从 Google Drive 下载文件并使用 NodeJS 上传到 S3
【发布时间】:2022-08-18 19:36:56
【问题描述】:

我根据documentation从谷歌驱动器下载我的PDF文件:

const file = await this.driveClient.files.get(
  {
    fileId: id,
    alt: \'media\',
  },
  {
    responseType: \'stream\'
  },
);

然后我构造一个表单数据:

const formData = new FormData();
formData.append(\'file\', file.data, \'file.pdf\');

并通过presigned upload url 将其发送到 S3:

const uploadedDocument = await axios({
  method: \'put\',
  url: presignedS3Url,
  data: formData,
  headers: formData.getHeaders(),
});

该流程有效,但上传到 s3 的文件显示已损坏:

我还尝试了来自 Google API 的不同响应类型,例如 blob。知道我缺少什么吗?提前致谢!

    标签: javascript node.js amazon-s3 google-drive-api


    【解决方案1】:

    您需要从谷歌驱动器将文件导出为 PDF,使用以下函数,传递 id:

    /**
     * Download a Document file in PDF format
     * @param{string} fileId file ID
     * @return{obj} file status
     * */
    async function exportPdf(fileId) {
      const {GoogleAuth} = require('google-auth-library');
      const {google} = require('googleapis');
    
      // Get credentials and build service
      // TODO (developer) - Use appropriate auth mechanism for your app
      const auth = new GoogleAuth({scopes: 'https://www.googleapis.com/auth/drive'});
      const service = google.drive({version: 'v3', auth});
    
      try {
        const result = await service.files.export({
          fileId: fileId,
          mimeType: 'application/pdf',
        });
        console.log(result.status);
        return result;
      } catch (err) {
        console.log(err)
        throw err;
      }
    }
    

    【讨论】:

    • Export 方法抛出Export only supports Docs Editors files. 错误,所以我必须使用get 方法
    【解决方案2】:

    我设法通过将流转换为缓冲区并在不使用Formdata 的情况下调用预签名的 S3 URL 来解决该问题:

    streamToBuffer(stream) {
      return new Promise((resolve, reject) => {
        const chunks = [];
        stream
          .on('data', (chunk) => {
            chunks.push(chunk);
          })
          .on('end', () => {
            resolve(Buffer.concat(chunks));
          })
          .on('error', reject);
      });
    }
    
    async uploadFileToS3(fileStream, signedUrl, contentType) {
      const data = await this.streamToBuffer(fileStream);
    
      const response = await axios.put(signedUrl, data, {
        headers: {
          'Content-Type': contentType,
        },
      });
    
      return response;
    }
    
    const file = await this.driveClient.files.get(
      {
        fileId: id,
        alt: 'media',
      },
      {
        responseType: 'stream'
      },
    );
    
    const uploadedDocument = await this.uploadFileToS3(
      file.data,
      s3Url,
      file.mimeType
    );
    
    

    【讨论】:

      猜你喜欢
      • 2021-10-24
      • 1970-01-01
      • 1970-01-01
      • 2023-03-23
      • 2013-09-04
      • 2018-10-14
      • 1970-01-01
      • 1970-01-01
      • 2021-10-05
      相关资源
      最近更新 更多