How to access to a subFolder with google app script? - google-apps-script

Im using the script editor in a Google spreadsheet, and I want to create a folder inside a root folder , already created. I've tried to follow the official notice of the API DriveApp, but without success.
Here is my code :
function createSubFolder(rootFolder,name){
DriveApp.getFoldersByName(rootFolder);
DriveApp.createFolder(name);
}
I've tried also ( following this old post working with the old version of DriveApp : i.e DocsList) :
function createSubFolder(rootFolder,name){
DriveApp.getFoldersByName(rootFolder).createFolder(name);
}
It seems to be very easy but I don't see where am I wrong.
Does anyone know the way to do it?
Thanks

You need to assign values to a variable.
function createSubFolder(rootFolder,name) {
var AllFoldersWithThisName = DriveApp.getFoldersByName(rootFolder);
var theFirstFolderWithThisName = AllFoldersWithThisName.next();
theFirstFolderWithThisName.createFolder(name);
};
In Google Drive, you could have 1,000 folders all with the same name. Same thing with file names.
The getFoldersByName() method returns:
FolderIterator — a collection of all folders in the user's Drive that have the given name
You need to get one of the folders out of the collection of folders. That is done with the next() method.

Related

Modify Google App Script - Gmail to Google Drive

I'm trying to modify this script found here:
https://github.com/ahochsteger/gmail2gdrive
I need the script to check if the file already exists on Google Drive and if not, create it. Currently, the script just creates the file into Google Drive, without checking to see if an existing file with the same name already exists or not.
I'm not a programmer, I know nothing about Google App Script (although I have managed to set it up and got it running) and I know nothing about JavaScript. I'm just wondering if someone could either point me in the right direction or help me code this one feature that I need?
From what I understand (I could be wrong), the attachment is created based on this line in the code:
var file = folder.createFile(attachment);
So then I tried add this before the createFile:
var file = folder.removeFile(attachment);
My logic here is that if the file exists in the folder, then remove it first before creating it (therefore avoiding duplicate files). But that didn't work.
From the script of GitHub in your question, it is found that attachment is blob. So how about using this filename? I think that there are several solutions for your situation. So please think of this as one of them. The flow of sample script is as follows.
Retrieve the filename of blob.
Retrieve FileIterator using getFilesByName().
If the FileIterator has values, it means that the file with the same filename has already been existing.
If the FileIterator has no values, it means that the file with the same filename is not existing.
The sample script is as follows.
Sample script 1:
If you want to create new file only when the file of same filename is not existing, you can use the following script.
var fileName = attachment.getName();
var f = folder.getFilesByName(fileName);
var file = f.hasNext() ? f.next() : folder.createFile(attachment);
Sample script 2:
If you want to do something when the file of same filename is existing, you can use the following script.
var fileName = attachment.getName();
var f = folder.getFilesByName(fileName);
var file;
if (f.hasNext()) {
// If the file has already been existing, you can do something here.
} else {
// If the file is not existing, you can do something here.
file = folder.createFile(attachment);
}
Note:
From your question, the file is searched from the folder. If you want to search the file from all files, please tell me.
References:
getName()
getFilesByName(name)
FileIterator
If this was not what you want, please tell me. I would like to modify it.

Searching current folder for spreadsheets and changing value in specific cell of each file found

New to Google Apps script here, but have some coding experience. I want to scan current folder for spreadsheets. For each spreadsheet found, I want to change the value in a specific cell (say cell F16 in "Sheet1") to "Q1 FY16". Here is what I have so far:
function myFunction() {
var folderID ="0BxfGszImm3D9flpVlWXd4bjQ";
var topFolder = DriveApp.getFolderById(folderID);
Logger.log(topFolder.getName());
var filesList = topFolder.getFiles();
while (filesList.hasNext()) {
var file = filesList.next();
Logger.log(file.getName());
file.getSheetByName("Sheet1").getRange("F16").setValue("Q1 FY16");
}
}
There are two main problems:
I have to specify a folder ID in this and I don't want to. I want the code to run in the current directory (and eventually I will make it recursive to scan all subfolders as well).
The File class doesn't have the "getSheetByName()" or "getRange()" methods, but I don't know how to cast the files into Spreadsheets.
Any help with this would be greatly appreciated.
Cheers
Where will you be launching this script from? They are no way of launching script directly from google drive.
to Be able to use the getSheetByName() and the getRange() you need to open the file as a spreadsheet.
instead of using this line:
file.getSheetByName("Sheet1").getRange("F16").setValue("Q1 FY16");
You should use something like this :
try {
SpreadsheetApp.openById(file.getId()).getSheetByName("Sheet1").getRange("F16").setValue("Q1 FY16");
}
catch(e){}
you need to use the try - catch since some of the files won't be spreadsheet and give and error when trying to use the SpreadsheetApp.openById().
I hope this helps you a bit, I'll try to update this answer once I get more information for the first part.
Best of luck.

Delete or Trash specific file in Drive

I had a script that ran every day at 5 am, that would move a specific file (data.xls) to the trash. However, since DocsList has been retired, the script no longer functions, and I'm having trouble updating it.
I've seen a couple of delete/setTrashed scripts posted here, but they all seem to function for an array of files, and i only want one specific file deleted.
I'm not a coder, and self-taught myself most of the small amount i have, so i need it as simple as possible (sorry.)
Any and all help or guidance is very appreciated. Thank you.
function myFunction() {
var files = DriveApp.getFilesByName('data');
while (files.hasNext()) {
var file = files.next();
ID = file.getId(file)
Drive.Files.remove(ID);
}
}
I've seen a couple of delete/setTrashed scripts posted here, but they
all seem to function for an array of files, and i only want one
specific file deleted.
Simply put, to delete a single file you delete the first item in the list, what you are calling an array and what Google calls a file iterator.
Retrieving a file by name is going to return a list(iterator), even if it has only one file by that name, so you must treat the single item as the first item in the iterator and set that first item to trash.
Edit:
function myFunction() {
var files = DriveApp.getFilesByName('data');
while (files.hasNext()) {
files.next().setTrashed(true);
}
}
if you know that there is one and only one file by that name you could do something as simple as:
function myFunction() {
DriveApp.getFilesByName('data').next().setTrashed(true);
}
Since this is the first hit for Googling "apps script move file to trash", I found the following easy solution:
let file = DriveApp.getRootFolder().createFile('RIP file.txt', 'Good-bye, world ㅜㅜ');
file.setTrashed(true); // So the file is deleted after 30 days
File documentation
I have workaround using DriveApp removeFile. Note this does not delete or trash the file in the user archive, but is no longer visible in the named folder.
removeFile(child)
Removes the given file from the root of the user's Drive. This method
does not delete the file, but if a file is removed from all of its
parents, it cannot be seen in Drive except by searching for it or
using the "All items" view.
DriveApp.getFolderById(DriveApp.getFolderById(folderId)).removeFile(DriveApp.getFileById(fileId))

Implement a folder move function in Google Dirve

I am very new to writing any types of scripts and am trying to write a Google Apps Script to search through folders for a particular string, and if found move the folder to another folder.
I can copy a folder, but not move it since the copied folder has the same ID as the original, and deleting one deletes the other. From what I have been able to figure out I can implement this by deleting the right child from the folder. I've tried this in the APIs explorer and it does what I expect.
The problem is that I can't for the life of me figure out how to implement the example given in the Google Drive SDK page in script.google.com. If I paste in the example code I get a Missing name after . operator error. None of the scripting commands let me delete a child.
Likely this is a simple issue and arises from my trying to learn some JavaScript by doing this project, but I would appreciate any help or advice on how to implement a move function in Google Script.
The specific question is: How do I implement a move folder script? This is what I am trying, but it removes both folders:
while (contents.hasNext()) {
folder = contents.next();
name = folder.getName();
if (name.search("XYZ") != -1) {
moveFolder = folder;
targetFolder.addFolder(moveFolder) moveFolder.setName('DEL_' +
moveFolder.getName());
removeFolder(moveFolder);
}
}
First, let's clear up some confusion. Two Drive-related "Services" are provided for use within Google Apps Script, Drive Services, and Docslist Services. The documentation you've referenced is for the Google Drive SDK, which is not the same thing. If you're programming in Google Apps Script, ignore the SDK documentation.
Next, let's talk about what a folder or file is on Drive, and how that affects the concepts of "copy", "move" and "delete". A file or folder may have a folder as a parent. In fact, it may have multiple parents. If we want to have the same file or folder "copied" to another folder, we just add it as a child to the target folder. At this point, it may look like we have two items with the same ID - but what we actually have is one item with two parents. If we then remove the file or folder from the original folder (disown it, in a way), it will be left with one parent, and this will appear like a "move". The file or folder will not have been "deleted". On the other hand, if instead of removing the parent / child relationship, we DO delete the file or folder, it will appear that we have "deleted both folders", as you have described.
So, your "move" script needs to add a new parent / child relationship, and remove the other.
The Drive starter script that is presented when you open a new script in the editor contains a function called moveFileToFolder().
This function does what you are looking for, except that the thing it's moving is a file. However, the methods that are used for a file have cousins for folders, so you can just do some replacement to end up with moveFolderToFolder():
/**
* This script moves a specific folder into a given folder, and removes the folder
* from all other folders that previously contained it. For more information on
* interacting with files, see
* https://developers.google.com/apps-script/drive/file
*/
function moveFolderToFolder(sourceFolderId, targetFolderId) {
var targetFolder = DriveApp.getFolderById(targetFolderId);
var sourceFolder = DriveApp.getFolderById(sourceFolderId);
var currentFolders = sourceFolder.getParents();
while (currentFolders.hasNext()) {
var currentFolder = currentFolders.next();
currentFolder.removeFolder(sourceFolder);
}
targetFolder.addFolder(sourceFolder);
};
If you want to deal with folder Names, then you need to use getFoldersByName() to collect all matching folders, then iterate using next() into the list. Here's how that function could be modified to use folder names. To simplify things, it assumes that there is just ONE folder with the given name, and throws an exception if that's not the case. Once we have a handle on the folders we're interested in, the balance of the function remains the same as the previous example.
function moveNamedFolderToFolder(sourceFolderName, targetFolderName) {
var matchedFolders = DriveApp.getFoldersByName(sourceFolderName);
if (matchedFolders.hasNext()) {
var sourceFolder = matchedFolders.next();
if (matchedFolders.hasNext()) throw new Error( "Source Folder Name not unique" );
}
matchedFolders= DriveApp.getFoldersByName(targetFolderName);
if (matchedFolders.hasNext()) {
var targetFolder = matchedFolders.next();
if (matchedFolders.hasNext()) throw new Error( "Target Folder Name not unique" );
}
var currentFolders = sourceFolder.getParents();
while (currentFolders.hasNext()) {
var currentFolder = currentFolders.next();
currentFolder.removeFolder(sourceFolder);
}
targetFolder.addFolder(sourceFolder);
};

How do I set the sharing options for files in Google Drive

I want to change the sharing 'visibility' of currently stored documents from 'anyone with the link may view' to 'private'. This is distinct from removing named viewers and editors.
Unfortunately, the GAS has a very limited support of the documents visibibility. There is no functionality to change this option for the DocsList.File and DocumentApp.Document classes. The Spreadsheet class has the setAnonymousAccess method using which is possible to set if a spreadsheet is public.
Please open a new feature request on the issue tracker if this feature is important for you.
There is an easy way to get what you want using a method that has already been mentioned in this post
You can set the sharing / visibility parameters of any document by moving it to a shared folder. If you remove it from the shared folder then it is no long shared and that is what you wanted to do didn't you ?
So all you need to do is not to use individual sharing parameters on files but rather use the folder structure to share your files.
As a reminder, the code could be something like this to add to the folder :
function sharebyFolder(){
var file = DocsList.getFileById('docId');
var folder = DocsList.getFolderById('shared folder Id');
file.addToFolder(folder)
}
and to remove it :
function UnsharebyFolder(){
var file = DocsList.getFileById('docId');
var folder = DocsList.getFolderById('shared folder Id');
file.removeFromFolder(folder)
}
The old docs API offers a good solution:
https://developers.google.com/google-apps/documents-list/#removing_sharing_permissions