Google Apps Scriptを使って定期実行するcronを作る

GoogleAppsScriptを使って定期実行するcronを作る

こんにちは、最近ジムで身体を少しだけ鍛えてランニングマシーンで軽く走っているので体力ちょっとは付いたかな?と過信して、山登りをしたらすぐに動けなくなってしまう最大HPが低いことが改めて分かった、らいかです。

いま面倒を見ているWebシステムで1時間に1回定期的にphpを実行させたい要件があって、つい先日までは、旧ライブドアのWebサービス「DATAHOTEL PATROL」というものを使っていたのですが、急遽サービス提供を打ち切るという連絡があったので代替手段を探すことに。

しかし、問題がお客さんのサーバーはWindowsServerでLinuxでいうところのcronを実現する事が出来ません。それに替わる手段として、タスクスケジューラーを検討したのですが

お客
セキュリティ方針的に許可できません

というコトで更に代替手段を検討したところ、Googleが提供しているGoogle Apps Scriptが定期実行に対応していて、しかも今のところ(2016年8月時点)ではリクエスト制限等がなかったので、Google Apps ScriptでLinuxのcronっぽいものを作りました。

また、定期実行が何らかの原因で正常に行われなかったことを考慮して失敗時にはメールを送信して失敗したことをいち早く伝えれるようすることを目指します。

Google Apps Scriptとは

その名の通り、Googleが提供しているWebアプリをサクっと作れる便利サービス。今回作るようなcron系だけじゃなくAuth認証を通してTwitterのBotを作ったり、チャットサービスと連携させてChatBotを作ったり用途は非常に様々。めっちゃ便利。すごい。

JavaScriptっぽい構文なので完全に新しい言語を覚えるというハードルもなく、とにかく無料で今のところ制限なく使えるのがステキ。

定期実行プログラム

急いでいる方向けに完成したコードから先に紹介します

function myFunction() {
  var url = "http://www.example.com/";    // 監視対象URL
  
  var res = UrlFetchApp.fetch(url, { muteHttpExceptions:true });
  var rescode = res.getResponseCode();

  if (rescode != 200){ errorMail(rescode); }
}

function errorMail(rescode){
  MailApp.sendEmail(
    "hogehoge@example.com",    // 送信先
    "【Error】サーバーの死活監視に失敗しました",    // メールタイトル
    "",    // オプション
    {htmlBody:"xxxサーバーが停止しています。
HTTPステータスコード:"+ rescode + "
ステータスコードに従って対処を行って下さい。"}
  );
}

監視対象URLがHTTPステータスコード200(正常)以外を返却した場合は、エラーメールを送信するプログラムです。監視対象URLとメールの送信先やタイトルや本文を好きなものに変更すればそれだけで使えるようになります。めっちゃ便利。

作り方とコードの説明とか注意点

プロジェクトの作成

お手持ちのGoogleアカウントにてGoogleDriveにログインします。続いて、以下の手順でGoogle Apps Scriptを選択すると別ウィンドウにてコードを入力する画面が表示されます。

Google Apps Scriptを使って定期実行するcronを作る

あとはココにコードを入力していくだけで、定期実行できるプログラムが作成出来ます。

指定したURLへのリクエスト

var url = "http://www.example.com/";    // 監視対象URL
var res = UrlFetchApp.fetch(url, { muteHttpExceptions:true });

「UrlFetchApp.fetch()」をすることで、普通に対象のURLへアクセスした動きと同じ動きを再現できます。この関数と次に使うHTTPステータスコードの取得を組み合わせることで、監視対象のURLが正常に動いているか否かを判別します。

UrlFetchapp.fetch()の注意点

この関数の第二引数として「{ muteHttpExceptions:true }」を設定するとHTTPリクエストの結果が200(正常)以外の場合に例外エラーとして判断しません。
例外エラーとして処理されると「try-catch」を使って例外処理を実装する必要があり非常に面倒です。今回作りたいものはHTTPリクエストのエラーは例外でなく、想定内であるため、例外エラーを発生させないために、muteHttpExceptionsを設定します。

HTTPステータスコードの取得

監視対象URLに対してリクエストを送信すると、様々な応答が返ってきます。必要なのは監視対象が正常に動いているのか、異常なのかだけなので、他の情報は無視してHTTPステータスを取得します。

var rescode = res.getResponseCode();
if (rescode != 200){ errorMail(rescode); }

取得したHTTPステータスコードが200(正常)以外の場合は、異常であると判断してメールを送信します。

エラーメールの送信

非常にセキュアなシステムでは自動的にリトライなどを行うのですが、異常時は手動対応を想定しているので、シンプルにメール送信のみを行います。

function errorMail(rescode){
  MailApp.sendEmail(
    "hogehoge@example.com",    // 送信先
    "【Error】サーバーの死活監視に失敗しました",    // メールタイトル
    "",    // オプション
    {htmlBody:"xxxサーバーが停止しています。
HTTPステータスコード:"+ rescode + "
ステータスコードに従って対処を行って下さい。"}
  );
}

メールの送信には「MailApp.sendEmail()」関数を利用します。関数名の通りメールを送信する関数でお使いのgmailアカウントから指定したメールアドレス宛にメールを送信します。上記の例では、メールを送信するだけではなくHTTPステータスコードをメールに埋め込むことで状況を把握しやすくしています。またメール本文の改行は直接brタグを使います。

複数の宛先に対して送信したい場合

複数の宛先に対してメールを送信したい場合は、第一引数の送信先をカンマ(,)で区切るだけで複数の宛先に対して同時にメールを送信する事が可能です。CCやBCCを使いたい場合は、第四引数にオプション設定する必要があるので詳しくはGoogle Apps Scriptのリファレンスを参照下さい。

トリガーの設定

このプログラムは1時間に1度実行するようにしたいのですが、定期実行に関するものはコードとしてではなく、Google Apps Scriptの機能を使って実現します。

Google Apps Scriptを使って定期実行するcronを作る

Google Apps Scriptのメニューバーにある「時計」っぽいマークをクリックすると、トリガーを設定するポップアップウィンドウが表示されます。ここに新しいトリガーを追加します。

Google Apps Scriptを使って定期実行するcronを作る

設定するトリガーは1時間ごとに実行させたいので「時タイマー」「1時間ごと」を指定します。この他にも、10分ごとの実行や指定時間での実行を柔軟に指定することができ、かなり夢が広がります。

作成したプログラムの実行について

作成した定期実行プログラムは、トリガーを指定した時点から定期的に実行され続けます。特別な設定が不要なので便利ですが、「テストしてから動かし始めたい時」にトリガーを設定してしまうと勝手に動き続けるので注意が必要です。また、トリガーを設定した状態でゴミ箱にプロジェクトファイルをゴミ箱に移動してもゴミ箱は厳密にはファイルが削除されていないのでプログラムは定期実行を続けます。本当に不要になった場合はプロジェクトファイルをGoogleDrive上から完全に削除するか、トリガーを削除します。

らいか
Googleの公式リファレンスページにはAuth認証を行ったTwitter連携プログラムがあったり、ちょっと工夫すれば簡単にTwitterBOTが作れるんじゃないか?って気になりました。今度挑戦してみたいです。

ABOUTこの記事をかいた人

工業高等専門学校を卒業後、NTTグループのSI企業に就職。数々の炎上案件を鎮火するために日本各地を5年間転々とする。2015年に一般ユーザ向けのWebシステム開発案件のチームリーダとして業務に従事し、改めて"Webのものづくりの楽しさ"に気付きWeb制作会社に転職。Web制作やアクセス解析を使ったオウンドメディアの運用改善などを行っていく中で、もっとユーザー目線でWebをただ制作するだけではなく企画や運用まで幅広い領域で仕事がしたいと感じるようになり、Webディレクターのキャリアを目指す。日本中のビジネスホテルに詳しく、犬や猫よりも鳥派。