5 google-apps-script google-drive-api
介绍
让我先介绍一下我尝试做的目标。
我之前有一个文件分成两部分
这两个文件的总大小可能超过 50 MB(作为长期目标)。由于UrlFetchApp.fetch()对请求的大小有限制,我想分别上传它们,其中每个文件将小于 50 MB,因此合并它们。现在(尝试 Drive API),我使用的是小文件。
第一个文件是(的倍数)。我意识到我之前犯了一个错误,即我使用文件的大小作为 256 的倍数,但它应该是 256 的倍数 640000 bytes256524288 bytes256*1024
第二个文件是.47626 bytes163339 bytes
我使用拆分文件curl并将它们上传到我的驱动器(正常的网络上传)。
我的目的是使用from将它们partial files一个一个地上Resumable Upload传到 Google Drive Google Drive API,Google Apps Script以便它们可以合并到一个文件中。
到目前为止我尝试过什么?
resumable upload使用Drive.Files.insert,用户指出无法使用Drive.Files.insert下面引用的内容。遗憾的是,现阶段无法使用Drive.Files.insert实现可续传。似乎这是谷歌方面的当前规范
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());
}
Run Code Online (Sandbox Code Playgroud)
我也尝试将方法更改为 patch
我Content-Length : 640000在里面添加headers,在这种情况下,我收到如下提供的错误。
Exception: Attribute provided with invalid value: Header:Content-Length
Drive.Files.insert(resource) using blank resource. Then I tried to update it using UrlFetchApp(patchUrl,options) while having the variable
var patchUrl = 'https://www.googleapis.com/upload/drive/v3/files/' + fileId + '?uploadType=resumable';Result
[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}
Question
What is the proper way of initiating a upload of a file in Drive to Drive using Drive API from Apps Script while keeping the upload type as resumable?
What should subsequent requests be like? So that files above 50 MB can be subsequently uploaded to the merged file?
Edit 1
Tried it again using corrected file chunks sizes. Same problem persists.
Edit 2
To understand the code in the answer, I used the code in // 2 of Tanaike's code alone to understand how Location is retrieved.
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);
}
Run Code Online (Sandbox Code Playgroud)
This creates a file understanding.pdf of size 0 bytes. However, Logger.log(location) logs null.
Why is it so?
The mistake was in the end point. Setting it to
https://www.googleapis.com/upload/drive/v3/files?uploadType=resumable works. It retrieves the location.
从你的问题和回复中,我可以理解你的情况和目标,如下所示。
为此,这个答案怎么样?
不幸的是,您的脚本不完整,无法实现可恢复上传。Google Drive API 的可恢复上传流程如下。参考
对于上面的流程,当准备好示例脚本时,它变成如下。
在这种情况下,使用 Drive API。因此,请在高级 Google 服务中启用 Drive API。这样,Drive API 会在 API 控制台自动启用。
示例脚本的流程如下。
请复制并粘贴以下脚本。并请设置文件 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.
}
Run Code Online (Sandbox Code Playgroud)
可续传上传完成后,在日志中可以看到如下结果。您可以在根文件夹中看到合并后的文件。
{
"kind": "drive#file",
"id": "###",
"name": "sample.pdf",
"mimeType": "application/pdf"
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
616 次 |
| 最近记录: |