I was looking for a solution so that people with access to a spreadsheet could upload files through it, researching I found some solutions, but as I will need these people to upload videos through the spreadsheet, some solutions that used Blob ended up being discarded.
Searching, I found this script made by Tanaike, apparently it solves practically all problems, I thought of pulling it into the spreadsheet using an html alert, thus allowing people to upload files with sizes greater than 50mb.
The script can be found here: Resumable Upload For WebApps
The issue is that I'm having some problems getting it to work, basically I'm getting this error when trying to upload a file:
Error: <HTML> <HEAD> <TITLE>Not Implemented</TITLE> </HEAD> <BODY BGCOLOR="#FFFFFF" TEXT="#000000"> <H1>Not Implemented</H1> <H2>Error 501</H2> </BODY> </HTML>
Other than that, I have a few questions I'd like to clear up:
1- I'm not sure if with this script people with other accounts would be able to upload the files to my Google Drive, is it possible?
2- Is it possible implement it in a button on a spreadsheet and request that the file be uploaded in the same folder as that spreadsheet?
Sorry for the amount of questions, javascript and GAS are things that are not very present in my daily life, so I have a little difficulty.
CodePudding user response:
Checking the developer console, the error returned from the server is accessNotConfigured
. This happens when the GCP Project doesn't have the necessary APIs enabled. To fix this you need to create a new Cloud Project:
In the Google Cloud console, go to Menu > IAM & Admin > Create a Project.
In the Project Name field, enter a descriptive name for your project.
In the Location field, click Browse to display potential locations for your project. Then, click Select.
Click Create. The console navigates to the Dashboard page and your project is created within a few minutes.
After that you need to enable the Drive API:
- In the Google Cloud console, go to Menu > More products > Google Workspace > Product Library.
- Click the API that you want to turn on.
- Click Enable.
Finally you need to attach the GCP project to your Apps Script Project:
- Determine the Project number of your Cloud project.
- Open the script whose Cloud project you want to replace.
- At the left, click Project Settings.
- Under Google Cloud Platform (GCP) Project, click Change project.
- Enter the new project number and click Set project.
After attaching the standard project the error stopped showing up for me. The reason for this is that Google changed the way Apps Script creates GCP projects so now scripts may have Default or Standard projects. Default projects are essentially more restricted so you may have to create a Standard Project in certain scenarios. One these scenarios in the documentation is "To create a file-open dialog". Tanaike's code uses the same technique as the file-open dialogs to retrieve the access token from the server, which I believe is the cause of the error.
As for your other questions:
- I'm not sure if with this script people with other accounts would be able to upload the files to my Google Drive, is it possible?
- Only if you deploy it as a Web App, setting it to execute with your account and available to "Anyone with a Google account". This uses your account's access token to authorize so other users will upload to your account.
- Is it possible implement it in a button on a spreadsheet and request that the file be uploaded in the same folder as that spreadsheet?
- As I mentioned under 1., doing it within the spreadsheet probably won't work, but you can add the
parents
property to the request body on the HTML side to specify the folder. You can also retrieve it dynamically by callinggoogle.script.run
. Here's a sample I modified to do this:
google.script.run.withSuccessHandler(function(at) {
var xhr = new XMLHttpRequest();
xhr.open("POST", "https://www.googleapis.com/upload/drive/v3/files?uploadType=resumable");
xhr.setRequestHeader('Authorization', "Bearer " at.token);
xhr.setRequestHeader('Content-Type', "application/json");
xhr.send(JSON.stringify({
mimeType: fileType,
name: fileName,
parents: at.parent
}));
xhr.onload = function() {
doUpload({
location: xhr.getResponseHeader("location"),
chunks: chunks,
});
};
xhr.onerror = function() {
console.log(xhr.response);
};
}).getAt();
That's a part of the init()
function in the index.html
file. The at
variable originally only received the access token retrieved from the server. I just modified it so it receives an object with both the access token and the folder ID, and I included the parent folder ID in the API call. You also need to modify the getAt()
function in Code.gs to actually return the folder ID:
function getAt() {
var id = SpreadsheetApp.getActiveSpreadsheet().getId()
var folder = DriveApp.getFileById(id).getParents().next().getId()
return { token: ScriptApp.getOAuthToken(), parent: [folder] }
}
There's a lot to unpack here so I advise you to check the documentation. I think you'll have to go through the Web App route if you want other users to upload the files to your Drive.