Introduction
Let me first introduce the goal of what I am trying to do.
I had a file split into two parts earlier
Size of both of these files together may exceed 50 MB (as a long term goal). Since
UrlFetchApp.fetch()has restriction regarding the size of the request, I want to upload them separately, where each file will be less than 50 MB and consequently merge them. For now (to try the Drive API), I am using small files.First file is of
640000 bytes(a multiple of256)524288 bytes. I realise I did a mistake earlier i.e I was using the size of the file as a multiple of 256 but it should be a multiple of256*1024Second file is of
47626 bytes163339 bytes.I had split the files using
curland uploaded them to my drive (normal web upload).My intention is to upload the
partial filesone by one usingResumable Uploadto Google Drive using theGoogle Drive APIfromGoogle Apps Scriptso that they maybe merged into one file.
What I have tried so far?
- Yesterday, I had asked a question here. I was trying to perform a
resumable uploadusingDrive.Files.insertand a user pointed out it is not possible usingDrive.Files.insertwhich is quoted below.
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
- What I am trying now is using
Google Drive API. Enclosed below is the code.
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());
}
I also tried changing the method to
patchI added
Content-Length : 640000insideheadersand in that case I receive an error as provide below.
Exception: Attribute provided with invalid value: Header:Content-Length
- I tried to create a file using
Drive.Files.insert(resource)using blankresource. Then I tried to update it usingUrlFetchApp(patchUrl,options)while having the variablevar patchUrl = 'https://www.googleapis.com/upload/drive/v3/files/' + fileId + '?uploadType=resumable';
Result
- It does not create any file.
- Logger logs for the result of the attached code (initial code) are provided below:
[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 uploadof a file in Drive to Drive using Drive API from Apps Script while keeping theupload typeasresumable?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);
}
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.
First file is of 640000 bytes (a multiple of 256)., in this case, the file cannot be directly used for the resumable upload. Because at the resumable upload, each chunk is required to be the multiples of 256 KB (256 x 1024 bytes). How about this? Ref If each file size (except for the last file) is the multiples of 262,144 bytes and less than 52,428,800 bytes for all files, the script for resumable upload can be simpler.256x1024x2 = 524288 bytes. It still didn't upload. Question Edited with new file size524,288 bytesand163,339 bytes, respectively. 2. Your tested script is the script showing in your question. 3. You want to merge the files using the resumable upload. Is my understanding correct? By the way, what is the mimeType of the merged file?By the way, what is the mimeType of the merged file?PDF