Check if google document is neither edited nor viewed - google-apps-script

Does google app script offers a class with a method allowing to check if a document with a given id is edited or viewed.
I'm build an application that allows user to delete google document from the google disk but before moving file to trash I would like to check if the file is neither edited nor viewed.
The similiar question has been posted here, but no solution provided.
Getting a list of active file viewers with apps script
Please note the the lock service is not a solution to this problem.

The Google Drive API must be used to get revisions to a file. The built-in DriveApp service, which is different than the Advanced Drive service, has no capability to get file revisions information, except for getLastUpdated() method, which gets the date when the file was last updated. The Drive API can be used within Apps Script by using the Advanced Drive service.
Advanced Services within Apps Script must be enabled. Click the "Resources" menu, and then choose the Advanced Google services menu item.
After you have enabled the Advanced Drive Service, the "Drive" class will show up in the context menu. Use Ctrl + Space Bar to have a list of available classes displayed in the code editor.
To get revisions to a specific file, use the Revisions class of the Advanced Drive service.
Drive.Revisions.list(fileId)
Check for no revisions:
function trash_If_No_Changes_(fileID) {
var revs;
revs = Drive.Revisions.list(fileID);
if (revs.items && revs.items.length === 0) {
trashFile_(fileID);
}
}
The Advanced Drive Service can also delete a file without sending it to the trash first.
function trashFile_(fileID) {
var i;
/*
This deletes a file without sending it to the trash
*/
for (i=1;i<4;i++) {
try{
Drive.Files.remove(fileID);//deletes a file without sending it to the trash
return;//return here instead of break because if this is successful the task is completed
} catch(e) {
if (i!==3) {Utilities.sleep(i*1500);}
if (i>=3) {
errHndl_(e,'trashFile','Can not delete the file by ID');
return false;
}
};
}
}
If you want to avoid the need to ask the user for broad access to their Drive, then you may want to try setting the scope:
https://www.googleapis.com/auth/drive.file
In the appsscript.json manifest file.

Related

Share the Drive file with extra permissions

I have a drive file where I need to restrict the users from these (I mean ticks for both needs to be removed and shared using apps script/drive api)
I need to accomplish using Google Apps Script Advanced Drive service or regular apps script. I am unsure what is the exact method. I have tried with
function shareit() {
DriveApp.getFileById(id).setSharing(DriveApp.Access.ANYONE_WITH_LINK, DriveApp.Permission.EDIT);
}
Drive Sharing Permissions with App Script
I manage to make both changes by using Advance Services from App Script. I was able to use part of your code to first remove the "Editors can change permissions and share" by using the:
setShareableByEditors(false)
Code Sample:
function shareit() {
DriveApp.getFileById(id).setSharing(DriveApp.Access.ANYONE_WITH_LINK, DriveApp.Permission.EDIT).setShareableByEditors(false);
// Add advance service to be able to run a files patch and update the permissions of the ID to require writters permisions to copy, print and download.
Drive.Files.patch({copyRequiresWriterPermission:true}, id);
}
As presented in the comments you would need run a patch update to the File ID to change the permissions.
References:
https://developers.google.com/apps-script/advanced/drive
https://developers.google.com/drive/api/v2/reference/files/patch
https://developers.google.com/apps-script/reference/drive/file#setShareableByEditors(Boolean)

Can a Google Apps Script running as an editor add-on use the https://www.googleapis.com/auth/drive.file scope?

I'm creating a Google Docs add-on in Google Apps Script, and some of the functionality requires that I use the Google Drive advanced service as described in https://developers.google.com/apps-script/guides/services/advanced. After enabling the advanced service, my script is now requesting the https://www.googleapis.com/auth/drive scope, which is way overbroad for what I'm trying to do - I only want to touch the files that the user is actually using this add-on with, not their whole drive! I'd much rather be using https://www.googleapis.com/auth/drive.file, which is restricted to files the user is actively using with the script.
I've tried setting the #OnlyCurrentDoc JSDoc tag as mentioned in https://developers.google.com/gsuite/add-ons/concepts/scopes#editor_add-on_scopes, but that only changes the broad https://www.googleapis.com/auth/documents scope to https://www.googleapis.com/auth/documents.currentonly - it doesn't change the Drive API scope.
Also, I've verified that the script does actually need the auth/drive scope, because when I went into the project manifest and explicitly requested auth/drive.file, I got a 404 response with API call to drive.revisions.list failed with error: File not found: 1Sj_oq93ny5q9348ncyo8934nyc at getAuthors(Code:54) at showSidebar(Code:20). That's exactly what I'd expect for a file that hasn't been "tagged" for use with this script.
Here's a very minimal gdocs addon that shows the issue:
function onOpen(e) {
var menu = DocumentApp.getUi().createAddonMenu();
menu.addItem("Get revisions", "getRevisions");
menu.addToUi();
}
function getRevisions() {
var docId = DocumentApp.getActiveDocument().getId();
Logger.log("Document id: "+docId);
var revs = Drive.Revisions.list(docId);
Logger.log("Found revisions: "+revs.items.length);
}
Again, this works just fine with the default auth/drive scope, but not with auth/drive.file.
The documentation for https://www.googleapis.com/auth/drive.file specifies that it grants "Per-file access to files created or opened by the app. File authorization is granted on a per-user basis and is revoked when the user deauthorizes the app." according to the docs at https://developers.google.com/drive/api/v2/about-auth#OAuth2Authorizing. What isn't clear is: how does Google determine what files have been "created or opened by the app", especially when it comes to editor addons? I would think that any document that has had the add-on enabled would count as "opened by the app", but I guess not. Is there any way to make this scope work?

Deleting files from Google Drive with Google Apps Script [duplicate]

This question already has an answer here:
Permanently delete file from google drive
(1 answer)
Closed 4 years ago.
I have seen many topics talking about this problem, and I have been struggling with it for a week now: is there a real way to delete/remove/put to trash files from Google Drive using a script?
I have to upload CSV files on Drive to copy some of their rows into a Spreadsheet, and I would like to have these files deleted after use. I used DriveApp.remove(file.id), Drive.Files.remove(file.id) and, even though they did nothing on my documents, I did not get any error message...
I can use a method taking filenames, fileIDs in argument, whatever is needed to perform this deletion.
Per Apps Script documentation, the .removeFile(fileId) method does not delete the file, nor does it trash the file. This method simply removes the file from the current folder.
To delete a file from Google Drive via Apps Script will require using the Drive REST API possibly as an advanced service. This will skip the "Trash" - it is unrecoverable.
function deleteIt(fileId) {
var file = Drive.Files.get(fileId);
if(file.mimeType === MimeType.FOLDER) {
// possibly ask for confirmation before deleting this folder
}
Drive.Files.remove(file.id); // "remove" in Apps Script client library, "delete" elsewhere
}
"Trash"ing a file/folder can be done from Google Apps Script without needing to set up and configure the advanced service:
function trashIt(fileId) {
var file;
try {
file = DriveApp.getFileById(fileId);
}
catch (fileE) {
try {
file = DriveApp.getFolderById(fileId);
}
catch (folderE) {
throw folderE;
}
}
file.setTrashed(true);
}
(Trashing can also be done with the Advanced Service if you need to work with Team Drive items.)
See related questions:
Permanently delete file from google drive
Delete or Trash specific file in Drive
Google apps script : How to Delete a File in Google Drive?

About Google Drive's "state parameter"?

My App for Google Drive is by Google Script.
When I select files in Drive and then call my App, an official "state parameter" will be sent into my App for further digestion. However, the official document is not clear enough for its setting. I need to collect its info from different area like Google I/O video and examples. Is there a good site to introduce it?
Official Site: https://developers.google.com/drive/web/integrate-open
Especially, for the process, User select files in a Active folder => Run App => App save back files to Active Folder ... but this is the problem. How can I know which is the active folder through the state parameter? Any suitable command?
N.B. It is meaningless to use MyFile.getFolders() command, since one file can belong to several folders, and I cannot distinguish which one is "Active" folder.
The documentation shows some code that gets the id after the file is picked from a Google Drive:
// A simple callback implementation.
function pickerCallback(data) {
if (data.action == google.picker.Action.PICKED) {
var fileId = data.docs[0].id;
alert('The user selected: ' + fileId);
}
}

how to find files not owned by me in Google apps script

In Google Drive one can search files 'Not owned by me'.
I need access to this from Google Apps Script.
I already tried DocsList.find("Not 'me' in owner"); which appears to be the way to do it in the drive API, but without success (in fact that gets me files with me as owner.) I also replaced me with my email address, with and without quotes, but again without success.
Does anyone know if this is possible (other than by iterating all files and checking getOwner().getEmail() manually, which would take far too long given the enormous amount of files owned by this specific user.)
I think the updated answer as of now is to use DriveApp.searchFiles(params) (https://developers.google.com/apps-script/reference/drive/drive-app#searchFiles(String) ).
Code is something like:
// Log the name of every file in the user's Drive that shared with me
var files = DriveApp.searchFiles('sharedWithMe');
while (files.hasNext()) {
var file = files.next();
Logger.log(file.getName());
}
This function will return an array of all files shared with you. It uses the Advanced Drive Service, which must be enabled before use.
/**
* Get array of files on user's Google Drive that have been shared with them.
* From https://stackoverflow.com/a/15947340/1677912
*
* #returns {Array} Array of file resources
* (see https://developers.google.com/drive/v2/reference/files#resource)
*/
function getSharedWithMe() {
var optionalArgs = {q:"sharedWithMe=true"};
var sharedFiles = Drive.Files.list(optionalArgs);
debugger; // pause in debugger
return sharedFiles.items;
}
You can do the same thing without code, by using the Google Drive SDK "Explorer".
See this previous answer that used this technique to get a list of trashed files.
You'll find the Files List API Explorer at the bottom of the Google Drive SDK documentation page for Files:list. For information about search terms, see Search for files. For our purposes, we'll just use sharedWithMe.
If you leave "fields" blank, you'll get everything that's known about the shared files. You can expand and collapse the results using hard-to-see minus sign tags. But it's helpful to limit the output. I used items(id,selfLink,owners/displayName). Here's how that looks: