Google Apps Script - removeEditor/Viewer of single user from all files

Viewed 76

I would like to remove a single user's editor/viewer access for all files in my Google Drive. When I tried this, I get the error "No such user". When I logged getEditor, the only results were "[DriveUser]". Greatly appreciate any thoughts on how to solve this. Thank you.

function RemoveEditors(){ 

  const EDITOR = "mickey@mouse.com";

  var files = DriveApp.getFiles();
  while (files.hasNext()) {
    var file = files.next();
    file.removeEditor(EDITOR);
    }
}
1 Answers

In your script, how about the following modification?

Pattern 1:

In this pattern, your script is simply modified.

function RemoveEditors() {
  const EDITOR = "mickey@mouse.com";
  var files = DriveApp.getFiles();
  while (files.hasNext()) {
    var file = files.next();
    var editor = file.getEditors().find(e => e.getEmail() == EDITOR);
    if (editor) {
      file.removeEditor(EDITOR);
    }
  }
}

Pattern 2:

I thought that in the above modification, all files are required to be retrieved. In that case, the process cost might be high. So, in order to reduce the process cost of the script, in this pattern, the files with the editor of EDITOR are searched using the search query. And, the editor is removed.

function RemoveEditors() {
  const EDITOR = "mickey@mouse.com";
  var files = DriveApp.searchFiles(`'${EDITOR}' in writers and trashed=false`);
  while (files.hasNext()) {
    var file = files.next();
    file.removeEditor(EDITOR);
  }
}

Pattern 3:

In this pattern, Drive API is used. By this, I thought that when the number of files is large, the process cost might be reduced a little. When you use this script, please enable Drive API at Advanced Google services. And also, please install a Google Apps Script library of BatchRequest. Ref

function RemoveEditors() {
  const EDITOR = "mickey@mouse.com";

  const q = `'${EDITOR}' in writers and trashed=false`;
  let requests = [];
  let pageToken = "";
  do {
    const obj = Drive.Files.list({ q, fields: "nextPageToken,items(permissions(emailAddress,id,role),id)", maxResults: 1000, pageToken });
    if (obj.items.length > 0) {
      requests = [...requests, ...obj.items.flatMap(({ permissions, id }) => {
        const user = permissions.find(({ emailAddress, role }) => role == "writer" && emailAddress == EDITOR);
        if (user) {
          return {
            method: "DELETE",
            endpoint: `https://www.googleapis.com/drive/v3/files/${id}/permissions/${user.id}`,
          };
        }
        return [];
      })];
    }
    pageToken = obj.nextPageToken;
  } while (pageToken);
  if (requests.length == 0) return;
  var result = BatchRequest.EDo({ batchPath: "batch/drive/v3", requests });
}

References:

Added:

For example, when the above pattern 2 is used and an error at file.removeEditor(EDITOR) is avoided, how about the following sample script?

Sample 1:

function RemoveEditors() {
  const EDITOR = "mickey@mouse.com";
  var yourEmail = "###your email address###"; // Please set your email address.

  var files = DriveApp.searchFiles(`'${EDITOR}' in writers and trashed=false and '${yourEmail}' in owners`);
  while (files.hasNext()) {
    var file = files.next();
    file.removeEditor(EDITOR);
  }
}
  • From your reply, I'm worried that you might have no permission for removing the editors of the file. So, in this modification, the files, that you are the owner, are used.

Sample 2:

function RemoveEditors() {
  const EDITOR = "mickey@mouse.com";
  var files = DriveApp.searchFiles(`'${EDITOR}' in writers and trashed=false`);
  while (files.hasNext()) {
    var file = files.next();
    try {
      file.removeEditor(EDITOR);
    } catch(e) {
      console.log(`Error message: ${e.message}, Error file: ${file.getId()}`);
    }
  }
}
  • In this modification, when an error occurs at file.removeEditor(EDITOR), the error is skipped by try-catch. And, about the file that an error occurs, the error message and the file ID are shown in the log. By this, I thought that the reason for the issue might be found.
Related