访问不属于我的 Google 个共享云端硬盘中的文件

Access files in Google Shared Drive not owned by me

我正在尝试使用 Google 驱动器中的 Apps 脚本来搜索公司共享驱动器中的图像文件。文件列表保存在电子表格中,脚本搜索并复制文件(如果它已经是 jpg 或 png 文件)或导出 png 文件(如果它是 google 绘图。

这是我目前的代码...

function load_list_of_images(course_workbook) {
  var image_list_sheet = course_workbook.getSheetByName("image_list");
  // Get list of image names from spreadsheet
  var list_of_images = [];
  var images = image_list_sheet.getRange(1,1,1000).getValues();
  for (var row in images) {
    for (var col in images[row]) {
      var image = images[row][col];
      if (image == "") {
        return(list_of_images);
      }
      list_of_images.push(image);
    }
  }
}

function download_google_images() {
  var course_workbook_name = "NAME"; // Title of spreadsheet with file list
  var dst_folder_id = "FOLDER_ID"; // ID of destination folder

  // There may be more than one!
  var course_workbooks = DriveApp.getFilesByName(course_workbook_name);
  // Try to access the spreadsheet
  try{
    var course_workbook_id = course_workbooks.next();
    Logger.log("Spreadsheet ID : " + course_workbook_id);    
  } catch(error) {
    Logger.log("Spreadsheet doesn't exist... exiting...");
    return(null);
  }
  var course_workbook = SpreadsheetApp.open(course_workbook_id);
  var list = load_list_of_images(course_workbook);
  // This will hold a list of missing images
  var missing = [];
  // What if the list is empty?
  if (list == null){
    Logger.log("Errr... no images to find - check the sheet!");
    return(null);
  }
  // Set up handle to destination folder
  var dst_folder = DriveApp.getFolderById(dst_folder_id);

  // Now look for each image in the list
  for (var row in list){
    // Get the name of the image to look for
    var image_name = list[row];
    Logger.log("Looking for : " + image_name);
    // Get all the files which match this name
    // This line ONLY finds images that are owned by me
    // MOST of the images are owned by other users
    var image_exists = DriveApp.getFilesByName(image_name);
    // The list of images is empty
    if (!image_exists.hasNext()){
      Logger.log("  Can't find image : " + image_name);
      missing.push([image_name]);
    }
    // I found some images!
    else{
      while (image_exists.hasNext()){
        var image = image_exists.next()
        var drive_mime_type = image.getMimeType();
        // I'll tell you which type of file I've found
        Logger.log("  I've found a '" + drive_mime_type + "' file.");
        // Deal with file types
        switch (drive_mime_type) {
          // Existing JPG file
          case "image/jpeg":
            var already_exists = DriveApp.getFolderById(dst_folder_id).getFilesByName(image_name);
            if (!already_exists.hasNext()){
              Logger.log("  Creating image : " + image_name);          
              var copy = image.makeCopy(dst_folder);
            }
            else{
              Logger.log("  It's already in the destination so I won't create another one.");
            }
            break;
          // Existing PNG file
          case "image/png":
            var already_exists = DriveApp.getFolderById(dst_folder_id).getFilesByName(image_name);
            if (!already_exists.hasNext()){
              Logger.log("  Creating image : " + image_name);
              var copy = image.makeCopy(dst_folder);
            }
            else{
              Logger.log("  It's already in the destination so I won't create another one.");
            }
            break;
          // Google drawing - Convert to PNG!
          case "application/vnd.google-apps.drawing":
            var exportUrl = "https://www.googleapis.com/drive/v3/files/" + image.getId() + "/export?mimeType=image/png";
            var urlFetchOptions = {
              headers: {Authorization : "Bearer " + ScriptApp.getOAuthToken()}
            }
            try{
              var blob = UrlFetchApp.fetch(exportUrl, urlFetchOptions).getBlob();
            }
            catch(err){
              Logger.log("  There is an error getting the image : " + image_name);
              Logger.log(err);
              return(null);
            }
            var already_exists = DriveApp.getFolderById(dst_folder_id).getFilesByName(image_name + ".png");
            if (!already_exists.hasNext()){
              Logger.log("  Creating image : " + image_name);
              DriveApp.getFolderById(dst_folder_id).createFile(blob).setName(image_name + ".png");
            }
            else {
              Logger.log("  There is already a png version in the destination so I won't create another one.");
            }
            break;
          }
      } 
    }
  }
  // Populate the missing images list
  var missing_images_sheet = course_workbook.getSheetByName("missing_images");
  missing_images_sheet.getRange(1,1,1000).clear();
  var missing_images_range = missing_images_sheet.getRange(1,1,missing.length);
  missing_images_range.setValues(missing);
}

所有图像文件都在共享 Google 驱动器中。我是所有驱动器的正式成员。目前的行为是只有 我拥有的文件 从共享驱动器中找到并复制到目标文件夹中,而大多数图像是由驱动器的另一个用户创建的。

如何更改脚本以便它找到任何人拥有的文件?

带有脚本的 appscript.json 文件如下所示...

{
  "timeZone": "Europe/London",
  "dependencies": {
    "enabledAdvancedServices": []
  },
  "oauthScopes": [
    "https://www.googleapis.com/auth/drive.readonly",
    "https://www.googleapis.com/auth/drive",
    "https://www.googleapis.com/auth/drive.file",
    "https://www.googleapis.com/auth/spreadsheets",
    "https://www.googleapis.com/auth/script.external_request",
    "https://www.googleapis.com/auth/drive.metadata"
  ],
  "exceptionLogging": "STACKDRIVER",
  "runtimeVersion": "V8"
}

感谢您的帮助!

在那种情况下,使用 Drive API 代替 Drive 服务怎么样?当你的脚本修改后,变成如下。

主要修改如下

发件人:

var image_exists = DriveApp.getFilesByName(image_name);

收件人:

var image_exists = Drive.Files.list({corpora: "drive", driveId: "###DriveID###", includeItemsFromAllDrives: true, supportsAllDrives: true, maxResults: 1000, q: `title='${image_name}'`}).items;

修改后的脚本:

这种情况下,请修改download_google_images()如下。请将共享驱动器的驱动器 ID 设置为 ###DriveID### of var image_exists = Drive.Files.list({corpora: "drive", driveId: "###DriveID###", includeItemsFromAllDrives: true, supportsAllDrives: true, maxResults: 1000, q: title='${image_name}'}).items;。还有 please enable Drive API at Advanced Google services.

function download_google_images() {
  var course_workbook_name = "NAME"; // Title of spreadsheet with file list
  var dst_folder_id = "FOLDER_ID"; // ID of destination folder

  // There may be more than one!
  var course_workbooks = DriveApp.getFilesByName(course_workbook_name);
  // Try to access the spreadsheet
  try{
    var course_workbook_id = course_workbooks.next();
    Logger.log("Spreadsheet ID : " + course_workbook_id);    
  } catch(error) {
    Logger.log("Spreadsheet doesn't exist... exiting...");
    return(null);
  }
  var course_workbook = SpreadsheetApp.open(course_workbook_id);
  var list = load_list_of_images(course_workbook);
  // This will hold a list of missing images
  var missing = [];
  // What if the list is empty?
  if (list == null){
    Logger.log("Errr... no images to find - check the sheet!");
    return(null);
  }
  // Set up handle to destination folder
  var dst_folder = DriveApp.getFolderById(dst_folder_id);

  // Now look for each image in the list
  for (var row in list){
    // Get the name of the image to look for
    var image_name = list[row];
    Logger.log("Looking for : " + image_name);
    // Get all the files which match this name
    // This line ONLY finds images that are owned by me
    // MOST of the images are owned by other users

    var image_exists = Drive.Files.list({corpora: "drive", driveId: "###DriveID###", includeItemsFromAllDrives: true, supportsAllDrives: true, maxResults: 1000, q: `title='${image_name}'`}).items;  // <--- Modified

    // The list of images is empty
    if (image_exists.length == 0) {  // <--- Modified
      Logger.log("  Can't find image : " + image_name);
      missing.push([image_name]);
    }
    // I found some images!
    else {
      image_exists.forEach(e => {  // <--- Modified
        var image = DriveApp.getFileById(e.id);  // <--- Modified
        var drive_mime_type = image.getMimeType();
        // I'll tell you which type of file I've found
        Logger.log("  I've found a '" + drive_mime_type + "' file.");
        // Deal with file types
        switch (drive_mime_type) {
          // Existing JPG file
          case "image/jpeg":
            var already_exists = DriveApp.getFolderById(dst_folder_id).getFilesByName(image_name);
            if (!already_exists.hasNext()) {
              Logger.log("  Creating image : " + image_name);
              var copy = image.makeCopy(dst_folder);
            }
            else {
              Logger.log("  It's already in the destination so I won't create another one.");
            }
            break;
          // Existing PNG file
          case "image/png":
            var already_exists = DriveApp.getFolderById(dst_folder_id).getFilesByName(image_name);
            if (!already_exists.hasNext()) {
              Logger.log("  Creating image : " + image_name);
              var copy = image.makeCopy(dst_folder);
            }
            else {
              Logger.log("  It's already in the destination so I won't create another one.");
            }
            break;
          // Google drawing - Convert to PNG!
          case "application/vnd.google-apps.drawing":
            var exportUrl = "https://www.googleapis.com/drive/v3/files/" + image.getId() + "/export?mimeType=image/png";
            var urlFetchOptions = {
              headers: { Authorization: "Bearer " + ScriptApp.getOAuthToken() }
            }
            try {
              var blob = UrlFetchApp.fetch(exportUrl, urlFetchOptions).getBlob();
            }
            catch (err) {
              Logger.log("  There is an error getting the image : " + image_name);
              Logger.log(err);
              return (null);
            }
            var already_exists = DriveApp.getFolderById(dst_folder_id).getFilesByName(image_name + ".png");
            if (!already_exists.hasNext()) {
              Logger.log("  Creating image : " + image_name);
              DriveApp.getFolderById(dst_folder_id).createFile(blob).setName(image_name + ".png");
            }
            else {
              Logger.log("  There is already a png version in the destination so I won't create another one.");
            }
            break;
        }
      });  // <--- Modified
    }
  }
  // Populate the missing images list
  var missing_images_sheet = course_workbook.getSheetByName("missing_images");
  missing_images_sheet.getRange(1,1,1000).clear();
  var missing_images_range = missing_images_sheet.getRange(1,1,missing.length);
  missing_images_range.setValues(missing);
}

注:

  • 在这种情况下,当您没有reader的权限或共享驱动器的编写者时,将无法使用上述修改后的脚本。所以请注意这一点。
  • 在当前阶段,似乎无法使用 DriveApp.getFilesByName(filename) 和文件名来检索共享云端硬盘中的文件。另一方面,当使用文件 ID 时,DriveApp.getFileById(fileId) returns 来自共享驱动器的文件对象。基于这种情况,我建议使用files.list in Drive API 的方法从文件名中检索文件元数据。这是来自 .

参考: