Failing to get a file in Google Apps Script using the Drive API - google-apps-script

I have a google apps script (that I use in one of my spreadsheets). I'm used to calling the DriveApp service to handle files (list, create, move, etc), but I wanted to get the user that last modified a file. Looking it up in several places, I understood that the only way to achieve that is to import the Drive API SDK (the Advanced Drive Service) into the Google Apps script. I added it using the official documentation. So, here is where I'm stuck. To simplify, look at the code below:
console.log(DriveApp.getFileById('1eMIUTEmpvzN5a3kK6PWbK4W8RCkbNOSxxxxxxxxxxx').getName())
console.log(Drive.Files.get('1eMIUTEmpvzN5a3kK6PWbK4W8RCkbNOSxxxxxxxxxxx').title)
The first one shows my file name just fine.
The second one fails with:
GoogleJsonResponseException: API call to drive.files.get failed with
error: File not found: 1eMIUTEmpvzN5a3kK6PWbK4W8RCkbNOSxxxxxxxxxxx
(anonyme) # List Files.gs:2
Any ideas why it wouldn't work?

From your script and your error of File not found, I thought that in your situation, the file might be put in the shared Drive. If my understanding is correct, such error occurs. On the other hand, when DriveApp.getFileById is used, the file in the shared Drive can be retrieved. So in your situation, how about the following modification?
From:
console.log(Drive.Files.get('1eMIUTEmpvzN5a3kK6PWbK4W8RCkbNOSxxxxxxxxxxx').title)
To:
console.log(Drive.Files.get('1eMIUTEmpvzN5a3kK6PWbK4W8RCkbNOSxxxxxxxxxxx', {supportsAllDrives: true}).title)
Reference:
Files: get

Related

Automatic Syncing between two Google Drive Shared Drives

Question:
I have two Google Shared Drives (Team Drives), let's say Movies and MoviesBackup. I need to backup whatever I upload to Movies into MoviesBackup. For this, I need an unidirectional sync from Movies to MoviesBackup, once daily.
What I have tried:
I know of of Rclone, and have used its Command Line Interface to sync between two Shared Drives. Maybe if Rclone can be used from Google AppScript, I would set a daily trigger. But I seem to find no way to do so.
Any other solutions that work will be appreciated.
Although I'm not sure whether this is the direct solution of your issue, in your situation, how about the following sample script? This sample scripts uses a Google Apps Script library. Ref
When this library is used, a source folder can be copied to the specific destination folder. And, when the files in the source folder are updated, the updated files are copied to the destination folder as the overwrite.
Usage:
1. Install library.
Please install the library to your Google Apps Script project. The method of installing it can be seen at here.
2. Sample script.
Please copy and paste the following script to the script editor of your Google Apps Script project. And save it. And, in this library, Drive API is used. So please enable Drive API at Advanced Google services.
And, please set the source and destination folder IDs to the following object.
function myFunction() {
const object = {
sourceFolderId: "###", // Please set the source folder ID.
destinationFolderId: "###", // Please set the destination folder ID.
overwrite: true,
};
const res = CopyFolder.copyAllFilesFolders(object);
console.log(res);
}
Note:
When this script is run for the 1st time, all files are copied. And, after the script is run as 2 times, only the updated files are copied.
Reference:
CopyFolder of Google Apps Script library

Deploying Script as Webapp directly from Sheets

Is it, at all, possible to deploy a Google Scripts as web app directly from Google Sheets?
I am trying to add a custom menu to Google Sheets where the user can programmatically deploy the file's script as a web app. And it looks like it is possible to do so by following instructions from this GitHub repo.
But for obvious reasons, I need to set projectId to equal ScriptApp.getScriptId(), so that when the Spreadsheet file is copied, this variable is dynamically set to equal to that script's unique id. However, when executing saveAndDeployNewVersion() from the custom menu I've set up (and even from inside the script itself) I always get deploymentId returned as undefined, before getting a 403 error from the final function in the chain (makeRequest_).
Is there any other approach, OR, can you point out what I'm doing wrong when implementing this script into my own project?
Request failed for https://script.googleapis.com returned code 403. Truncated server response: { "error": { "code": 403, "message": "Apps Script API has not been used in project 575477635395 before or it is disabled. Enable it by vi... (use muteHttpExceptions option to examine full response) (line 211, file "Code")
You need to
Switch to standard GCP.
Enable the apps script api for that GCP
Also see Related answer.

How do I list a specific user's permissions on a teamdrive using Google Apps Script?

Per the Google API reference it looks like a Drive.Permissions.List call would work on a Teamdrive, however I am getting a 404 error when using the following:
Drive.Permissions.list(TEAMDRIVEID);
Is there an alternative way to get a specific user's permissions to a specific drive?

How do I download previous saved revisions of a Google Apps Script?

I am still attempting to recover from somehow 'loosing' a Google Apps Script when I created a copy of the script to fork the code to another project... My thought was to attempt to download older revisions of the Google Apps Script via the drive API, but this page indicates that perhaps it is not possible.
Actions such as versioning, publishing or executing the script are not available through the API.
So I attempted it anyway and alas this error occurs...
<HttpError 400 when requesting
https://www.googleapis.com/drive/v2/files/..snipped../revisions?alt=json
returned "File does not support revisions">
So is there no mechanism to download previous versions or "Revisions" of Google Apps Script? What I would love is to get access to 'Revision 1' shown here within the script.google.com interface:
This is a bit manual but:
Create another script project
Include your original script as a library in your new script and select v1
In the new script add some code that uses your "library"
Use the script editor debugger to step into the library and you should see the code from the correct version
For example if your library is called something like "MyOldCode", include some code like this in your new script:
function getOldCode() {
var a = MyOldCode.anExampleFunction()
}
Put a breakpoint below the "var a" line, run getOldCode() with the debugger and then step into anExampleFunction(). This will open up one file of your old code allowing you to copy and paste it elsewhere.
You can then piece together v1.
Edit 2019-04-11: There is also Romain's function for accessing old versions.
Edit 2022-05-05: With V8 and the new editor I can no longer find a way to step into a library. Rhino gives a server error, and V8 ignores the "step in".
FYI, the Apps Script API can get project files from a previous version number:
https://developers.google.com/apps-script/api/reference/rest/v1/projects/getContent
If you'd like to see this in the Apps Script CLI, clasp, like clasp pull 3, I'm sure I could add this feature.
https://github.com/google/clasp/
Just file a new issue.
Grant is the right answer. Clasp is the way. I just wanted to update the command for the current state of clasp which is
clasp pull --versionNumber 12

Google drive api: copy error with scopes "drive.file" and "drive.readonly"

My question is if it is not possible to copy a file from one folder in drive to another folder in drive with the google drive api if you only have the scopes "drive.file" and "drive.readonly"?
Tested using the API explorer: https://developers.google.com/drive/v2/reference/files/copy
The error is: "The authenticated user has not granted the app X write access to the file Y".
Creating a file (using the same scopes) and copying it is possible however.
Figured I ask and put the answer up since it's hard to find info about the google drive api.
It is possible but you also need the "drive.metadata" scope for it to work. You can ofc use the "drive" scope but that provides more access than needed.