2

My goal is to create a trigger time base in Google App Script to run a function every 15 minutes starting from a specific minute, example: 11:01 - 11:16 - 11:31 - 11:46 --> so starting point 11:01 and then every 15 minutes, every day.

I know that this is not a new problem but I've searched a lot and I've found only these answers:

It's possible run Google Sheets script Exact Time Everyday?

Run a Gmail Google Apps Script daily at 8:00, 12:30, 17:00

https://github.com/davidtheweiss/Apps-Script-Season-3-Script-Service/blob/master/Episode%201.1.gs

Unfortunatelly none of them works, in particular my try was:

function setTrigger() {

deleteTriggers();  
var times = [[11,01],[11,16],[11,31],[11,46],[12,01],[12,16],[12,31],[12,46],[13,01],[13,16],
[13,31],[13,46],[14,01],[14,16],[14,31],[14,46],[15,01],[15,16],[15,31],[15,46],[16,01],[16,16],
[16,31],[16,46],[17,01],[17,16],[17,31],[17,46],[18,01],
[18,16],[18,31],[18,46],[19,01],[19,16],[19,31],[19,46],[20,01],[20,16],
[20,31],[20,46],[21,01][10,36],[10,46],[11,01],[11,16],[11,31],[11,46],[12,01]]; // 9:30 am, 9:45 am, 10:00 am 12:00pm
times.forEach(t_el => scheduledTrigger(t_el[0],t_el[1]));
}

function scheduledTrigger(hours,minutes){
  
var today_D = new Date();  
var year = today_D.getFullYear();
var month = today_D.getMonth();
var day = today_D.getDate();
  
pars = [year,month,day,hours,minutes];
  
var scheduled_D = new Date(...pars);
var hours_remain=Math.abs(scheduled_D - today_D) / 36e5;
ScriptApp.newTrigger("function_Triggered")
.timeBased()
.after(hours_remain * 60 *60 * 1000)
.create()
}

function deleteTriggers() {
  
var triggers = ScriptApp.getProjectTriggers();
for (var i = 0; i < triggers.length; i++) {
  if (   triggers[i].getHandlerFunction() == "function_Triggered") {
    ScriptApp.deleteTrigger(triggers[i]);
  }
}
}

function function_Triggered() {
 // your function code here
}

But the problem is that it creates way too much triggers at the same time and it gives me error for this reason

3 Answers3

3

If you do not care about trigger precision (+- 1 minute of desired time or so): use everyMinutes(n) trigger and inside callback function check which minute it is:

  • if not minute you need, skip execution
  • if exact minute you need - do your thing

If you DO care about precision (like it should be exact minute you need and not previous or next) in your case Apps Script is not helpful at all, you may want to use some workaround, for example:

  1. Set up some simple Node.js App Engine cron job (which will have great precision).
  2. Inside cron function call your Apps Script (deployed as Web App).

This will allow you to have your Apps Script function executed at exact time you need.

Kos
  • 4,890
  • 9
  • 38
  • 42
  • That's an interesting point, with this methos you force the trigger by calling it from another service! Thank your for the feedback – marcoversus Aug 02 '21 at 11:05
  • You definitely can use Google Apps Script to trigger a function at the exact minute you want - see [this answer](https://stackoverflow.com/a/76350865/3059685) for how. – Joman68 Jun 04 '23 at 10:49
2

Try this : create a function that will test date, hour and minute. Then include the result in your own function on which you apply a trigger "every minute"

//put a trigger every minute
function function_Triggered(){
  if (testDateHour()==true) {
    // here is your script
  }
}
function testDateHour(){
  var d = new Date();
  // not on sunday and saturday and between 10am and 4pm each 15mn
  if (d.getDay()!=0 && d.getDay()!=6 && d.getHours()>=10 && d.getHours()<=16 && d.getMinutes()%15==1) {return true}else{return false}
}
Mike Steelson
  • 14,650
  • 2
  • 5
  • 20
1

There are 2 ways to do it (actually the same logic):

Method A: Create a every 15 minute trigger, which create a trigger of function_Triggered in (every) nearest 15 minute.

Method B: Include a trigger create function in function_Triggered, which create trigger of function_Triggered in (next) nearest 15 minute.

Reference:

timeBased().at(date)


function function_Triggered() {
  try { /* ... */ }
  catch(e) { /* ... */ }
  finally { setTrigger('function_Triggered', 15); }
}

function setTrigger(funcName, min) {
  deleteTrigger(funcName);
  let date = new Date();
  const diff = 1000 * 60 * min;
  date = new Date(Math.floor(date.getTime() / diff + 1) * diff);
  ScriptApp.newTrigger(funcName).timeBased().at(date).create();
}

function deleteTrigger(funcName) {
  const triggers = ScriptApp.getProjectTriggers();
  for (const trigger of triggers) {
    if (trigger.getHandlerFunction() === funcName) {
      ScriptApp.deleteTrigger(trigger);
    }
  }
}
idfurw
  • 5,727
  • 2
  • 5
  • 18
  • I think I haven't understood completely your answer, in both way I think I won't have the triggers to start at a specific time, right? Could you please provide me some examples? Thank you very much – marcoversus Aug 02 '21 at 09:40
  • Time is specified in `timeBased().at(date)` – idfurw Aug 02 '21 at 09:46