Specify folder to save files to in Google Script - google-apps-script

I have a simple form published through Google Apps Scripts that lets someone upload a file anonymously. The script works well, but it will always save to the root of my Google Drive instead of to a specific folder. I'd like it to create a new folder with the person's first name + last name (collected from the form) within a specific folder. I know I need to use the destination FolderID, just not sure how to use it properly.
Here's my existing code:
function uploadFiles(form) {
try {
var dropbox = form.FirstName + form.LastName;
var folder, folders = DriveApp.getFoldersByName(dropbox);
if (folders.hasNext()) {
folder = folders.next();
} else {
folder = DriveApp.createFolder(dropbox);
}
var blob = form.myFile;
var file = folder.createFile(blob);
file.setDescription("Uploaded by " + form.Name);
return "Thank you, your file was uploaded successfully!";

I'm not sure if I understood well what is your goal. But if you want to create folder 'FirstnameLastname' within some specific folder, you should first select this 'parent' folder and then use it for creating new one.
EDIT:
Summary
First look at the reference from Google. You use class DriveApp and methode .createFolder(). Google cheat sheet says, that this methode within the DriveApp class 'Creates a folder in the root of the user's Drive with the given name.'. This methode returns folder as return type (your variable type will be folder).
This is the reason why your code creates folders only in root folder.
Look in the cheatsheet again but now look at the folder class. You can use the same methode .createFolder() with this class. Result is following: 'Creates a folder in the current folder with the given name.' This methode returns again folder.
Solution
Google Drive:
Create (or open) manually your desired folder in your Google Drive repository.
Find the ID of your folder (when you open the folder, you can find the id at the end of the URL: drive.google.com/drive/folders/{this is your ID})
Script:
Get your desired destination folder var parentFolder = DriveApp.getFolderById("{put your folder id here}");
Add your code
When you are creating new folder within parent folder, just call the .createFolder() methode from your parentFolder which you have created earlier: var folder = parentFolder.createFolder();
Edited script:
function uploadFiles(form) {
try {
var dropbox = form.FirstName + form.LastName;
var parentFolder = DriveApp.getFolderById('parentfolderId'); //add this line...
var folder, folders = DriveApp.getFoldersByName(dropbox);
if (folders.hasNext()) {
folder = folders.next();
} else {
folder = parentFolder.createFolder(dropbox); //edit this line
}
var blob = form.myFile;
var file = folder.createFile(blob);
file.setDescription("Uploaded by " + form.Name);
return "Thank you, your file was uploaded successfully!";
}

Related

How to search and get a specific file using Google Apps Script to search in the Parent folder and in its subfolders?

The issue I'm current facing is:
I created a main folder named "Parent" with the folder ID:eg abcde12345.
Within the Parent folder, there are 3 diff folders (eg. Folder A, Folder B, Folder C) with their own files.
The specific file I am looking for is: "File to be sent.pdf"
This file, I placed in Folder C for example.
However, the script I wrote below (with some details edited out) only search for the specific file in the Parent folder. The search does not go into Folder A,B or C to look for the file with the exact filename.
Is there a way to search for this specific file within the Parent + A + B + C without hardcode the Folder A,B,C IDs in the script?
Thank you!
Ps. The number of sub folders may grow more than A,B,C and in these sub folders, I am thinking of creating more layers.
function ReturnWork(){
var markedFolder = DriveApp.getFolderById("abcde12345");
var ws = SpreadsheetApp.getActiveSpreadsheet();
/*This section which I edited out to shorten this post contains variables example:
-emailAddress
-subject
-etc... all details needed for the mailApp below.*/
var docName = 'File to be sent.pdf';
var markedFiles = markedFolder.getFilesByName(docName);
if(markedFiles.hasNext()){
MailApp.sendEmail({
to: emailAddress,
subject: subjectMarked,
replyTo: centre_email,
htmlBody : markedHTML.evaluate().getContent(),
attachments: [markedFiles.next().getAs(MimeType.PDF)],
});
}
}
One option would be to recursively search the file in the target folder and its subfolders:
function searchFileTest() {
const targetFolderId = 'abc123';
const fileName = 'File to be sent.pdf';
const filesFound = searchFile(fileName, targetFolderId);
for (const file of filesFound) {
Logger.log('File found: ' + file.getUrl());
}
}
function searchFile(fileName, folderId) {
let files = [];
// Look for file in current folder
const folderFiles = DriveApp.getFolderById(folderId).getFiles();
while (folderFiles.hasNext()) {
const folderFile = folderFiles.next();
if (folderFile.getName() === fileName) {
files.push(folderFile);
}
}
// Recursively look for file in subfolders
const subfolders = DriveApp.getFolderById(folderId).getFolders();
while (subfolders.hasNext()) {
files = files.concat(searchFile(fileName, subfolders.next().getId()));
}
return files;
}
This will return an array with all the files that have that name in the folder you specify of its subfolders.
Related:
How to search contents of files in all folders and subfolders of google drive in Apps Scripts?
Google apps script - iterate folder and subfolder
assign hyperlink to cell in google sheets to google drive files using google app script

Google Spredsheet - Copy files to another folder in TeamDrive

I try to copy some movies from a Google Drive folder to another Folder and rename the file by using a script in a Spreadsheet. (other options than spreadsheets are also welcome, but this seems to be easyest). I got access on both folders.
a) is working as it should, makeing a copy of the file in the same folder;
b) is also doing a copy but still in the same folder and not in the destination-folder;
c) giving error:
"cannot find method makeCopy(string,string)"
function copyFile() {
var FileToCopy=DriveApp.getFileById('12B-zfprxgazbZ4JFxyrqhYveofYATzC1');
FileToCopy.makeCopy()
}
function copyFile() {
var FileToCopy=DriveApp.getFileById('12B-zfprxgazbZ4JFxyrqhYveofYATzC1');
var Destination = "1yC_nDk9VQLHBAkYNwNkRucfxp6yFBIV1";
FileToCopy.makeCopy(Destination)
}
function copyFile() {
var FileToCopy=DriveApp.getFileById('12B-zfprxgazbZ4JFxyrqhYveofYATzC1');
var Destination = "1yC_nDk9VQLHBAkYNwNkRucfxp6yFBIV1";
var Filename = "newFile.mp4";
FileToCopy.makeCopy(Filename, Destination)
}
Instead of
var Destination = "1yC_nDk9VQLHBAkYNwNkRucfxp6yFBIV1";
try
var Destination = DriveApp.getFolderById("1yC_nDk9VQLHBAkYNwNkRucfxp6yFBIV1");
If you see the documentation, you need to pass the folder and not the ID of the destination folder.

Move file from Drive to TeamDrive folder appscript

I would like to transfer a file from MyDrive to TeamDrive with script from AppmMaker. I use DriveApp to create the file in MyDrive and with a DrivePicker widget from appmaker i get id from target folder to save the file.
DriveApp can move file in TeamDrive with
var file = DriveApp.getFileById(fileId);
var parentFolder = DriveApp.getFolderById(TEAM_DRIVE_ID);
parentFolder.addFile(file);
but not in a folders in TeamDrive.
I have try to use this code :
function moveFileToFolder(fileIds, newFolderId) {
var file = Drive.Files.get(fileIds, {supportTeamDrives: true,supportsTeamDrives: true});
Drive.Files.patch(file, fileIds, {
removeParents: file.parents.map(function(f) { return f.id; }),
addParents: [newFolderId],
supportTeamDrives: true,
supportsTeamDrives: true
});
}
I have the error "Sharing restrictions cannot be set on a Team Drive item."
Reference :How to move a file from MyDrive to Team Drive?
(the solution of the reference not work because i want to move it in a folder in teamdrive not directly in teamdrive)
Any Idea ?
There is a parameter to change in the file metadata because Drive file and Team Drive file are not the same. You can change it with
var file = Drive.Files.get(FileId);
file.capabilities.canMoveTeamDriveItem = true;
And after simply move it with
var fileDriveApp = DriveApp.getFileById(FileId);
fileDriveApp.getParents().next().removeFile(fileDriveApp);
var folder = DriveApp.getFolderById(foldersId);
folder.addFile(fileDriveApp);
Reference : https://developers.google.com/drive/api/v3/reference/files

Move Folder Using App Script

So i'm brand new to JS and trying to build a program for internal operation at the company I work for. Below is the first bit of my code. I have a created a google form, and set a trigger so that when the submit button is clicked the below code will start. The trigger works and the first two functions work, but I cannot seem to get the Karrie folder to move from the root to the sub folder id (I do have the correct ID but omitted it from this post). Maybe I'm doing this all backwards so any help would be appreciated.
// Create Karrie Folder In Root
function start() {
var sourceFolder = "Property Template";
var targetFolder = "Karrie";
var source = DriveApp.getFoldersByName(sourceFolder);
var target = DriveApp.createFolder(targetFolder);
if (source.hasNext()) {
copyFolder(source.next(), target);}}
// Adds Property data to Karrie Folder
function copyFolder(source, target) {
var folders = source.getFolders();
var files = source.getFiles();
while(files.hasNext()) {
var file = files.next();
file.makeCopy(file.getName(), target);}
// Adds Photo Folders to Karrie Folder
while(folders.hasNext()) {
var subFolder = folders.next();
var folderName = subFolder.getName();
var targetFolder = target.createFolder(folderName);
copyFolder(subFolder, targetFolder);}}
// Moves Karrie folder to propertie folder
function MoveFiles(){
var files = DriveApp.getFolderByName("Karrie");
var destination = DriveApp.getFolderById("ID NA");
destination.addFolder(files);}
Debugger
I understood that MoveFiles() in your script doesn't work. If my understanding is correct, how about this modification?
Modification points :
In order to move a folder, it required to move the parent of the folder.
But when addFolder() is used to the folder, the folder has 2 parents.
So original parent has to be removed.
There is no getFolderByName(). Please use getFoldersByName().
Modified script :
function MoveFiles(){
var folder = DriveApp.getFoldersByName("Karrie").next();
var destination = DriveApp.getFolderById("ID NA");
destination.addFolder(folder);
folder.getParents().next().removeFolder(folder);
}
Note :
In this script, The folder and parent of "Karrie" supposes only one in the Google Drive, respectively.
References :
getFoldersByName()
addFolder()
removeFolder()
If I misunderstand your question, please tell me. I would like to modify it.
Edit 1 :
When you run this function, does the ID of Logger.log(r) show the folderId of "Karrie"?
function sample() {
var r = DriveApp.getFoldersByName("Karrie").next().getId();
Logger.log(r)
}
Edit 2 :
Please confirm and consider the following points.
Confirm the folder name and the existence of the folder again.
Run sample() and confirm folder ID of "Karrie".
Confirm whether there are no functions with the same name.
Can I ask you the folder ID of "Karrie"? If you cannot retrieve the folder ID using DriveApp.getFoldersByName("Karrie").next().getId(), I propose to use directly the folder ID of "Karrie".
Updated on March 30, 2022:
In the current stage, the files and folders can be moved using moveTo. Ref This method has added on July 27, 2020. When moveTo is used, the above script can be modified as follows.
function MoveFiles(){
var folder = DriveApp.getFoldersByName("Karrie").next();
var destination = DriveApp.getFolderById("ID NA");
folder.moveTo(destination);
}
Reference:
moveTo(destination) of Class Folder
As of 2020, the easier way I found to move a file is to use this function:
function moveToFolder(file, sourceFolder, destFolder) {
var file = DriveApp.getFileById(file.getId());
destFolder.addFile(file);
sourceFolder.removeFile(file);
}
Because of the first line, you can convert your Spreadsheet, Google Form, Document or others Google objects into a File.
Then we just use methods of the Folder class : https://developers.google.com/apps-script/reference/drive/folder
Notes:
If you created your file by using .create() your sourceFolder will be DriveApp.getRootFolder().
If you have multiple files to move, just iterate over them.

How to Create a Spreadsheet in a particular folder via App Script

Can anybody help me out,
I want to create a Spreadsheet through App Script in a particular folder. How to do that.
Presently I am doing as follow:
var folder = DocsList.getFolder("MyFolder");
var sheet = SpreadsheetApp.create("MySheet");
var file = DocsList.getFileById(sheet.getId());
file.addToFolder(folder);
file.removeFromFolder(file.getParents()[0]);
It is not working.......
As suggested by #Joshua, it's possible to create a Spreadsheet (in a specific folder) with the Advanced Drive Service (you'll need to activate this if you haven't already, by going into Services +, find Drive API and click Add).
var name = 'your-spreadsheet-name'
var folderId = 'your-folder-id'
var resource = {
title: name,
mimeType: MimeType.GOOGLE_SHEETS,
parents: [{ id: folderId }]
}
var fileJson = Drive.Files.insert(resource)
var fileId = fileJson.id
No need to move files around with this method !
folder = DriveApp.getFolderById("FOLDER_ID")
var ss = SpreadsheetApp.create("SPREADSHEET_NAME")
DriveApp.getFileById(ss.getId()).moveTo(folder);
You may use the above code to achieve the same without using advanced drive services
Since you can no longer create Google Docs (Docs or SpreadSheets) using DriveApp, nor use addToFolder because DocList is deprecated. There is only one way to create or "move" Google Docs or Google SpreadSheets..
//"Move" file to folder-------------------------------//
var fileID = '12123123213321'
var folderID = '21321312312'
var file = DriveApp.getFileById(fileID).getName()
var folder = DriveApp.getFolderById(folderID)
var newFile = file.makeCopy(file, folder)
//Remove file from root folder--------------------------------//
DriveApp.getFileById(fileID).setTrashed(true)
As you can see this DOES NOT move the file, it makes a copy with the same name in the folder you want and then moves the original file to the trash. I'm pretty sure there is no other way to do this.
The other answer is a bit short (and not very explicit).
While your approach is logic and should work if you replace
file.removeFromFolder(file.getParents()[0]);
with
file.removeFromFolder(DocsList.getRootFolder());
there is a better way to do the same job using the new Drive app and the Folder Class, Folder has a method to create a file and you can specify the file type using the mimeType enum.
Code goes like this :
function myFunction() {
var folders = DriveApp.getFoldersByName('YOUR FOLDER NAME'); // replace by the right folder name, assuming there is only one folder with this name
while (folders.hasNext()) {
var folder = folders.next();
}
folder.createFile('new Spreadsheet', '', MimeType.GOOGLE_SHEETS); // this creates the spreadsheet directly in the chosen folder
}
In July 27, 2020 there have been these updates:
The File class now has the following methods:
file.getTargetId(): Gets a shortcut's file ID.
file.getTargetMimeType(): Returns the mime type of the item a shortcut points to.
file.moveTo(destination): Moves a file to a specified destination folder.
The Folder class now has the following methods:
folder.createShortcut(targetId): Creates a shortcut to the provided Drive item ID, and returns it.
folder.moveTo(destination): Moves an item to the provided destination folder.
The following Folder class methods have been deprecated:
addFile(File)
addFolder(Folder)
removeFile(File)
removeFolder(Folder)
https://developers.google.com/apps-script/releases/#july_27_2020
So you can create a Spreadsheet file in a folder using file.moveTo(destination) method:
function createSpreadSheetInFolder(ss_new_name, folder_dest_id) {
var ss_new = SpreadsheetApp.create(ss_new_name);
var ss_new_id = ss_new.getId();
var newfile = DriveApp.getFileById(ss_new_id);
newfile.moveTo(DriveApp.getFolderById(folder_dest_id))
return ss_new_id;
}
var file_name = 'SPREADSHEET NAME';
var folder_id = 'DESTINATION FOLDER ID';
var new_ssId = createSpreadSheetInFolder(file_name, folder_id)
You can create a spreadSheet and then add it to the folder.
function createSpreadSheetInFolder(name,folder){
var ss = SpreadsheetApp.create(name);
var id = ss.getId();
var file = DriveApp.getFileById(id);
folder.addFile(file);
return ss;
}
folderId='your_folder_id'
name='my_new_ss'
folder=DriveApp.getFolderById(folderId)
createSpreadSheetInFolder(name,folder)
By using the folder.addFile method there's no need to use a temp file (no need to duplicate and remove file). Pretty straightforward !
I finally got the answer to my question. The following works
var file = DocsList.getFileById(sheet.getId());
var folder = DocsList.getFolder("MyFolder");
file.addToFolder(folder);
// remove document from the root folder
folder = DocsList.getRootFolder();
file.removeFromFolder(folder);
What is not working? Use getRootFolder in the last line.
Creating a new spreadsheet in a file can be done using this link as a reference.
createFile(name, content, mimeType)
Therefore using the enum MimeType we can do:
var folder = DriveApp.getFolderById("your-folder-id");
folder.createFile("My File Name","",MimeType.GOOGLE_SHEETS)