Search code examples
google-apps-scripttriggersgoogle-drive-api

Google Apps Script trigger - run whenever a new file is added to a folder


I want to execute a google apps script whenever a new file is added to a specific folder.

Currently I'm using a run-every-x-minutes clock trigger, but I only need to run the script whenever I add a file to a folder. Is there a way to do this?

The same as this question - which is now almost 3 years old. The comment below the question states that:

There's not a trigger for that, if that's what you're hoping. How are things getting into the folder, and do you have any control over that? – Jesse Scherer Apr 8 '18 at 3:02

I wonder if this comment is still valid, and if it is, then if there's a workaround.


Solution

  • Issue:

    Unfortunately, the comment you read is still true. Here is a list of all the available triggers and a trigger for a new file added to a folder is not one of them.

    Workaround / Explanation:

    I can offer you a workaround which is usually used by developers when they built their add-ons. You can take advantage of the PropertiesService class. The logic is quite simple.

    1. You will store key-value pairs scoped to the script:

    In your case, the key will be the folder id, and the value will be the number of files under this folder.

    1. You will setup a time-driven trigger to execute mainFunction for example every one minute.

    2. The script will count the current number of files within the selected folder. The function responsible for that is countFiles.

    3. The checkProperty function is responsible for checking if the current number of files under this folder matches the old number of files. If there is a match, meaning no files were added, then checkProperty returns false, otherwise return true and update the property for the current folder ID, so when the script runs after 1 minute, it will compare with the fresh value.

    4. If checkProperty returns true, then execute the desired code.

    Code snippet:

    Set up a time-driven trigger for mainFunction. Whatever code you put inside the brackets of the if(runCode) statement will be executed if the number of files under the folderID has changed.

    function mainFunction(){
      const folderID = 'folderID'; //provide here the ID of the folder
      const newCounter = countFiles(folderID);
      const runCode = checkProperty(folderID, newCounter);
      
      if(runCode){
       // here execute your main code
       // 
        console.log("I am executed!");
       //
      }
    }
    

    And here are the helper functions which need to be in the same project (you can put them in the same script or different scripts but in the same "script editor").

    function countFiles(folderID) {
      const theFolder = DriveApp.getFolderById(folderID);
      const files = theFolder.getFiles();
      let count = 0;
      while (files.hasNext()) {
       let file = files.next();
       count++;
       };
      return count;
    }
    
    
    function checkProperty(folderID, newC){
      const scriptProperties = PropertiesService.getScriptProperties();
      const oldCounter = scriptProperties.getProperty(folderID);
      const newCounter = newC.toString();
      if(oldCounter){
        if(oldCounter==newCounter){
          return false;
        }
        else{
          scriptProperties.setProperty(folderID, newCounter);  
          return true;
        }
      }
      else{
         scriptProperties.setProperty(folderID, newCounter);  
         return true;
      }
    }