Google Apps Script Multiple Search with Drive App - google-apps-script

I hope I have searched good enough in order to ask this questions.
I have this code to clean up some default files in our team drive, if somebody got them in sync by accident...
In this case desktop.ini
function cleanup(){
var folderID = 'FOLDERID';
var search = 'title Contains "desktop.ini"';
var fileIDs = [];
var files = DriveApp.searchFiles(search);
while (files.hasNext()){
files.next().setTrashed(true);
}
Logger.log('fileIDs.length + ' files have been moved to trash');
}
Is there a way to add multiple hits in one search?
What if I would want to add other files like "thumbs.db" or from the mac guys ".DS_Store". Do I need to search for everything individually or is there a .gitignore way to solve it?

How about this? When you want to retrieve the files with the filenames which contained "desktop.ini", "thumbs.db" and ".DS_Store" in one search using DriveApp.searchFiles(), you can achieve it using or operator as follows.
var search = 'title contains "desktop.ini" or title contains "thumbs.db" or title contains ".DS_Store"';
Reference :
https://developers.google.com/drive/v3/web/search-parameters

Related

Return Collection of Google Drive Files Shared With Specific User

I'm trying to get a collection of files where user (let's use billyTheUser#gmail.com) is an editor.
I know this can be accomplished almost instantly on the front-end of google drive by doing a search for to:billyTheUser#gmail.com in the drive search bar.
I presume this is something that can be done in Google App Scripts, but maybe I'm wrong. I figured DriveApp.searchFiles would work, but I'm having trouble structuring the proper string syntax. I've looked at the Google SDK Documentation and am guessing I am doing something wrong with the usage of the in matched to the user string search? Below is the approaches I've taken, however if there's a different method to accomplishing the collection of files by user, I'd be happy to change my approach.
var files = DriveApp.searchFiles(
//I would expect this to work, but this doesn't return values
'writers in "billyTheUser#gmail.com"');
//Tried these just experimenting. None return values
'writers in "to:billyTheUser#gmail.com"');
'writers in "to:billyTheUser#gmail.com"');
'to:billyTheUser#gmail.com');
// this is just a test to confirm that some string searches successfully work
'modifiedDate > "2013-02-28" and title contains "untitled"');
Try flipping the operands within the in clause to read as:
var files = DriveApp.searchFiles('"billyTheUser#gmail.com" in writers');
Thanks #theAddonDepot! To illustrate specifically how the accepted answer is useful, I used it to assist in building a spreadsheet to help control files shared with various users. The source code for the full procedure is at the bottom of this post. It can be used directly within this this google sheet if you copy it.
The final result works rather nicely for listing out files by rows and properties in columns (i.e. last modified, security, descriptions... etc.).
The ultimate purpose is to be able to update large number of files without impacting other users. (use case scenario for sudden need to immediately revoke security... layoffs, acquisition, divorce, etc).
//code for looking up files by security
//Posted on stackoverlow here: https://stackoverflow.com/questions/62940196/return-collection-of-google-drive-files-shared-with-specific-user
//sample google File here: https://docs.google.com/spreadsheets/d/1jSl_ZxRVAIh9ULQLy-2e1FdnQpT6207JjFoDq60kj6Q/edit?usp=sharing
const ss = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("FileList");
const clearRange = true;
//const clearRange = SpreadsheetApp.getActiveSpreadsheet().getRangeByName("ClearRange").getValue();
//if you have the named range setup.
function runReport() {
//var theEmail= SpreadsheetApp.getActiveSpreadsheet().getRangeByName("emailFromExcel").getValue();
//or
var theEmail = 'billyTheUser#gmail.com';
findFilesByUser(theEmail);
}
function findFilesByUser(theUserEmail) {
if(clearRange){
ss.getDataRange().offset(1,0).deleteCells(SpreadsheetApp.Dimension.ROWS)
}
var someFiles = DriveApp.searchFiles('"' + theUserEmail + '" in writers');
var aListOfFiles = []
while(someFiles.hasNext()){
var aFile = someFiles.next();
aListOfFiles.push([aFile.getId()
,aFile.getName()
,aFile.getDescription()
,aFile.getSharingAccess()
,aFile.getSharingPermission()
,listEmails(aFile.getEditors())
,listEmails(aFile.getViewers())
,aFile.getMimeType().replace('application/','').replace('vnd.google-apps.','')
,aFile.getDateCreated()
,aFile.getLastUpdated()
,aFile.getSize()
,aFile.getUrl()
,aFile.getDownloadUrl()
])
}
if(aListOfFiles.length==0){
aListOfFiles.push("no files for " + theUserEmail);
}
ss.getRange(ss.getDataRange().getLastRow()+1,1, aListOfFiles.length, aListOfFiles[0].length).setValues(aListOfFiles);
}
function listEmails(thePeople){
var aList = thePeople;
for (var i = 0; i < aList.length;i++){
aList[i] = aList[i].getEmail();
}
return aList.toString();
}

How to create a shortcut in Google Drive Apps Script instead of multiple parents

I've been trying to read about it here: https://developers.google.com/drive/api/v3/shortcuts
And I understand the basics in shortcuts but I can't figure out how to use it in the code - the syntax.
I need to instead of placing a folder in multiple folders, placing shortcuts in those folders named the same as the original folder.
I have an original folder called Project1 placed in Drafts. Shortcuts for this folder needs to be places in Folder2/Drafts, Folder3/Drafts and Folder4/Drafts.
If I afterwards change the name of the original folder Project1 ex. to "New Building" I need to find the shortcuts in Folder 2,3 and 4 (by Id? - I can put the ID of the shortcuts in a datasheet from where I can iterate through them) - and then rename them as the original folder's new name.
And when I move the Project1 from Drafts to Confirmed. I need to move the shortcuts from Folder2/Drafts to Folder2/Confirmed etc.
This is mainly how the basic code looked like for placing the new folder
var folder1 = draft.createFolder("DRAFT - "+"Project1");
var folder1Url = folder1.getUrl();
var folder1Id = folder1.getId();
folder2Draft.addFolder(folder1);
When changing the name of the folder the name would (of course) change in the other places. But as I understand this is not the case with shortcuts. I've tested it with manually created shortcuts witch confirmed this.
The renaming part I do like this when confirming the project:
var folder1 = DriveApp.getFolderById(folder1Id);
var folder1NameOld = folder1.getName();
var folder1NameNew = folder1NameOld.replace("DRAFT - ","");
folder1.setName(folder1NameNew);
And I move the file when confirming the project with the simple:
confirmed.addFolder(folder1);
draftsFolder.removeFolder(folder1);
The script is made in a spreadsheet and I already put alle the folderIDs in a data sheet in the file so I can very easy make references to the different folders and if needed also collect the IDs of the shortcuts to be able to rename them.
Update:
To make a more clear question:
How to do this with shortcuts instead of multi-parenting?
function shortcut() {
var s = SpreadsheetApp.getActive();
var sheet = s.getActiveSheet();
var projectFolderId = sheet.getRange('B1').getValue();
var folder1DraftId = sheet.getRange('B2').getValue();
var folder2DraftId = sheet.getRange('B3').getValue();
var folder1 = DriveApp.getFolderById(projectFolderId);
DriveApp.getFolderById(folder1DraftId).addFolder(folder1);
DriveApp.getFolderById(folder2DraftId).addFolder(folder1);
}
I believe your goal is as follows.
You want to achieve the following script as the shortcut.
function shortcut() {
var s = SpreadsheetApp.getActive();
var sheet = s.getActiveSheet();
var projectFolderId = sheet.getRange('B1').getValue();
var folder1DraftId = sheet.getRange('B2').getValue();
var folder2DraftId = sheet.getRange('B3').getValue();
var folder1 = DriveApp.getFolderById(projectFolderId);
DriveApp.getFolderById(folder1DraftId).addFolder(folder1);
DriveApp.getFolderById(folder2DraftId).addFolder(folder1);
}
At above script, folder1 is put in the folders of folder1DraftId and folder2DraftId.
For this, how about this answer?
Modification points:
In this case, the method of files.create in Drive API is used. But in the current stage, the method of Files: insert in Drive API v2 can also create the shortcut. So in this answer, Drive API v2 of Advanced Google services is used.
Modified script:
When your script is modified, it becomes as follows. Before you run the script, please enable Drive API at Advanced Google services.
From:
var folder1 = DriveApp.getFolderById(projectFolderId);
DriveApp.getFolderById(folder1DraftId).addFolder(folder1);
DriveApp.getFolderById(folder2DraftId).addFolder(folder1);
To:
const folderIDs = [folder1DraftId, folder2DraftId];
folderIDs.forEach(f => {
Drive.Files.insert({
shortcutDetails: {targetId: projectFolderId},
parents: [{id: f}],
title: DriveApp.getFolderById(projectFolderId).getName(),
mimeType: "application/vnd.google-apps.shortcut"
});
});
References:
Advanced Google services
Create a shortcut to a Drive file
Files: insert of Drive API v2
The official document says as follows.
Note: Apps creating shortcuts with files.insert must specify the MIME type application/vnd.google-apps.drive-sdk.
But, when application/vnd.google-apps.drive-sdk is used, the shortcut couldn't be created. I'm not sure whether this is the bug or the current specification. So I used application/vnd.google-apps.shortcut as the mimeType.

Using searchFiles or getFilesByName isn't yielding any results

I'm trying to write a script that will sort large numbers of photos and videos on Google Drive into folders that make it easier for my wife to find what she's looking for. Unfortunately, she has to use Drive rather than Google Photos, so she doesn't have access to the much more robust sorting functionality that Photos would give her.
Warning: I'm not a programmer, so I really don't know what I'm doing. I think I'm telling the script what folder to look in and then telling it to search for files that meet certain criteria in terms of name of the file, but the script is returning null from its search results.
I have tried using both searchFiles (with "name contains [my string var]" as the param), and getFilesByName (with my string var as the param). In both cases, I'm getting named folders but no files.
var currDate = strMonth + strDay;
var photos = currFolder.getFilesByName(
"" + "2019" + currDate + "");
var activeFolder = currFolder.createFolder(currDate);
if (photos.hasNext()) {
myLog = Logger.log("HasNext");
} else {
myLog = Logger.log("Doesn't HasNext");
}
while ( photos.hasNext() ) {
var currPhoto = photos.next();
currPhoto.makeCopy(activeFolder);
myLog = Logger.log(currPhoto);
}
What I expect is that photos is a list of pictures the script has found, that can then be copied over to the folder I created. My debug logging always tells me hasNext() is FALSE, though, and this seems to agree with the fact that no files are getting copied into the folder.
Any help would be greatly appreciated. I'm sure I'm just doing something dumb. Thanks!
Here's an example that will display all of your JPEG files
function findJPEGFiles() {
var files=DriveApp.getFilesByType(MimeType.JPEG);
var html='<style>td,th{border:1px solid black;}</style><table><tr><th>Name</th><th>Id</th><th>Url</th></tr>';
while(files.hasNext()) {
var file=files.next();
html+=Utilities.formatString('<tr><td>%s</td><td>%s</td><td>%s</td></tr>',file.getName(),file.getId(),file.getUrl());
}
html+='</table>';
var userInterface=HtmlService.createHtmlOutput(html);
SpreadsheetApp.getUi().showModelessDialog(userInterface, 'Files');
}

Sorting Google Docs into Google Drive folders based upon a common string in file and folder names

I have hundreds of Google Docs, and lots of Google Folders. They share a common string in the filename. The Docs need to go into the corresponding Folder, and I'd like to automate this with some Script.
What I want to do is as follows:
I have hundreds of Google Docs which follow a similar pattern in the filename:
SURNAME, Forename_userID_fileName
So for instance,
DOE, Jane_jd5678_Document3
PUBLIC, Tom_tp9123_reportTPS
SMITH, John_js1234_finaldocument
and so on and so forth.
I also have corresponding Folders in a Google Team Drive, set up as follows:
SURNAME, Forename (userCode) (userID) - userType
So for instance,
DOE, Jane (145374578) (jd5678) - AET Full Time
PUBLIC, Tom (673468714) (tp9123) - NR Full Time
SMITH, John (874512456) (js1234) - AET Part Time
The common string between the files and the folder names is the userID string.
Currently I download all the Docs, and then upload drag-and-drop into each corresponding folder. Takes ages! I was hoping there is a bit of Apps Script that I can do to automate this but I really don't know where to start at all. Anyone have any pointers?
This StackOverflow question seems to want to do what I want to do, but as I'm such a beginner with Apps Script I can't really decipher the solution.
This is a basic example to point you in the right direction using the basic Google Apps Script DriveApp (as opposed to the advanced Script Services version or other Google Drive API methods). The main concern that comes to mind is the script timing out if this example takes too long to complete. If that happens, you'll need a more complex solution. You could also chunk it up by having the idRegex only work on, e.g., surnames A-D then E-G, etc. The example regular expression could match random files you have with underscores; you may want to find a more complicated regular expression if that is a concern.
function organizeFilesById() {
var idRegex = /_[A-z]+[0-9]+_/;
var files = DriveApp.getFiles();
while (files.hasNext()) {
var file = files.next();
var filename = file.getName();
var id = idRegex.exec(filename);
if (! id) {
continue;
} else {
id = id[0];
}
var query = "title contains '" + id + "'";
var folders = DriveApp.searchFolders(query);
if (folders.hasNext()) {
var folder = folders.next();
Logger.log("Will add %s to %s", filename, folder.getName());
//folder.addFile(file); // uncomment line to actually do it
} else {
Logger.log("No folder found for %s", filename);
// could create folder or just report "folder not found"
}
}
}

PDF Template Archiving

I have Created a form that generates a response sheet. I also have created a Doc which is a Template that my responses fill into. From here it was being turned into a PDF and e-mailed to specific recipients. I now need to archive these into specific folders based on a columns answer. I simply first would like to just be able to move or copy them into a specific folder. How is this possible. I have used multiple scripts but just cant see where the disconnect is. Any help would be greatly appreciated. Thank you enter link description here
You could try using some code like this:
function moveFileToFolder() {
var theFolder = DriveApp.getFolderById('your Folder ID');
var theFile = DriveApp.getFileById('Your File ID').makeCopy(theFolder);
var oldFileName = theFile.getName();
var archivedName = oldFileName.slice(5);
Logger.log('archivedName: ' + archivedName);
archivedName = "archive" + archivedName;
theFile.setName(archivedName);
}
To delete the old file without having to send it to the trash:
//This requires the Drive API To be turned on in the Advanced Google Services.
//RESOURCES menu, ADVANCED GOOGLE SERVICES
function deleteFile(idToDLET) {
//idToDLET = 'the File ID';
//This deletes a file without needing to move it to the trash
var rtrnFromDLET = Drive.Files.remove(idToDLET);
}