LANG SELRCT

コードを書く場所についてはこちら

2018年4月8日日曜日

毎日特定の日時ちょうどに実行するトリガーを作る


今回やること
毎日12:55に自分宛てにメールを送信する


それを実現するためにやること
  • 毎日11時〜12時に定期実行するトリガーを登録しておく
  • そのトリガーの関数内で、当日の12:55に実行するトリガーを登録する

時系列でみると
時系列
実行するトリガー
実行する処理
11時
add_temp_trigger
既存のsend_mailトリガーを削除
新規のsend_mailトリガーを登録
12時
12:55
send_mail
メールが送信される



実際に登録するトリガーを見るとこうなる



前提知識:GASのトリガーで実現できること
  • 「日タイマー」を設定すると毎日X時〜Y時の間に特定の関数を実行できる
  • 「特定の日時」で2018-04-08 12:55などを設定するとその日時に実行できる
  • ひとつのトリガーで「日タイマー」と「特定の日時」を同時に使うことはできない

やりたいこと:毎日12:55に特定の関数を実行したい
手順を書き出してみる
  1. まず実行したい関数を書く
  2. 「特定の日時」を指定して手順1の関数をトリガーに登録する
  3. 指定した日時にコードが自動で実行される
  4. 手順2で登録したトリガーは実行後も残っているので削除する
  5. 手順2と4を毎日繰り返す

手順5を自動化したい
  • 毎日「特定の日時」に実行する関数を自動でトリガーに登録して、使い終わったそのトリガーを自動で削除する



コード.gs
function set_project_trigger(){
  var date = new Date();
  ScriptApp.newTrigger("add_temp_trigger")
  .timeBased()
  .everyDays(1)
  .atHour(11)
  .create();
}

function add_temp_trigger() {
  delete_temp_trigger();
  var date = new Date();
  date.setHours(12);
  date.setMinutes(55);
  var trigger = ScriptApp.newTrigger("send_mail")
    .timeBased()
    .at(date)
    .create();
}  

function send_mail(){
  var mail_address = Session.getActiveUser().getEmail();
  MailApp.sendEmail(mail_address, "実行したスクリプトID", ScriptApp.getScriptId());
}

function delete_temp_trigger() {
  var allTriggers = ScriptApp.getProjectTriggers();
  for (var i = 0; i < allTriggers.length; i++) {
    if (allTriggers[i].getHandlerFunction() == "send_mail") {
      ScriptApp.deleteTrigger(allTriggers[i]);
      break;
    }
  }
}
意訳
この機能がやること
現在日時を取得する
add_temp_triggerを
時間主導型で
毎日
11時(〜12時の間)に実行する
トリガーを登録する


この機能がやること
使い終わったトリガーを削除する
現在日時を取得して
時刻を当日の12時
55分に設定して
send_mailを
時間主導型で
設定した日時に実行する
トリガーを登録する


この機能がやること
スクリプトを実行しているユーザのメールアドレスを取得して
実行したスクリプトIDをmaiで送信して


この機能がやること
このスクリプトに設定されているすべてのトリガーを取得して
そのトリガーの数だけ以下を繰り返す
もしトリガーに設定されている関数名が"send_mail"なら
プロジェクトのトリガーから削除して
for文から抜ける





試してみる


やることは add_temp_trigger を以下のようにトリガーに登録するだけ

これは毎日add_temp_triggerを実行するためのトリガーなので、故意に消さない限り残り続けます

このトリガーは編集メニューから直接登録しても良いですし set_project_trigger() を実行することでも登録できます
(set_project_trigger() は最初にこれを登録するためだけのコードなので使っても使わなくても良いですが、2日おきとか3日おきとかにしたい場合は、everyDays(1)をeveryDays(2)とかeveryDays(3)にするとよさそう)

編集メニューから登録する手順がわからない場合


以下は自動で行われる

毎日午前11時〜12時(正午)の間に send_mail を トリガーに登録するadd_temp_trigger が自動で実行される
そのときにプロジェクトのトリガーを見ると、send_mailが「特定の日時」でトリガーに登録されている


「特定の日時」である「2018-04-08 12:55」に send_mail が実行されたあと delete_temp_trigger() も自動で実行されて

2018-04-08 12:55の send_mail トリガーは削除される


翌日(2018-04-09)も午前11時〜12時(正午)の間に send_mail を トリガーに登録するadd_temp_trigger が自動で実行されて
send_mailトリガーが「特定の日時」で「2018-04-09 12:55」に登録されて、その時間に実行されて、削除されて...が毎日定期的に繰り返される


定期的な処理が不要になったら add_temp_trigger をプロジェクトのトリガーから削除する


参考

Installable Triggers
https://developers.google.com/apps-script/guides/triggers/installable#errors_in_triggers

everyDays(n)
https://developers.google.com/apps-script/reference/script/clock-trigger-builder#everyDays(Integer)


参考にさせていただいたQiita記事
https://qiita.com/sumi-engraphia/items/465dd027e17f44da4d6a