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

2

5

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.

Swaddle answered 26/1, 2021 at 13:1 Comment(2)
The Drive REST API supports push notifications which allow you to track events such as when a new file is added to a Google Drive folder. Unfortunately, this feature is not accessible from Apps Script for numerous reasons. But its possible to create a intermediary service in another language/platform and have Apps script call out to it. Not trivial to implement but viable.Congo
Many thanks @Congo for this suggestionSwaddle
W
11

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;
  }
}
Wolters answered 26/1, 2021 at 14:12 Comment(6)
Great answer - I'd give more than 1 upvote if I could!Swaddle
@Andy thanks already for your support. Glad the answer was helpful to you :)Wolters
@soMarios I don't understand how oldCounter and newCounter could have different values because they will be called by the same trigger and in countFiles() the counter is reset to 0 everytime it is called.Salomie
Is it because the quantity of files is being stored with scriptProperties.setProperty(folderID, newCounter)?Salomie
What happens when more than 1 file is added to the folder at the same time or within a minute (if using a time trigger)?Salomie
The frequency of the refresh is determined by you. The amount of files you add between the refreshes is irrelevant to the code.Wolters
T
1

here is my solution for this. It is based on Mario's answer. It will run once a day at 9AM and check the folder for new files:

// "MyFolder" in Google Drive
const folderID = "1KhHwTI6bKDKxWVextm6E9h84_lA8Q"


function sendNotificationIfNeeded() {
// skip week-end
var dayIndex = new Date().getDay()
if (dayIndex == 0 || dayIndex == 6) {
  return
}


if (hasNewFiles()) {
  console.log("sending Firebase Message")
  } 
}


function hasNewFiles() {
   const scriptProperties = PropertiesService.getScriptProperties()
   const newCount = countFiles(folderID)
   const oldCount = parseInt(scriptProperties.getProperty(folderID)) || 0
   if (newCount != oldCount) {
   // save the new count
   scriptProperties.setProperty(folderID, newCount)
   }
  // TODO the PDF index rather than the files count
  return newCount > oldCount
 }


function countFiles() {
  const files = DriveApp.getFolderById(folderID).getFiles()
  var count = 0
  while (files.hasNext()) {
   files.next()
   count++
  }
 return count
}


function createTimeDrivenTriggers() {
  ScriptApp.newTrigger('sendNotificationIfNeeded')
   .timeBased()
   // .everyMinutes(5)
   .everyDays(1)
   .atHour(9)
   .create()
  }


  function deleteAllTriggers() {
    ScriptApp.getProjectTriggers().forEach(function (trigger) {
    ScriptApp.deleteTrigger(trigger)
   })
  }
Thud answered 8/6, 2023 at 15:28 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.