毎日決まった時刻にトリガー

Googleスプレッドシート

はじめに

 Googleスプレッドシートでは、マクロ(GAS)をある決まった時刻に起動させたり、定期的に実行したりする事が出来ます。
 時間主導型のオプションは、以下のようになっています。
 ・特定の日時
 ・分ベースのタイマー
 ・時間ベースのタイマー
 ・日付ベースのタイマー
 ・週ベースのタイマー
 ・月ベースのタイマー

 
 このように、ある特定の日の決まった時刻には起動できても、
 毎日決まった時刻に起動するということは、オプションで指定できません。
 
 一番近いのは、日付ベースの「午前9時から10時」など、1時間の範囲指定になるでしょう。
 
 これではまずい場合もあるので、プログラムで工夫してみましょう。
 ただし、1秒単位で厳密な処理というのはネット環境の影響もあるため、それほどの精度は求めないものとします。

プログラムの仕方

 トリガーは、プログラムから新しく作ったり、削除したりという事ができます。
 「特定の日時」モードで時間指定するトリガーを、その時間前までに「日付ベースのタイマー」でトリガー設定する関数を起動すれば、毎日決まった時刻に関数を実行するという事が可能になります。
 ただ、そのままですと、プログラムで設定した「特定の日時」モードのトリガーはどんどん増えてしまいます。
 そのため、プログラムで作成したトリガーは、関数の実行後に削除するようにします

プログラムソース

 今回のプログラムは、17時15分にメールでメッセージを送信するというサンプルです。
 メッセージはスクレイピングした内容を送信するようにしています。
 筆者の場合、ここに電車の遅延情報をスクレイピングするようにしています。
 つまり、帰宅する17時15分に電車の遅延情報をメールで受け取るようにしてみます。

function getMySite() {
  // サイトURL
  const url = "https://****サイトURL****";
  let html = UrlFetchApp.fetch(url).getContentText('UTF-8');

  //文章の抜き出し
  const str = '</header>';           //切り出し文字列 開始
  let s1 = html.indexOf(str);
  html = html.substring(s1 + str.length);
  let s2 = html.indexOf('</div>'); //切り出し文字列 終端

  //HTML記号を削除
  let content = html.substring(0,s2).replace(/<("[^"]*"|'[^']*'|[^'">])*>/g,'');

  //日付を取得
  let myDate = new Date();
  myDate = Utilities.formatDate(myDate,'Asia/Tokyo','yyy/MM/dd HH:mm_ss');

  //最終行の取得
  let ssh = SpreadsheetApp.getActiveSpreadsheet();
  let sht = ssh.getSheetByName('HTML');
  let myRow = sht.getDataRange().getLastRow() + 1;

  //日付と文章をセルに入力
  sht.getRange(myRow,1).setValue(myDate);
  sht.getRange(myRow,2).setValue(content);
  sht.getRange(myRow,2).trimWhitespace();
  
  //メールで送信
  let myStr = sht.getRange(myRow,1).getValue();
  myStr = myStr + '\r\n' + sht.getRange(myRow,2).getValue();
  sendMyGmail(myStr);

  //トリガーを削除
  deleteMyTrigger();
}

function sendMyGmail(body){
  const recipient = '**** メールアドレス ****';   // メールアドレス
  const subject ='テストメール';                         // 題名
  const options = {name: 'Userより'};                  // 差出人
  
  GmailApp.sendEmail(recipient,subject,body,options)
}

//目的の時間にトリガーを設定する
//この関数をトリガーを「日付ベースのタイマー」で設定時刻の前に登録しておく
function setMyTrigger(){
  //今の日時を取得
  let time = new Date();
  //トリガー実行時刻を設定
  time.setHours(17);             // 17時
  time.setMinutes(15);          // 15分
  //MyMailTest関数を特定日時モードでトリガー作成
  ScriptApp.newTrigger('getMySite').timeBased().at(time).create();
}

//トリガー登録された関数名でトリガーを削除する
function deleteMyTrigger(){
  //プロジェクトに設定したトリガーを取得
  const myTrg = ScriptApp.getProjectTriggers();
  //トリガー登録数のforループを実行
  for(let i=0;i<myTrg.length;i++){
    //トリガー関数が目的のものであれば
    if(myTrg[i].getHandlerFunction()==='getMySite'){ 
      ScriptApp.deleteTrigger(myTrg[i]); 
    }
  }
}

 プログラムは、黄色い下線部分を書き変えれば使えるようになると思います。

 使い方は、「日付ベースのタイマー」「午後4時~5時」のトリガーでmySetTrigger関数を起動するようにします。


 
 mySetTrigger関数では、「特定の日時」モードのトリガーを本日の17時15分getMySite関数が起動するようにしています。
 
 getMySite関数の最後に自分自身を起動したトリガー(「特定の日時」モードのトリガー)を削除するようにします。
 
 

 
 動作としては、毎日、「午後4時~5時」のトリガーでmySetTrigger関数が起動します。
 起動した、mySetTrigger関数は、本日の17時15分getMySite関数を起動します。
 getMySite関数の最後には、新しく作ったトリガーを削除するようになっています。

まとめ

 既に用意されているトリガーであれば、上記のようなプログラムは不要になります。

 別の方法としては、頻繁にトリガーで関数を起動し、関数内で現在の時間を確認して処理を実行するという方法も考えられます。ただ、この方法ですと無駄が多いので見送ることにしました。

 トリガーをうまく使いこなせば、手元のPCが稼働していなくても情報を取り出す事が容易にできます。これこそGoogleスプレッドシートの大きな魅力と言えるでしょう。

コメント

タイトルとURLをコピーしました