I need the script to recognize that it should only search for files I created, because I'm not allowed to delete other people's files in this Google Drive folder.
var files = folder.searchFiles('modifiedDate < "' + cutOffDate + '"');
I confess that I tried to adjust by myself, but in every way is giving error, something always goes wrong. That form was my last attempt, which also failed:
var files = folder.searchFiles('modifiedDate < "' + cutOffDate + '" and "me#gmail.com" in owners ');
This answer is working for me on a folder that I have shared with one other account.
function getMyFilesFromFolder() {
var myFolderId = "FolderId";
var files = DriveApp.getFolderById(myFolderId).getFilesByType(MimeType.GOOGLE_SHEETS);
var myFiles=[];
while(files.hasNext()) {
var file = files.next();
if(file.getOwner().getEmail()==Session.getActiveUser().getEmail()) {
myFiles.push({name:file.getName(),id:file.getId(),owner:file.getOwner().getEmail(),currentuser:Session.getActiveUser().getEmail()});
Logger.log(Utilities.formatString('Name: %s Id: %s Owner: %s CurrentUser: %s', file.getName(),file.getId(),file.getOwner().getEmail(),Session.getActiveUser().getEmail()));
}
}
}
Let me know if it works for you. It should only be Logging files that you own. So current user email and owner email should be the same.
I also tested this on a shared folder and it works. I didn't want to delete anything so a changed a few things and I was just searching for Google Sheets.
function getOldFileIDs() {
// Old date is 3 Hours
var oldDate = new Date().getTime() - 3600*1000*3;
var cutOffDate = new Date(oldDate).toISOString();
// Get folderID using the URL on google drive
var folder = DriveApp.getFolderById('1iJTAdlhCM13c1CB5xMAjtLZlkaPMIlPb');
var files = folder.getFilesByType(MimeType.GOOGLE_SHEETS);//Just looking for Google Sheets
var obj = [];
while (files.hasNext()) {
var file = files.next();
obj.push({name: file.getName(),id: file.getId(), date: file.getDateCreated(), owner: file.getOwner().getEmail()}); // Modified
}
obj.sort(function(a, b) {
var a= new Date(a.date).valueOf();
var b= new Date(b.date).valueOf();
return b-a;
});
//obj.shift();//I wanted to log all of them
return obj; // Modified
};
function logFiles() {
var email = Session.getActiveUser().getEmail();// Added
var obj = getOldFileIDs(); // Modified
obj.forEach(function(e) { // Modified
if (e.owner == email) { // Added
//Drive.Files.remove(e.id); // Modified
Logger.log('FileName: %s,Owner Email: %s',e.name,e.owner);
}
});
};
Related
Need help on simplifying this script. I still need to add more clusters in while loops.
function Files() {
var ss = SpreadsheetApp.getActive();
var names = ss.getSheetByName("AME");
var SupplierName = names.getRange(names.getLastRow(),5).getValue();
var Cluster = names.getRange(names.getLastRow(),3).getValue();
if (Cluster == 'US'){
var ClusterID = DriveApp.getFolderById("1z2R");
var newFolderID = ClusterID.createFolder(SupplierName);
var sourceFolder = DriveApp.getFoldersByName("US").next();
var files = sourceFolder.getFiles();
var destFolder = DriveApp.getFoldersByName(SupplierName).next();
while(files.hasNext()){
var file = files.next();
file.moveTo(destFolder);
}
return newFolderID.getId();
SUGGESTION:
We are still kind of lurking in the dark here but here are some opportunities I have identified on the provided script above.
/** Can be a global variable */
var ss = SpreadsheetApp.getActive();
var names = ss.getSheetByName("AME");
var SupplierName = names.getRange(names.getLastRow(),5).getValue();
var Cluster = names.getRange(names.getLastRow(),3).getValue();
function Files() {
if(Cluster == 'US') {
var ClusterID = DriveApp.getFolderById("SET FOLDER ID");
var folders = ClusterID.getFoldersByName(SupplierName).hasNext();
if(folders !== true){
ClusterID.createFolder(SupplierName);
moveFolders(SupplierName);
}
else {
moveFolders(SupplierName);
}
}
else {
Logger.log('Cluster is ' + Cluster);
}
}
function moveFolders() {
var sourceFolder = DriveApp.getFoldersByName("US").next();
var files = sourceFolder.getFiles();
Logger.log(files);
var destFolder = DriveApp.getFoldersByName(SupplierName).next();
while(files.hasNext()){
var file = files.next();
file.moveTo(destFolder);
}
}
Created a separate function moveFolders() to move files to the created folder ClusterID.createFolder(SupplierName); if Cluster 'US' was checked on the last row of the sheet. I assumed that your data is from a response that came from a Google Form that is why the last row is only being checked.
Sample Data:
Source parent folder for Cluster Folder and US Folder:
Files inside the "US" Folder:
After the script is run, created the SupplierName folder containing the files moved from the US Folder:
Now I haven't worked on dynamically adjusting the script to manually define the cluster name as of the moment due to lack of clarity of the question, but I'll modify my answer once questions are addressed.
I have a Form bound to a Sheet. That works fine. I need to move the uploads to the newFolder and delete them from the temp holding folder.
I have it split into 2 functions. They work independently but I can not get them to work together. I think I just don't know enough.
So I could use some help sorting this out.
Thanks
//this part works great
function autoFillForm(e) {
var timestamp = e.values[0];
var firstName = e.values[1];
var lastName = e.values[2];
var title = e.values[3];
//create new folder
var parentFolder = DriveApp.getFolderById('My Parent Folder ID');
var newFolder = parentFolder.createFolder(lastName + ' - ' + firstName);
//Get template
var file = DriveApp.getFileById('My Template ID');
//Copy template, name it, save to new folder
var copy = file.makeCopy(lastName + ',' + firstName + ' - ' + 'Template Name', newFolder);
//Open copied file
var doc = DocumentApp.openById(copy.getId());
//Get Template body
var body = doc.getBody();
//Replace text in template
body.replaceText('{{fName}}', firstName);
body.replaceText('{{lName}}', lastName);
body.replaceText('{{title}}', title);
//Save and close
doc.saveAndClose();
}
UPDATE
I was able to get this working and it moves the files but only in a stand alone script. I have been trying for hours to get it to work with the main scripts and I'm at a loss.
function movingFiles (e){
//get file names from source folder
var files = DriveApp.getFolderById(ID for Source Folder).getFiles();
while(files.hasNext())
{
var file = files.next();
}
//get file ID
var fileId = file.getId();
//move file, clean source folder
DriveApp.getFolderById(newFolder).addFile(file);
file
.getParents()
.next()
.removeFile(file);
}
TLDR:
this: DriveApp.getFolderById(newFolder).addFile(file);
to this: DriveApp.getFolderById(newFolder.getId()).addFile(file);
this: (newFolder)
to this: (newFolder.getId())
I feel kind of stupid because this was an easy answer in the end.
I am able to to do everything in the one function. No need for seperate functions of Global Variables.
//this part works great
function autoFillForm(e) {
var timestamp = e.values[0];
var firstName = e.values[1];
var lastName = e.values[2];
var title = e.values[3];
//create new folder
var parentFolder = DriveApp.getFolderById('My Parent Folder ID');
var newFolder = parentFolder.createFolder(lastName + ' - ' + firstName);
//Get template
var file = DriveApp.getFileById('My Template ID');
//Copy template, name it, save to new folder
var copy = file.makeCopy(lastName + ',' + firstName + ' - ' + 'Template Name',
newFolder);
//Open copied file
var doc = DocumentApp.openById(copy.getId());
//Get Template body
var body = doc.getBody();
//Replace text in template
body.replaceText('{{fName}}', firstName);
body.replaceText('{{lName}}', lastName);
body.replaceText('{{title}}', title);
//Save and close
doc.saveAndClose();
//get file names from source folder
var files = DriveApp.getFolderById(ID for Source Folder).getFiles();
while(files.hasNext())
{
var file = files.next();
}
//get file ID
var fileId = file.getId();
//error here
//move file, clean source folder
DriveApp.getFolderById(newFolder).addFile(file);
file
.getParents()
.next()
.removeFile(file);
//this is where I was making a mistake
//this: DriveApp.getFolderById(newFolder).addFile(file);
//to this: DriveApp.getFolderById(newFolder.getId()).addFile(file);
//I was failing to understand I needed to define the function to the var again
}
I am pulling a drive activity report using GCP/GAMadv which gives me file IDs of various users in our workspace domain on a google sheet. My goal is to find the folder path of these files using file IDs. I am using appscript to get to that. Here is the code that I am running so far.
function getFolderPath(fileID, folderPath =""){
var sheetID = "1YfZgkLvAnPj7kOIQOVkcXeJgnh-KTecMn6er1a0elkk"
var sheet = SpreadsheetApp.openById(sheetID)
// var file = sheet.Files.get(fileID)
var parent = Drive.Files.get(fileID);
console.log(parent)
// console.log(file)
var parentElement = parent.items[0]
console.log(parentElement)
// var parentElement = parent[0]
var parentFile = Drive.Files.get(parent.id);
var parentPath = parentFile.title;
if (parent.isRoot)
return "/" + folderPath;
else {
return getFolderPath(
parentFile.id,
parentPath + "/" + folderPath
);
}
}
Looks like this is returning ALL the files we have in our drive rather than the ones on the sheet.
Help would be greatly appreciated! Thanks.
Folder Path from Id
function getFolderPathFromId(id="fileid") {
try {
var file = DriveApp.getFileById(id)
var pA = [];
pA.push(file.getName());
var folder = file.getParents();
while (folder.hasNext()) {
var f = folder.next();
pA.push(f.getName());
folder = f.getParents()
}
var r = pA.reverse().slice(0,-1).join(' / ');
}
catch (e) {
return e;
}
Logger.log(r);
return r;
}
I would like to save gmail attachments(.pdf files) from a specific email in a specific Google Drive folder. I also need to rename file with a string composed by some string of the email.
I have developed a simple script using Google Apps Script with some functions.
This is the main function I have wrote:
function GmailToDrive() {
var query = '';
query = 'in:inbox from:noreply#agyo.io has:nouserlabels ';
var threads = GmailApp.search(query);
var label = getGmailLabel_(labelName);
var parentFolder;
if (threads.length > 0) {
parentFolder = getFolder_(folderName);
}
var root = DriveApp.getRootFolder();
for (var i in threads) {
var mesgs = threads[i].getMessages();
for (var j in mesgs) {
//get attachments
var attachments = mesgs[j].getAttachments();
var message_body = mesgs[j].getBody();
for (var k in attachments) {
var attachment = attachments[k];
var isDefinedType = checkIfDefinedType_(attachment);
if (!isDefinedType) continue;
var attachmentBlob = attachment.copyBlob();
var file = DriveApp.createFile(attachmentBlob);
file.setName(renameFile_(attachment, message_body))
parentFolder.addFile(file);
root.removeFile(file);
}
}
threads[i].addLabel(label);
}
}
The checkIfDefinedType_(attachment) function checks if the attachments is a .pdf file and the renameFile_(attachment, message_body) rename the attachment extracting some string from the email.
The script seems to be correctly developed but sometimes I have two or more same attachments saved in my google drive folder.
Stefano, I had the same issue, if this is the same code as adapted from here.
I removed the line for (var i in fileTypesToExtract) { which was causing duplicates for me. It was running the query for each of the file types.
// `has:pdf` searches for messages with PDF attachments
var query = 'has:pdf in:inbox from:noreply#agyo.io has:nouserlabels ';
var results = Gmail.Users.Messages.list(userId, {q: query});
results.messages.forEach(function (m) {
var msg = GmailApp.getMessageById(m.id);
msg.getAttachments().forEach(function (a) {
var fileName = a.getName();
fileName = saveAttachmentToFolder(folder, a, fileName, msg.getDate(), input.tz);
});
});
function saveAttachmentToFolder(folder, attachment, fileName, date, timezone) {
if (timezone) {
fileName = standardizeName(attachment, date, timezone);
}
Logger.log(fileName);
folder.createFile(attachment.copyBlob()).setName(fileName);
}
The code snippet above is based on a Gmail add-on that I created, specifically for saving attachments to labeled folders in Drive: https://github.com/ellaqezi/archiveByLabel/blob/main/Code.gs#L24
In the label field, you can define nested directories to create in Drive e.g. foo/bar.
In the query field, you can copy the parameters as you would use them in Gmail's search bar.
I've been working on a script that lists the name and folder ids of the all the folders in a specific folder in my drive. Once the list is created, I run the function to get the id and change the folder permissions to private (only specific people can view), remove editors who do not have the company domain and switches them to viewers, and then it should change the permissions for any files in the folder as well. The initial step of creating the ids works fine. Unfortunately, the updatePermissions() function only seems to infinitely loop through the first folder and I'm not sure what next steps to take to ensure that the script pulls the next folder id from the list in the spreadsheet. Any help would be greatly appreciated.
function listSchoolFolders(){
var folderId = 'enter folder id here';
var myspreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var parentFolder = DriveApp.getFolderById(folderId);
var childFolders = parentFolder.getFolders();
// List folders inside the folder
while (childFolders.hasNext()) {
var childFolder = childFolders.next();
var data = [
childFolder.getName(),
childFolder.getId()
];
//Write
myspreadsheet.appendRow(data)
}
}
//------------------------- New Function -------------------------//
function updatePermissions() {
var myspreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var schoolRows = myspreadsheet.getDataRange();
var schoolNumRows = schoolRows.getNumRows();
var schoolValues = schoolRows.getValues();
//Loop through List of Schools
var row_num = schoolValues[0][2];
while(row_num<schoolNumRows){
//Retrieve folder id and go to folder
var folderId = schoolValues[row_num][1];
var folderName = schoolValues[row_num][0];
Logger.log(folderName);
try {
var schoolFolder = DriveApp.getFolderById(folderId);
}
catch (err){
Logger.log(folderName + ": " + err.message);
row_num = row_num+1;
myspreadsheet.getRange(1,3).setValue(row_num);
continue;
};
};
//Loop through folders and set permissions
var childFolders = DriveApp.getFolderById(folderId).getFolders();
while (childFolders.hasNext()) {
var childFolder = childFolders.next();
var childFolderPermissions = childFolder.setSharing(DriveApp.Access.PRIVATE, DriveApp.Permission.VIEW);
var files = DriveApp.getFolderById(folderId).getFiles();
while (files.hasNext()) {
Logger.log(files.next().getName());
var fileFolderPermissions = files.next().setSharing(DriveApp.Access.PRIVATE, DriveApp.Permission.VIEW);
//check for rogue editors
var viewEditors = schoolFolder.getEditors();
for (i in viewEditors) {
var email = viewEditors[i].getEmail();
var emailSource = email.split("#")[1]
if (emailSource != "tester.com") {
// add as a viewer or remove completely?
addViewer(email)
};
};
};
};
// Recursive call for any sub-folders
getChildFolders(childFolder);
The error was in the logic checking for child folders. If there was no child folder, the script completed. I've added two conditional checks on each top-level folder, one for child folders and one for files. This script functions with one-level depth.
function updatePermissions() {
// define several variables to use throughout the script
var editors, domain, email;
var myspreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var schoolValues = myspreadsheet.getDataRange().getValues();
// Loop through List of folders
// Skip row 1
for(var i=1; i<schoolValues.length; i++) {
//Retrieve folder id and go to folder
var folderId = schoolValues[i][1];
var folderName = schoolValues[i][0];
Logger.log(folderName);
var schoolFolder = DriveApp.getFolderById(folderId);
// Get the children
var childFolders = schoolFolder.getFolders();
// test for child folders.
if(!childFolders.hasNext()) {
// There is no child folder, so test for files
if(!schoolFolder.getFiles().hasNext()) {
// There are no files, so get the folder editors and loop
editors = schoolFolder.getEditors();
for(var j=0; j<editors.length; j++) {
email = editors[j].getEmail();
domain = editors[j].getDomain(); // easier than using a split function
// Check the domain. Remove if no match, add as viewer if there is a match
if(domain !== "testdomain.com") {
schoolFolder.removeEditor(email)
} else {
schoolFolder.removeEditor(email).addViewer(email);
}
}
}
// There are child folders, loop through and change permissions
} else {
while (childFolders.hasNext()) {
var childFolder = childFolders.next();
// Set permissions on the folder
childFolder.setSharing(DriveApp.Access.PRIVATE, DriveApp.Permission.VIEW);
// Get the files in the child folder and loop
var files = childFolder.getFiles();
while (files.hasNext()) {
files.next().setSharing(DriveApp.Access.PRIVATE, DriveApp.Permission.VIEW);
var viewEditors = schoolFolder.getEditors();
// Loop the array of editors
for (var j=0; j<viewEditors.length; j++) {
email = viewEditors[j].getEmail();
domain = viewEditors[j].getDomain();
if (domain !== "testdomain.com") {
// add as a viewer or remove completely?
Logger.log("add " + email + " as a viewer");
files.next().addViewer(email);
} else {
// Remove the editor
Logger.log("removed " + email + " from folder");
files.next().removeEditor(email);
}
};
}
}
};
}
// Recursive call for any sub-folders
//getChildFolders(childFolder);
};