how to find files not owned by me in Google apps script - 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:

Related

Check if google document is neither edited nor viewed

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.

apps script google drive auto remove editors

I am sharing the folder / file in my Google drive to 'A'.
But now I'm trying to stop sharing to 'A'.
I tried to stop sharing all folders / files using apps script, but apps script could not execute for more than 5 minutes.
apps script Is there a better solution?
Are you exceeding the 5 minutes because you are iterating over a lot of files?
By the way, probably it is better to use the advanced API to perform this operation quicker (this is what comes from my personal experience, it maybe not true, but avoiding FileIterators tends to speed things up). Also, if you are iterating using DriveApp.getFiles() instead by searching directly the right ones, you are iterating over all files that you have in your drive, and it takes quite a lot.
Using the advanced API you may only iterate over the files that user A can modify/read (and even if you reach the 5 minutes, if you run again the function, the files/folders that you have already modified will be not taken into account by the query).
The file list can be obtained via (hypothesis: user A has mail address a.mail#gmail.com):
var files = Drive.Files.list({
q: '"a.mail#gmail.com" in readers or "a.mail#gmail.com" in writers'
});
files.items.forEach(file => {
var file_app = DriveApp.getFileById(file.id);
// Do here what you need to stop sharing.
});
The listing gets both files and folders. You can check this by using the property file.mimeType (it is application/vnd.google-apps.folder for folders, tha actual mimetype for the files, like application/pdf for a PDF).
DISCLAIMER: you have to enable the advanced API in both AppScript and Google Console. It is easy, just read carefully the instructions.
Test: I tested this solution against the file shared with one of my colleague. We have in shared folders with more than 10000 files, and I succeed to iterate on all the files without reaching the limit. The DriveApp callback reached the limit. But again, this is personal tests, take it with cautions.

Using Google Apps Scripts to generate shareable links of new files

I recently discovered this Google Apps Scripts feature and am wondering if my issue can be addressed by using that.
Let's say I have a machine generating new files (screenshots or videos taken from a capture card) that are being saved in a folder that is sync'd to my Google Drive. What I would like to do is somehow automatically generate a shareable link for each NEW file that gets added and send it to an email address (may or may not be a Gmail address).
Is this something that I can use Google Apps Scripts for? I tried looking into batch files first but I can't generate the shareable link automatically (or couldn't figure out how).
I don't have any code yet, just looking at potential approaches.
Thanks in advance!
Yes almost everything is possible in GAS. However, you are likely to find better answers when you post some code that you have tried yourself before asking the answer here.
However, if the machine automatically saves the files in a folder in google drive you can scan that folder with a script and find the links. Attach a trigger to it with a, for example, 5 minute interval and write those links on a spreadsheet.
an example:
function links(){
var sheet = SpreadsheetApp.getActive.getActiveSpreadsheet();
var folder = DriveApp.getFolderById('put google folder id here');
var files = folder.getFiles();
while (files.hasNext()) {
var file = files.next();
var vals = file.getUrl();
sheet.getRange(your range you want to paste the link).setValues(vals);
}
}
This will find the links of all the files in the folder and paste that onto a google spreadsheet where the code is linked to.
Use that spreadsheet as a database and send an email by using that database.

can I iterate through files using google apps script using an iteration order other than latest modified time

I am iterating through text files using Google Apps Script and the pasting contents of text files to a google sheet
var allFiles = sourceFolder.getFiles()
var file = allFiles.next()
var fileContent = file.getAs('text/plain').getDataAsString()
sheet = ss.getSheetByName("Data")
var pasteRange = sheet.getRange(rowId,205)
pasteRange.setValues(fileContent)
All is fine. The variable RowId is taken from the filename of the text file. The problem is that a user may create a text file for RowId 230 then 1 minute later another user may also create row 230. I need the latter user to take priority. But Google iterates through the files using most recent first leaving me with the oldest update to row 230 in the google sheet.
Is there any way of sorting the files in the file iterator to determine the iteration order. I can manipulate the filename if that helps.
thanks
If you're using GSuite API Services (DriveApp), its not possible. However there is an advanced set of services referenced here. These are wrappers for the respective REST APIS for Drive, Sheets and other Google REST-based services.To use them you'll need to enable the service as described here.
Once you have the Drive service enabled, you'll have to navigate the REST API documentation for Drive V2 to figure out the methods you need to use (though Apps Script has an auto-complete feature that will aid you). For example, to list files, you can reference the Advanced Service from the Drive (NOT DriveApp)module as follows:
Drive.Files.list(options);
options is an object with parameters listed here. The orderBy option should have what you need to sort the files.

Get JSON of container-bound Google Apps-Script through Apps-Script or download

If you create a non-container bound g-apps script (i.e. not as part of a gDoc or a gSheet), you can download it (however not view as a .json directly in the browser from the link) from gDrive as a .json. If you download a gDoc or gSheet, it converts to xlsx or docx and opening these with a zip viewer shows a number of files (many of type xml) however none contain the Google version's attached scripts.
Is there a way to read script files as a .json from within another Google Apps
Script? perhaps using the Drive-API or with g-a-s. DriveApp class?
Is there a way to download or read through DriveApp, the .jsons of
container bound scripts (which are usually invisible from all but within the original gFile)?
Update
Based on Kriggs, added a Logger.log(link) and this works great for stand-alone scripts.
How about for container-bound?
for stand alone script files:
exportLinks={
application/vnd.google-apps.script+json=
script.google.com/feeds/download/export?id=[scriptId]&format=json
}
for container-bound script files, there are links to csv, sheet and pdf, but no script json.
exportLinks= {
text/csv=docs.google.com/spreadsheets/export?id=[sheetId]&exportFormat=csv,
application/vnd.openxmlformats-officedocument.spreadsheetml.sheet=
docs.google.com/spreadsheets/export?id=[sheetId]exportFormat=xlsx,
application/pdf=
docs.google.com/spreadsheets/export?id=[sheetId]&exportFormat=pdf
}
Update
In Google sheet, go to Tools->script Editor->
URL in address bar looks like:
https://script.google.com/macros/d/
[ProjectKey]/edit?uiv=2&mid=[aVeryLongAlphaNum]
this is the download json:
https://script.google.com/feeds/download/export?id=[ProjectKey]
Question is, can we use the Drive API to find [ProjectKey]
Have there been any feature requests for DriveApp/Drive-API methods to seek Project Keys in your account?
Would there be a way to test if a file has a container bound script? Then the question is, is the script included in the file size (this can be easily tested, however it is unknown to the asker at this point).
Something like this may work although it looks computationally costly:
var SizeOfFile = yourFile.getSize();//
var charsInFile = yourFile.getAsString();
var unicodeSizeReference = [];//get bytes per character array
charsInFile.sort()
//find frequency of characters then multiply from unicoseSizeReference.
//there could be other gotchas as well, however this is just testing for feasibility
var SizeOfTextInFile = [/*#of chars in file name and sheetname*/]+[/*#of chars in all sheets*/];
SizeOfTextInFile *= unicodeBytesPerCharacter;//ranges from 1 to 4
var someThreshold = 10;//bytes
var hasScript=0;
if ([SizeOfFile - SizeOfTextInFile] > someThreshold) hasScript=1
Yes you have to get it trough the Drive API with OAuth2, I used the DriveApp to get the fileId, but you can modify to use Drive api aswell. To enable the Drive API go to Resources -> Advanced Google Services, find the Drive API and turn on.
When you send a get with Drive you get back an object of the file which contains the property exportLinks, using it you fetch the URL with OAuth2 authentication (the ScriptApp.getOAuthToken()), the fetched string will be a JSON, which has the Array fileswith the colection of scripts.
function getAppsScriptAsJson( fileName ) {
var fileDrive = Drive.Files.get( DriveApp.getFilesByName( fileName ).next().getId() );
var link = JSON.parse(fileDrive)[ 'exportLinks' ][ 'application/vnd.google-apps.script+json' ];
var fetched = UrlFetchApp.fetch(link, {headers:{'Accept':'application/vnd.google-apps.script+json', "Authorization":'Bearer '+ScriptApp.getOAuthToken()}, method:'get'});
return JSON.parse(fetched.getContentText());
}
As for container bound:
DriveApp can't get it by name
It doesn't display an ID anywhere, just the project key
Drive API can't lookup by the project id, nor DriveApp
Drive API can't find by the name
There's no reference of the script from the returned object from Drive API nor the DriveApp
I guess it is pretty much incognito, doubt there's any way ATM.
You can always make a Standalone app and set it as a library for the Spreadsheet...