S Woodhouse
S Woodhouse

Reputation: 221

Moving Files In Google Drive Using Google Script

I'm trying to create documents using information posted through Google forms, then once the document is created I would like to move the document into a shared folder for people to view.

At the moment I have the script taking all of the information from the Google Forms linked spreadsheet.

Using that information I'm using the following code to create the document:

  var targetFolder = DriveApp.getFolderById(TARGET_FOLDER_ID);
  var newDoc = DocumentApp.create(requestID + " - " + requestSummary);

This is creating the document successfully in my Google Drive root folder, but I can't seem to move it where I want to move it to.

I've seen a lot of posts suggesting use stuff like targetFolder.addFile(newDoc) but that doesn't work, similarly I've seen examples like newDoc.addToFolder(targetFolder) but again this isn't working for me.

It seems that all the online questions people have already asked about this are using the previous API versions that are no longer applicable and these methods do not apply to the new DriveApp functionality.

What I would like, if possible, is to create the new document as above so that I can edit the contents using the script, then be able to move that file to a shared folder. (From what I understand there is no 'move' function at present, so making a copy and deleting the old one will suffice).

Upvotes: 22

Views: 65577

Answers (9)

user3075569
user3075569

Reputation:

There is no direct method in the File or Folder Classes to move files from one folder in Google Drive to another. As you mentioned you can copy the file to another folder with the method makeCopy() and then delete it with setTrashed(), the code should look like this:

  var targetFolder = DriveApp.getFolderById(TARGET_FOLDER_ID);
  var newDoc = DocumentApp.create(requestID + " - " + requestSummary); // Creates the Document in the user's Drive root folder

  // Modify the new document here, example:
  // var body = newDoc.getBody();
  // body.appendParagraph("A paragraph.");
  // newDoc.saveAndClose();
  
  var driveFile = DriveApp.getFileById(newDoc.getId()); // Gets the drive File
  
  driveFile.makeCopy(newDoc.getName(), targetFolder); // Create a copy of the newDoc in the shared folder
  driveFile.setTrashed(true);  //  sets the file in the trash of the user's Drive

EDIT:

In a second thought and taking into account Ruben's comments. I agree that it is a better practice to implement Amit's answer.

Upvotes: 4

Oleg S.
Oleg S.

Reputation: 11

The script transfers all your personal files to a shared disk (Team drive). Saves the folder structure.

DRIVE_FOLDER_ID = '111aaa'; // Folder ID on the shared drive

function start() {
    var files = DriveApp.searchFiles('"me" in owners');
    while (files.hasNext()) {
      var file = files.next();
      newPath = fileMoveWithPath(file, DRIVE_FOLDER_ID);
      
      console.info("New path: ", getFullPath(newPath));
    }
}

function fileMoveWithPath(file, root) {
  var folders = [],
      parent = file.getParents();

  // Проходим по иерархии папок текущего файла до корня
  while (parent.hasNext()) {
    parent = parent.next();
    folders.push(parent);
    parent = parent.getParents();
  }

  console.info("Old path: ", getFullPath(file));
  if (folders.length > 0)
    targetPath = makeNewPath(folders, DriveApp.getFolderById(root));
  else
    targetPath = DriveApp.getFolderById(root);

  if (targetPath) {
    targetFile = file.moveTo(targetPath);
    return targetFile;
  };
  return;
}

function makeNewPath(folders, newroot) {
  var f = folders.pop();
  var query = "'" + newroot.getId() + "' in parents and title = '" + f.getName() + "' and mimeType='application/vnd.google-apps.folder' "
  var targetFolder = DriveApp.searchFolders(query);
  if (targetFolder.hasNext()) 
    targetFolder = targetFolder.next()
  else
    targetFolder = newroot.createFolder(f.getName());

  if (folders.length > 0) 
    return makeNewPath(folders, targetFolder)
  else
    return targetFolder;
}

function getFullPath(file) {
  var folders = [],
      parent = file.getParents();
  while (parent.hasNext()) {
    parent = parent.next();
    folders.push(parent.getName());
    parent = parent.getParents();
  }
  if (folders.length) {
    return '> /' + folders.reverse().join("/") + '/' + file.getName();
  }
  return '> /' + file.getName();
}

Upvotes: 1

Amit Agarwal
Amit Agarwal

Reputation: 11268

If we make a copy of the file and trash the original, it would change the file URL and also the file sharing settings won't be preserved.

In Drive, it is possible to add a file to multiple folders with the .addFolder() method of DriveApp service. You can add the file to the target folder and then remove the file from the immediate parent folder.

function moveFiles(sourceFileId, targetFolderId) {
  var file = DriveApp.getFileById(sourceFileId);
  var folder = DriveApp.getFolderById(targetFolderId);
  file.moveTo(folder);
}

Upvotes: 42

Janine White
Janine White

Reputation: 489

Use File.moveTo(destination).

var newFileId = newDoc.getId();
var newFile = DriveApp.getFileById(newFileId);
newFile.moveTo(targetFolder);

Upvotes: 3

ScrapeHeap
ScrapeHeap

Reputation: 435

It looks like there is now a moveTo() function with the Drive API (advanced services) that makes it easy to move files:

moveTo(destination)

Moves this item to the provided destination folder.

The current user must be the owner of the file or have at least edit access to the item's current parent folder in order to move the item to the destination folder.

Here is some code I used to move all files from the "screenshot input" folder to the "screenshot processed" folder:

var inputFolder = DriveApp.getFolderById(SCREENSHOT_INPUT_FOLDER_ID);
var processedFolder = DriveApp.getFolderById(SCREENSHOT_PROCESSED_FOLDER_ID);

var files = inputFolder.getFiles();
while (files.hasNext()) {
    var file = files.next();
    file.moveTo(processedFolder);
}

Upvotes: 6

Alexey Dral
Alexey Dral

Reputation: 11

A bit safer approach compared to the previous ones:

  1. If you remove link to the file first, then you will not be able to addFile.

  2. If file is already located in the target folder, then the approach provided by Amit (https://stackoverflow.com/a/38810986/11912486) only removes file.

So, I suggest to use the following approach:

function move_file(file_id, target_folder_id) {
  var source_file = DriveApp.getFileById(file_id);
  var source_folder = source_file.getParents().next();
  if (source_folder.getId() != target_folder_id) {
    DriveApp.getFolderById(target_folder_id).addFile(source_file);
    source_folder.removeFile(source_file);
  }
}

can be improved by:

  • javascript camel style

  • multiple locations validation

Upvotes: 1

Aaron McKeehan
Aaron McKeehan

Reputation: 420

This is my first post! I know this has been answered a few times, but I actually came across this question while working on my project, and while reviewing the Apps Script documentation, I figured out a concise way to do it. A variation of some1's answer.

var file = DriveApp.getFileById(fileid);
DriveApp.getFolderById(folderid).addFile(file);
DriveApp.getRootFolder().removeFile(file);

Hope it helps!

Upvotes: 16

Alan Wells
Alan Wells

Reputation: 31300

This question has been answered, but here is a slightly different configuration:

function moveFile(parameterObject) {
  var currentFolderID,file,fileToMoveID,sourceFolder,targetFolder,targetFolderID;

  fileToMoveID = parameterObject.fileToMoveID;
  currentFolderID = parameterObject.currentFolderID;
  targetFolderID = parameterObject.targetFolderID;

  file = DriveApp.getFileById(fileToMoveID);//Get the file to move

  if (!file) {
    functionToHandleThisKindOfThing("there is no file");
    return;
  }

  if (currentFolderID) {//The folder ID holding the current file was passed in
    sourceFolder = DriveApp.getFolderById(currentFolderID);
  } else {//No ID for the current folder
    sourceFolder = file.getParents();
    if (sourceFolder) {
      if (sourceFolder.hasNext()) {
        sourceFolder = sourceFolder.next();
      }
    }
  }

  targetFolder = DriveApp.getFolderById(targetFolderID);

  targetFolder.addFile(file);
  sourceFolder.removeFile(file);
}

function testCode() {
  var o;

  o = {
    'fileToMoveID':"File ID of file to Move",
    "targetFolderID":"ID of folder to Move to"
  }

  moveFile(o);

}

Upvotes: 0

some1
some1

Reputation: 867

Try this:

var file = DriveApp.getFileById(newDoc.getId());
targetFolder.addFile(file);
//DriveApp.getFolderById('root').removeFile(file); // remove from root

Upvotes: 0

Related Questions