Как переместить папку на Google Диске с помощью скрипта Google Apps - PullRequest
1 голос
/ 06 августа 2020

РЕДАКТИРОВАТЬ

Я зарегистрировал проблему с помощью Google Issue Tracker по поводу того, что функция Folder.moveTo(destination) не работает, поскольку это, похоже, ошибка. Не стесняйтесь отмечать проблему звездочкой, чтобы повысить ее!

https://issuetracker.google.com/issues/163080678

Фон

Я пытаюсь предоставить способ перемещения папок на Google Диске одним щелчком мыши с помощью надстройки (которая появляется как на Диске, так и в Gmail). Для контекста, каждая «папка» в этом случае является вопросом, и «один щелчок» переместит папку (содержащую все соответствующие документы, относящиеся к этому вопросу) из «открытой» папки в «закрытую» папку. Однако я получаю сбивающие с толку и бесполезные ошибки каждый раз, когда пытаюсь добиться этого.

Примечание : все эти папки находятся на общем общем диске. Я знаю, что это накладывает некоторые ограничения на то, что могут делать DriveApp Service и Drive API, но я скрещиваю пальцы рук и ног, говоря, что это не просто врожденное ограничение и что существует обходной путь!

Я уже читал следующее:

Но они не решили мою проблему (отмечая, что addFile(), addFolder(), removeFile() и removeFolder() были устаревшими в последнее время и поэтому больше не доступны, как следует из ответов выше).

Ожидаемый результат

Я ожидаю, что когда пользователь нажмет кнопку «Закрыть» в надстройке, он переместит соответствующую папку (выбранную на предыдущем этапе в надстройке) из "открытая" папка в "закрытую" папку (которые находятся рядом друг с другом на одном уровне в иерархии папок). Для ясности, я надеюсь, что он переместит папку, а не дублирует ее в целевой папке, а затем удалит оригинал из исходной родительской папки.

Фактический результат

См. Конкретные сообщения об ошибках c ниже, но, вообще говоря, когда пользователь нажимает кнопку «Закрыть», я сразу получаю сообщение об ошибке, и с папкой ничего не происходит.

Попытка 1 - Folder.moveTo (назначение)

Взяв документацию Google по номинальной стоимости, я сначала попытался использовать Folder.moveTo(destination), как показано ниже:

function moveFolder() {
    var folderToMove = DriveApp.getFolderById(MOVE_FOLDER_ID);
    var destinationFolder = DriveApp.getFolderById(DESTINATION_FOLDER_ID);

    folderToMove.moveTo(destinationFolder);
}

Однако при запуске я получаю сообщение об ошибке: Exception: Unexpected error while getting the method or property moveTo on object DriveApp.Folder.

Попытка 2 - Drive.Files.update ()

Не сумев исправить вышеуказанное, я попробовал Advanced Drive , функция скрипта Google Apps, и попытка использовать Drive.Files.update() (документация здесь ). Мой код выглядит так:

function moveFolder() {
    Drive.Files.update({parents: [{id: DESTINATION_FOLDER_ID}]}, MOVE_FOLDER_ID);
}

Я также пробовал вариант, включающий необязательный параметр supportsAllDrives, как показано ниже:

function moveFolder() {
    Drive.Files.update({supportsAllDrives: true, parents: [{id: DESTINATION_FOLDER_ID}]}, MOVE_FOLDER_ID);
}

Однако оба варианта дают ошибку: GoogleJsonResponseException: API call to drive.files.update failed with error: File not found: [fileId], где [fileId] - это фактический идентификатор Google Диска для папки, которая перемещена .

Я подтвердил в обеих попытках 1 и 2, используя различные другие функции, которые, как я знаю, работают ( например, добавление свойств клиента с помощью Drive.Properties и переименование папки с помощью DriveApp), что сами папки определенно передаются правильно и ими можно управлять программно. Ie, папка определенно существует, и, используя URL-адрес в браузере, ее можно точно найти с использованием этого идентификатора диска.

Ответы [ 2 ]

1 голос
/ 07 августа 2020

Вместо того, чтобы перемещать папку напрямую, вы можете: а) создать «эквивалент» в новом месте на вашем общем диске, б) переместить его файлы в новую папку из a с помощью moveTo () и c) удалить оригинал папка после полной миграции. Это, конечно, изменит идентификатор ваших папок, но это работает для общих дисков, а также с папками из MyDrive, которые необходимо перенести на общий диск

Обратите внимание, что это использует Advanced Drive Service v2 (включите его в скрипте приложений):

// function to copy a folder e.g. to a shared drive
function copyFolderToSharedDrive(folderTitle,folderId,targetParentId) {  
  var optionalArgs={supportsAllDrives: true};
  var resource = {
    title: folderTitle + '_copy', // adjust according to your needs
    mimeType: 'application/vnd.google-apps.folder',
    parents:[{
      "id": targetParentId, // some folder in a shared drive
    }],
    description: folderId // optional, to back reference the source Folder
  }  
  
  var migratedFolder = Drive.Files.insert(resource, null, optionalArgs);
  Logger.log(migratedFolder.id);
  
  // Optional: post-process original folder, e.g. trash it
  // ...
}

Недостаток при переходе с «Мой диск» до тех пор, пока в «Мой диск» не будет применена одиночная родительская модель: вам необходимо проверить несколько «добавлений» ваших подпапок, чтобы избежать создания дублирующихся папок .

0 голосов
/ 08 августа 2020

Используя только методы DriveApp, вы также можете перенести папку,

  1. создав папку на общем диске
  2. переместив файлы в созданные папки
  3. рекурсивно для любые подпапки
  4. tra sh исходная папка, которая перемещается.

подсказка: если к подпапкам в переносимой папке применяется многопользовательский режим, вам необходимо включить проверьте приведенный выше код, чтобы избежать создания повторяющихся папок.

// execute this function
function run_me() {
  var folderId = 'ID_OF_FOLDER_TO_BE_MIGRATED'; // some folder (located in My Drive or Shared Drive)
  var targetParentId = 'ID_OF_TARGET_PARENT_FOLDER'; // a folder in a Shared Drive
  var folder = DriveApp.getFolderById(folderId);
  var parent = DriveApp.getFolderById(targetParentId);
  
  migrateFolderToSharedDrive(folder,parent); // copy folders and move files
  
  folder.setTrashed(true); // trash original folder
}

// main function (recursive)
function migrateFolderToSharedDrive(folder,parent) {
  var copiedFolder = parent.createFolder(folder.getName()).setDescription('previous Id: '+folder.getId());
  Logger.log('Folder created with id %s in parent %s',copiedFolder.getId(),parent.getId());
  
  // move files
  var files = folder.getFiles();
  while (files.hasNext()) {
    Logger.log('File with id %s moved to %s', files.next().moveTo(copiedFolder).getId(), copiedFolder.getId())
  }
  
  // recurse any subfolders 
  var childfolders = folder.getFolders();
  while (childfolders.hasNext()) {
    var child = childfolders.next();
    Logger.log('processing subfolder %s',child.getId());
    
    migrateFolderToSharedDrive(child,copiedFolder); // recursive call
  }
}
...