关于谷歌表格:如何使用基于时间的触发器每小时运行一个脚本,仅在工作日的每小时运行一次?

How to run a script every hour, on the hour only on weekdays using time-based trigger?

我需要仅在工作日的整点每小时运行一次 Google App Script 脚本。

这两种方法中的一种似乎很容易,但将其结合起来我不确定...

每小时触发:
ScriptApp.newTrigger("RefreshRates").timeBased().inTimezone("GMT").everyHours(1).nearMinute(0).create();

它需要尽可能接近每小时运行一次。
因此,例如 09:00、10:00、11:00 等。我知道 App Script 对此不太准确,但尽可能接近时间。

我发现这可能有助于解决工作日问题,但是否可以将上述内容与以下内容结合起来:

1
2
3
4
5
6
7
8
9
10
 function createWeeklyTrigger() {
    var days = [ScriptApp.WeekDay.MONDAY, ScriptApp.WeekDay.TUESDAY,
                ScriptApp.WeekDay.WEDNESDAY, ScriptApp.WeekDay.THURSDAY,                                            
                ScriptApp.WeekDay.FRIDAY];
    for (var i=0; i<days.length; i++) {
       ScriptApp.newTrigger("your_function_name")
                .timeBased().onWeekDay(days[i])
                .atHour(11).create();
    }
 }

理想的时间是格林威治标准时间周五晚上 9:45 到周日晚上 10:15,此时外汇市场收市和开市...

编辑:
我想我在最初的问题中对每个工作日的每个小时都做了一些不太清楚的事情,而不是特定的时间。但市场的一周从格林威治标准时间周日 22:00 开始,到格林威治标准时间周五 22:00 结束。因此,理想的时间是从格林威治标准时间周日 22:00 到格林威治标准时间周五 22:00 整点整点……


我认为,您最好的选择是将 Trigger 设置为您希望脚本运行的每个小时,在设置工作日的循环中使用第二个循环,因为 everyHours() 不接受开始和结束参数.

请注意,这将创建在一周的同一天触发的单独触发器。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function setWeekdaysTrigger() {

  var startHour = 9;
  var endHour   = 13;
  var daysWeek  = []; //put Enums for days of the week here;

  //set trigger to specific week days;
  daysWeek.forEach(function(day){
    //set trigger for 9AM to 13PM;
    for(var h=startHour; h<endHour; h++) {
      var tg = ScriptApp.newTrigger('doSomething').timeBased();
          tg.onWeekDay(day);
          tg.atHour(h).nearMinute(15).create(); //arbitrary precision (minutes);
    }        
  });

}

作为答案的更新 - 请注意,不幸的是,您可以代表一个用户为项目创建多少触发器(目前等于每个项目每个用户 20 个)是有配额的。

可配置的触发器

正如评论中所阐明的,配置自定义日期自定义时间触发器需要更复杂的处理。建议的解决方案(不计算显式日期时间检查)是动态触发器配置(因为由于重复重复而无法同时设置 onWeekDay(day) everyHours(n) [我发现 onWeekDay(day) 设置了隐式 everyWeeks(1) 重复模式]):

首先,创建一个设置天数重复的主触发函数

1
2
3
4
5
6
7
8
9
10
11
12
function custom24trigger() {
  var days  = [ScriptApp.WeekDay.TUESDAY]; //put Enum values here;

  //create trigger for each date (arbitrary hours);
  days.forEach(function(day){
    for(var offset = 0; offset < 23; offset=offset+4) { //every 4 hours;
      var tg = ScriptApp.newTrigger('changeTriggers').timeBased();
          tg.onWeekDay(day).atHour(offset).create(); //change every N hours;
    }
  });

}

其次,创建一个触发器更改函数,该函数将通过设置重复触发,清除之前设置的触发器并创建新的触发器:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
function changeTriggers() {
  var triggers   = ScriptApp.getProjectTriggers(); //get project's triggers;
  var props      = PropertiesService.getScriptProperties(); //get script properties store;
  var triggerIds = props.getProperty('triggerIds'); //get arbitrary property to set Ids to;

  //if ids are not empty, split into Array of Ids, else set up empty Array;
  if(triggerIds!==null) { triggerIds = triggerIds.split(','); }else { triggerIds = []; }

  //loop over triggers and delete saved;
  triggerIds.forEach(function(id){
    triggers.forEach(function(trigger){
      if(trigger.getUniqueId() == id) {
        ScriptApp.deleteTrigger(trigger);
      }
    });
  });

  var today = new Date(); //current date;
  var start = today.getHours(); //current hour;

  var stop = start+3; //hour to stop (sets N triggers);

  //create hourly trigger for each hour;
  var newId = '';
  for(var h = start; h < stop; h++) {
    var trg = ScriptApp.newTrigger('doSomething').timeBased();

    //make trigger fire once at specific date and hour;
    today.setHours(h);
    today.setMinutes(0);

    var created = trg.at(today).create();  
    newId += ','+created.getUniqueId(); //get new trigger Id;
  }

  props.setProperty('triggerIds', newId); //set trigger property;
}