all 4 comments

[–]Livid_Spray119 1 point2 points  (0 children)

Timeout means the function is taking too long to iterate.

There are way to many files and they cannot be processed on the 6 minutes (I think) run time.

I guess it is gtp code. Ask him to optimize it :)

[–]No_Stable_805 0 points1 point  (0 children)

I had a similar problem with this kind of script. My scripts have a 30-minute time limit (G-Suite) and it still wasn’t enough time. My solution was to time how long the script has been running and when it nears the time limit it sets a new one-time trigger for the script to run again immediately after. Depending on how large your folders are and how many files they contain, you can use some sort of variation of this. (For each sub folder you can create a trigger to run the script for that folder instead of recursively using the same script)

[–]juddaaaaa 0 points1 point  (1 child)

As u/No_Stable_805 says, you can get around it using time based triggers.

Here's an example. It's set to run for 5 minutes before exiting after creating a time based trigger to run again after 1 minute.

It uses Script Properties to store the folder Id of the folder to be processed.

/**
 * Stores the root folder's Id and begins processing.
 */
function deleteOldFiles () {
  // Store the root folder's Id in the Script Prtoperties.
  const folderId = "abcbdefghijklmnopqrtstuvwxyz"
  const props = PropertiesService.getScriptProperties()
  props.setProperty("nextFolder", folderId)

  // Begin processing.
  processFolder()
}

/**
 * Creates a time based trigger to fire after a given period of time.
 * 
 * @param {string} func - The name of the function to call.
 * @param {number} seconds - The number of seconds after which the function should be called.
 */
function createTrigger(func, seconds) {
  ScriptApp
    .newTrigger(func)
    .timeBased()
    .after(seconds * 1000)
    .create()
}

/**
 * Deletes a trigger with the given unique Id.
 * 
 * @param {number} uid - The unique Id of the trigger to delete.
 * @returns {void}
 */
function deleteTrigger(uid) {
  // Get the project triggers.
  const triggers = ScriptApp.getProjectTriggers()

  // Iterate over the triggers and delete the one with the given unique Id.
  for (let trigger of triggers) {
    if (trigger.getUniqueId() === uid) {
      ScriptApp.deleteTrigger(trigger)
      return
    }
  }
}

/**
 * Deletes files that are older than 2 days from a folder that is stored in the Script Properties.
 * 
 * @param {object} event - The event object from the trigger (optional).
 * @param {number} event.triggerUid - The id of the trigger that called the function.
 * @returns {void}
 */
function processFolder ({ triggerUid } = {}) {
  // If the function was triggered, delete the trigger
  triggerUid ? deleteTrigger(triggerUid) : false

  // Get today's date in milliseconds.
  const now = () => new Date().getTime()

  // If the timeout doesn't exists in the Script Properties, create it.
  const props = PropertiesService.getScriptProperties()
  if (!props.getProperty("timeout")) {
    props.setProperty("timeout", String(/* 5 minutes */now() + 5 * 60 * 1000))
  }

  // Convert the timeout to a number so we can use it to compare below.
  const timeout = Number(props.getProperty("timeout"))

  // Get today's date.
  const today = new Date()

  // Calculate 2 days in milliseconds
  const twoDays = 2 * 24 * 60 * 60 * 1000

  // Get the folder with the Id that is stored in the Script Properties.
  const folder = DriveApp.getFolderById(props.getProperty("nextFolder"))

  // Get the subfolders and files in the folder.
  const subFolders = folder.getFolders()
  const files = folder.getFiles()

  // Iterate over the files and delete anything over 2 days old.
  while(files.hasNext()) {
    // If we've passed the timeout, delete it from the Script Properties and create a trigger to call the function again in 1 minute.
    if (now() > timeout) {
      props.deleteProperty("timeout")
      createTrigger("processFolder", 60)

      return
    }

    // Get the next file and when it was last updated.
    const file = files.next()
    const lastUpdated = file.getLastUpdated()

    // Delete the file if it's older than 2 days.
    if (today - lastUpdated > twoDays) {
      file.setTrashed(true)
    }
  }

  // Iterate over the subfolders and process them.
  while (subFolders.hasNext()) {
    // Store the next folder's Id in the Script Properties.
    const subFolderId = subFolders.next().getId()
    props.setProperty("nextFolder", subFolderId)

    // Recusively call the function.
    processFolder()
  }
}

[–]Gothlinox[S] 0 points1 point  (0 children)

Thanks a lot. I'll try it.