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*1024
Second file is of
47626 bytes
163339 bytes
.I had split the files using
curl
and uploaded them to my drive (normal web upload).My intention is to upload the
partial files
one by one usingResumable Upload
to Google Drive using theGoogle Drive API
fromGoogle Apps Script
so 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 upload
usingDrive.Files.insert
and a user pointed out it is not possible usingDrive.Files.insert
which 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
patch
I added
Content-Length : 640000
insideheaders
and 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 upload
of a file in Drive to Drive using Drive API from Apps Script while keeping theupload type
asresumable
?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. - Tanaike256x1024x2 = 524288 bytes
. It still didn't upload. Question Edited with new file size - user13355752524,288 bytes
and163,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? - TanaikeBy the way, what is the mimeType of the merged file?
PDF - user13355752