Move file from Drive to TeamDrive folder appscript - google-apps-script

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

Related

Google Apps Script - Impossible operation with an element inside a shared drive

I need your help on something.
I did a function which goal is to make a copy of a template file and put it in a folder in a shared drive. The problem is that the program returns :
"Exception: This operation cannot be performed on an item in a shared Drive"
Yet, I have all the permissions in that shared drive so I don't understand.
I did several tweaks and I've founded that removeFile and addFile are parts of the problem. If I don't run them, the folder is created and the copy is made. But I still need the file to be moved.
I hope someone can help me with this.
PS : You can fin my code below.
function makeCopyFile(folderID, fileID, newName) {
var getFolder = DriveApp.getFolderById(folderID);
var file = DriveApp.getFileById(fileID);
var copyFile = file.makeCopy();
var newFile = copyFile.setName(newName);
// Remove the file from all parent folders
var parents = newFile.getParents();
while (parents.hasNext()) {
var parent = parents.next();
parent.removeFile(newFile);
}
getFolder.addFile(newFile);
};
The problem is that you are trying to delete a file on a shared drive with DriveApp
It will work if you do it instead with the Advanced Drive service where you can specify "supportsAllDrives": true
So, after enabling the Advanced Service: replace
var parents = newFile.getParents();
while (parents.hasNext()) {
var parent = parents.next();
parent.removeFile(newFile);
}
through
var id = copyFile.getId();
// or alternatively `var id = newFile.getId();` - because it is the same
Drive.Files.remove(id,{"supportsAllDrives": true})
As for getFolder.addFile(newFile);
Once you remove a file, you cannot add it back anymore. Also, I do not understand your motivation for it - copyFile.setName(newName); is enough to rename the file - you do not need to delete the file with the old name and insert the one with the new name.
UPDATE
If your goal is to copy a file to a team drive folder, you can do it easily as following with the Drive API:
function makeCopyFile(folderID, fileID, newName){
var resource = {
"parents": [
{
"id": folderID
}
],
"title": newName
}
Drive.Files.copy(resource, fileID, {"supportsAllDrives": true})
}

How to move a file from MyDrive to Team Drive?

I would like to use Google Apps Script to transfer a file from MyDrive to Team Drive. I can do this manually (so I know I have permission) and I enabled the Drive API (so was able to save to MyDrive). However, when I do this (which I got from another post):
function moveFileToFolder(fileId, newFolderId) {
var file = Drive.Files.get(fileId, {supportsTeamDrives: true});
Drive.Files.patch(file, fileId, {
supportsTeamDrives: true,
corpora: 'teamDrive',
removeParents: file.parents.map(function(f) { return f.id; }),
addParents: [newFolderId],
});
}
I get this error:
Sharing restrictions cannot be set on a Team Drive item.
Any ideas?
It appears I was overthinking it as the following works:
var file = DriveApp.getFileById(fileId);
var parentFolder = DriveApp.getFolderById(TEAM_DRIVE_ID);
parentFolder.addFile(file);

Specify folder to save files to in Google 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!";
}

How to copy google drive folder into another google drive account by using App Script?

I want to copy google drive folder to another google Drive by using App Script. Right now I am sharing folder to target account and try to copy folder to target google drive.Here is my App Script Code:
// Make copy in Google Drive
function CopyTamplate(companyName) {
var folder = DriveApp.getFolderById("<<folder_id>>");
var folderid = folder.getId();
folder.setSharing(DriveApp.Access.ANYONE, DriveApp.Permission.VIEW);
Drive.Permissions.insert(
{
'role': 'reader',
'type': 'user',
'value': "target_email#gmail.com"
},
folderid,
{
'sendNotificationEmails': 'false'
});
var sourceFolder = "Company1_copy_tamplete";
var targetFolder = companyName;
var source = DriveApp.getFoldersByName(sourceFolder);
var target = DriveApp.createFolder(targetFolder);
if (source.hasNext()) {
copyFolder(source.next(), target);
}
}
This is a Code for Share folder from One Drive to another by Target Email, Here is a function copyFolder:
function copyFolder(source, target) {
var folders = source.getFolders();
var files = source.getFiles();
while(files.hasNext()) {
var file = files.next();
file.makeCopy(file.getName(), target);
}
while(folders.hasNext()) {
var subFolder = folders.next();
var folderName = subFolder.getName();
var targetFolder = target.createFolder(folderName);
copyFolder(subFolder, targetFolder);
}
}
I have used Google Script Execution API for calling this Script function, and i am getting this Error.
Script error message: "Action not allowed". Please help me to solve the issue or suggest another way to perform this task. Thank you.
This is happening because the role you specified in Drive.Permissions.insert is 'role': 'reader'. Reading the Sharing Files docs, these are the only permitted operations for 'reader':
-Read the metadata (e.g. name, description) of the file or folder
-Read the content of the file
-Read the list of items in the folder
I suggest setting the role to owner or writer instead.

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)