Search code examples
google-apps-scriptgoogle-sheetsgoogle-drive-apigoogle-apps

How to store values & avoid execution time limit on this Google Drive Script?


I have a permissions audit Google Script & a Google Sheet ready to store output as the script runs. How can I have the Script save entries to the Sheet as it processes while avoiding the execution time limit (5 or 6 minutes)?

The Google Drive I'm scanning is >6gb, so while I assume the script can be made more efficient, hitting the execution limit may be inevitable.

Google Script: /* ====================================== Who Can See Your Files in Google Drive ====================================== Written by Amit Agarwal on 01/11/2014
Tutorial :: http://labnol.org/?p=28237 */

function ScanGoogleDrive() {

  var files = DriveApp.getFiles();  
  var timezone = Session.getScriptTimeZone();
  var email = Session.getActiveUser().getEmail();

  var file, date, access, url, permission;
  var privacy, view, viewers, edit, editors;

  var rows = [["File Name", "Who has access?", "Date Created"]];

  while ( files.hasNext() ) {

    file = files.next();

    try {

      access     = file.getSharingAccess();
      permission = file.getSharingPermission();
      viewers    = file.getViewers();      
      editors    = file.getEditors();

      view = [];
      edit = [];

      date =  Utilities.formatDate(file.getDateCreated(), timezone, "yyyy-MM-dd HH:mm")
      url = '<a href="' + file.getUrl() + '">' + file.getName() + '</a>';

      for (var v=0; v<viewers.length; v++) {                
        view.push(viewers[v].getName() + " " + viewers[v].getEmail());
      }

      for (var ed=0; ed<editors.length; ed++) {                
        edit.push(editors[ed].getName() + " " + editors[ed].getEmail());
      }

      switch(access) {
        case DriveApp.Access.PRIVATE:
          privacy = "Private";
          break;
        case DriveApp.Access.ANYONE:
          privacy = "Anyone";
          break;
        case DriveApp.Access.ANYONE_WITH_LINK:
          privacy = "Anyone with a link";
          break;
        case DriveApp.Access.DOMAIN:
          privacy = "Anyone inside domain";
          break;
        case DriveApp.Access.DOMAIN_WITH_LINK:
          privacy = "Anyone inside domain who has the link";
          break;
        default:
          privacy = "Unknown";
      }

      switch(permission) {
        case DriveApp.Permission.COMMENT:
          permission = "can comment";
          break;
        case DriveApp.Permission.VIEW:
          permission = "can view";
          break;
        case DriveApp.Permission.EDIT:
          permission = "can edit";
          break;
        default:
          permission = "";
      }

      view = view.join(", ");

      edit = edit.join(", ");

      privacy += (permission === "" ? "" : " " + permission) 
               + (edit === "" ? "" : ", " + edit + " can edit")
               + (view === "" ? "" : ", " + view + " can view")

      rows.push([url, privacy, date]);

    } catch (e) {Logger.log(e.toString()); Logger.log(file.getName());};

  }

  var html = "<p>File Permissions Report for Google Drive</p>";

  html += "<table><tr><td><b>" + rows[0].join("</b></td><td><b>") + "</b></td></tr>";

  for (var i=1; i<rows.length; i++) {
    html += "<tr><td>" + rows[i].join("</td><td>") + "</td></tr>";
  }

  html += "</table><br>For help, refer to this <a href='http://www.labnol.org/internet/google-drive-access/28237/'>online tutorial</a> written by <a href='http://ctrlq.org/'>Amit Agarwal</a>.";

  MailApp.sendEmail(email, "Google Drive - File Permissions Report", "", {htmlBody: html});

}

Thank you!


Solution

  • Unfortunately, the limits are set by the Quotas for Google Services. All scripts that make use of any Google Service are bound to such limits. You can read more about it in the following link: https://developers.google.com/apps-script/guides/services/quotas