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

Viewed 3490

I need to run a Google Apps script three times a day: at 8:00, 12:30, 17:00.

How to do this?

I have already looked at Triggers, and more specifically Time driven:

  • Hour timer, but Every hour, Every 2 hours, Every 4 hours are not adapted here

  • Day timer, but then 8am to 9am is not very precise, I would prefer something more precise, and also 12:30 is not possible

  • Specific time, but then YYYY-MM-DD HH:MM is not adapted to run it daily

From calendar triggers does not seem adapted either.

3 Answers

Use nearMinute() and atHour():

const createTrigger = ([hour, minute])=>
  ScriptApp.newTrigger("myFunction")
  .timeBased()
  .atHour(hour)
  .nearMinute(minute)  
  .everyDays(1) 
  .create();

[[8,0],[12,30],[17,0]].forEach(createTrigger)

Although the TheMaster's answer is correct I would like to elaborate a little bit on an alternative approach which might be useful for future readers and different projects.

Let's say you have a list of specific times (24H:mm) you want to schedule every day:

var times = [[9,30],[9,45],[10,00],[12,00]] // 9:30 am, 9:45 am, 10:00 am 12:00pm

which can be completely random, following any sequence you like.

As you can see in the code below, you can run the setTrigger() function , to generate a scheduled trigger of another function function_Triggered() for each element in the aforementioned list. The trigger will have the time provided in times and the date of today.

If you want to perform this task everyday, then you just need to create a daily trigger for setTrigger() and run it before the earliest time in times. In this case, you are generating triggers everyday, and therefore deleteTriggers() is used to delete the previous (disabled) triggers for function_Triggered() that are attached to your project.

function setTrigger() {

deleteTriggers();  
var times = [[9,30],[9,45],[10,00],[12,00]]; // 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
}

soMario and TheMaster have working solutions, but unfortunately for my use case I needed some tighter tolerances than the + or - 15 minutes!! Which the google app script scheduler 'works' upon.

I used their very inaccurate scheduler to run the below function every 5 minutes. This function will check current time very accurately, it seems so far, and only run the next 'core' function within your desired hours and minutes. A simple if condition addition, using getDay() will add a day of week 'filter'.

function timeCheck() {
  var nowH=new Date().getHours();
  var nowM=new Date().getMinutes();
  Logger.log('Hour: '+nowH+'  Minute: '+nowM)

  if (nowH = 1 && nowM < 12) { getStatus() }
  if (nowH = 10 && (nowM > 15 && nowM < 27)) { getStatus() }

  return
}
Related