gpt4 book ai didi

google-apps-script - 如何使用 Apps 脚本将 Drive 中的现有文件上传到 Drive

转载 作者:行者123 更新时间:2023-12-03 16:02:24 25 4
gpt4 key购买 nike

简介
让我先介绍一下我尝试做的目标。

  • 我之前有一个文件分成两部分
  • 这两个文件的总大小可能超过 50 MB(作为长期目标)。自 UrlFetchApp.fetch()对请求的大小有限制,我想单独上传它们,每个文件将小于 50 MB,因此合并它们。现在(尝试 Drive API),我使用的是小文件。
  • 第一个文件是 640000 bytes (256 的倍数)524288 bytes .我意识到我之前犯了一个错误,即我使用文件大小作为 256 的倍数,但它应该是 256*1024 的倍数
  • 第二个文件是 47626 bytes 163339 bytes .
  • 我使用 curl 拆分文件并将它们上传到我的驱动器(正常的网络上传)。
  • 我的意图是上传partial files一一使用Resumable Upload到 Google Drive 使用 Google Drive API来自 Google Apps Script以便它们可以合并到一个文件中。

  • 到目前为止我尝试过什么?
  • 昨天,我问了一个 question这里。我试图执行 resumable upload使用 Drive.Files.insert并且用户指出无法使用 Drive.Files.insert下面引用。

  • Unfortunately, in the current stage, the resumable upload cannot be achieved using Drive.Files.insert. It seems that this is the current specification at Google side


  • 我现在正在尝试使用 Google Drive API .下面附上代码。
  • function myFunction() {
    var token = ScriptApp.getOAuthToken();

    var f1_id = '1HkBDHV1oXXXXXXXXXXXXXXXXXXXXXXXX';
    var f2_id = '1twuaKTCFTXXXXXXXXXXXXXXXXXXXX';

    var putUrl = 'https://www.googleapis.com/drive/v3/files?uploadType=resumable';

    var fileData = {
    name : 'Merged-file-from-GAS',
    file : DriveApp.getFileById(f1_id).getBlob()
    }

    var options = {
    method : 'put',
    contentType:"application/json",
    headers : {
    Authorization: 'Bearer ' + token,
    'X-Upload-Content-Type' : 'application/octet-stream',
    'Content-Type' : 'application/json; charset=UTF-8'
    },
    muteHttpExceptions: true,
    payload : fileData
    };

    var response = UrlFetchApp.fetch(putUrl, options);
    Logger.log(response.getResponseCode());
    Logger.log(response.getAllHeaders());
    }

  • 我也尝试将方法更改为 patch
  • 我加了 Content-Length : 640000headers在这种情况下,我收到如下提供的错误。

  • Exception: Attribute provided with invalid value: Header:Content-Length


  • 我尝试使用 Drive.Files.insert(resource) 创建文件使用空白 resource .然后我尝试使用 UrlFetchApp(patchUrl,options) 更新它在拥有变量的同时var patchUrl = 'https://www.googleapis.com/upload/drive/v3/files/' + fileId + '?uploadType=resumable';

  • 结果
  • 它不会创建任何文件。
  • 下面提供了附加代码(初始代码)结果的记录器日志:

  • [20-05-12 21:05:37:726 IST] 404.0

    [20-05-12 21:05:37:736 IST] {X-Frame-Options=SAMEORIGIN, Content-Security-Policy=frame-ancestors 'self', Transfer-Encoding=chunked, alt-svc=h3-27=":443"; ma=2592000,h3-25=":443"; ma=2592000,h3-Q050=":443"; ma=2592000,h3-Q049=":443"; ma=2592000,h3-Q048=":443"; ma=2592000,h3-Q046=":443"; ma=2592000,h3-Q043=":443"; ma=2592000,quic=":443"; ma=2592000; v="46,43", X-Content-Type-Options=nosniff, Date=Tue, 12 May 2020 15:35:37 GMT, Expires=Mon, 01 Jan 1990 00:00:00 GMT, X-XSS-Protection=1; mode=block, Content-Encoding=gzip, Pragma=no-cache, Cache-Control=no-cache, no-store, max-age=0, must-revalidate, Vary=[Origin, X-Origin], Server=GSE, Content-Type=text/html; charset=UTF-8}


    问题
  • initiating a upload的正确方法是什么?使用 Apps Script 中的 Drive API 将 Drive to Drive 中的文件保存为 upload typeresumable ?
  • 后续请求应该是什么样的?以便随后可以将 50 MB 以上的文件上传到合并文件中?

  • 编辑 1
    使用更正的文件块大小再次尝试。同样的问题仍然存在。
    编辑 2
    为了理解答案中的代码,我使用了 // 2中的代码单凭田池的代码就明白了 Location被检索。
    function understanding() {
    var token = ScriptApp.getOAuthToken();
    const filename = 'understanding.pdf';
    const mimeType = MimeType.PDF;

    const url = 'https://www.googleapis.com/drive/v3/files?uploadType=resumable';

    const res1 = UrlFetchApp.fetch(url, {
    method: "post",
    contentType: "application/json",
    payload: JSON.stringify({name: filename, mimeType: mimeType}),
    headers: {authorization: "Bearer " + ScriptApp.getOAuthToken()
    }});
    const location = res1.getHeaders().Location;
    Logger.log(location);
    }
    这将创建一个文件 understanding.pdf尺寸 0 bytes .然而, Logger.log(location)日志 null .
    为什么会这样?
    错误在终点。将其设置为 https://www.googleapis.com/upload/drive/v3/files?uploadType=resumable作品。它检索位置。

    最佳答案

    从你的问题和回复中,我可以理解你的情况和目标,如下所示。

  • 在您的示例文件中,“文件 A”和“文件 B”分别为 524,288 字节和 163,339 字节。
  • 您测试的脚本是您的问题中显示的脚本。
  • 您想使用可恢复上传合并文件。
  • 合并文件的 mimeType 为 PDF。

  • 为此,这个答案怎么样?

    retrofit 要点:
  • 不幸的是,您的脚本不完整,无法实现可恢复上传。 Google Drive API 的可恢复上传流程如下。 Ref
  • 请求检索用作上传数据端点的位置。
  • 在您的情况下,将创建新文件。所以需要使用POST方法。
  • 通过包含数据来请求检索到的位置(在您的情况下,它是每个文件。)。
  • 在这种情况下,需要使用循环上传数据。并且使用了 PUT 方法。
  • 在这里,每个文件大小都是最重要的。如果除最后一个文件外的文件大小不是262,144字节的倍数,则无法运行可恢复上传,错误。请注意这一点。

  • 对于上面的流程,当准备好示例脚本时,它变成如下。

    用法:

    1. 启用驱动 API。

    在这种情况下,使用 Drive API。因此,请在高级 Google 服务中启用 Drive API。这样,Drive API 会在 API 控制台自动启用。

    示例脚本的流程如下。
  • 创建一个在可恢复上传时使用的对象。
  • 检索“位置”以开始可恢复上传。
  • 上传每个文件并合并它们。

  • 2. 示例脚本。

    请复制并粘贴以下脚本。并请设置文件 ID。在这种情况下,请设置它们以便合并。请注意这一点。
    function myFunction() {
    const fileIds = ["###", "###"]; // Please set the file IDs of the file "A" and "B" in order.
    const filename = "sample.pdf";
    const mimeType = MimeType.PDF;

    // 1. Create an object for using at the resumable upload.
    const unitSize = 262144;
    const fileObj = fileIds.reduce((o, id, i, a) => {
    const file = DriveApp.getFileById(id);
    const size = file.getSize();
    if (i != a.length - 1 && (size % unitSize != 0 || size > 52428800)) {
    throw new Error("Size of each file is required to be the multiples of 262,144 bytes and less than 52,428,800 bytes.");
    }
    o.files.push({data: file.getBlob().getBytes(), range: `bytes ${o.size}-${o.size + size - 1}\/`, size: size.toString()});
    o.size += size;
    return o;
    }, {size: 0, files: []});

    // 2. Retrieve "location" for starting the resumable upload.
    const url = "https://www.googleapis.com/upload/drive/v3/files?uploadType=resumable";
    const res1 = UrlFetchApp.fetch(url, {
    method: "post",
    contentType: "application/json",
    payload: JSON.stringify({name: filename, mimeType: mimeType}),
    headers: {authorization: "Bearer " + ScriptApp.getOAuthToken()
    }});
    const location = res1.getHeaders().Location;

    // 3. Upload each file and merge them.
    fileObj.files.forEach((e, i) => {
    const params = {
    method: "put",
    headers: {"Content-Range": e.range + fileObj.size},
    payload: e.data,
    muteHttpExceptions: true,
    };
    const res = UrlFetchApp.fetch(location, params);
    const status = res.getResponseCode();
    if (status != 308 && status != 200) {
    throw new Error(res.getContentText());
    }
    if (status == 200) {
    console.log(res.getContentText())
    }
    });

    // DriveApp.createFile() // This comment line is used for automatically detecting the scope of "https://www.googleapis.com/auth/drive" by the script editor. So please don't remove this line.
    }

    结果:

    可续传上传完成后,在日志中可以看到如下结果。您可以在根文件夹中看到合并后的文件。
    {
    "kind": "drive#file",
    "id": "###",
    "name": "sample.pdf",
    "mimeType": "application/pdf"
    }

    笔记:
  • 这是一个简单的示例脚本。所以请根据您的实际情况修改它。
  • 我针对您的示例情况测试了上述脚本,即“文件 A”和“文件 B”分别为 524,288 字节和 163,339 字节。因此,当使用此脚本合并大小约为 50 MB 的多个文件时,会发生错误。
  • 如果在使用大文件时出现内存错误,在现阶段,这似乎是谷歌方面的规范。所以请注意这一点。

  • 引用:
  • Perform a resumable upload
  • 关于google-apps-script - 如何使用 Apps 脚本将 Drive 中的现有文件上传到 Drive,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61756742/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com