Google Apps ScriptとTwilioで、システムアラートを100%気付ける環境作り

実は、今までガラケーで生活していました。
今日、無事にスマホシフトしたんですが、スマホだと「システムアラートに気づきにくくないか?」ということで、解決をしようと試みた記録です。

遂にガラケーからスマホに乗り換えました!

シャープのガラケーは7年も問題なく働いてくれました。すごすぎる。外装はさすがにひどいですが・・・。
IMG_20170610_213032
かれこれ7年ほど、スマホとガラケーの2台持ち状態で、スマホはSIMなしのWiFi運用でした。
ずっとガラケーを使っていた理由は、シンプルに安いからでした。通話専用機と化している僕のガラケーは毎月1,000円くらいの維持費で、1万円近くするスマホには、とても乗り換える気が起きませんでした。
どこでも開発ができるように24時間モバイルWiFiルーターを持ち歩いている身としては、スマホにSIMを入れる必要もなかったです。
そんなわけでずっとガラケーを使い続けていたわけですが、格安SIMならガラケーくらいの維持費でスマホのSIMを運用できるということを聞きまして、2台持っているのも鬱陶しいし、2年縛りの解除されるタイミングを狙い、重い腰を上げてスマホ移行しました。

システム監視のアラート通知に気づかない問題

ところで、エンジニアとしてシステムアラートをケータイで確実に受け取れるようにしておきたいです。
スマホには雑多に通知がたくさん流れていて、システムに障害が発生した際の重要な通知に気づけない不安がありました。
僕のガラケーに連絡してくる人はほぼいないので、ガラケーが震える時はシステム障害のとき、ということで気づきやすかったのですが。
そういうわけで、スマホでもシステムアラートを埋もれせずに、確実に気づける環境を作ろうと思い立ちました。
ちなみに、現在のシステムアラートはこんな感じになっています。

  • 監視ツールが問題を検知した場合、メールがアラートメーリングリストに送信される
  • メールは全エンジニアに通知されるが、各自で適宜担当サービスのメールをフィルタしている
  • 通知を受け取ったら、必要な対応をする
  • サービスダウンなど緊急度の高い問題は、別の緊急メーリングリストにもメールを送信して、担当外のエンジニアも検知して対応

そういうわけで、基本はメールです。

通知はTwilioで実現

基本はメールなんですが、Gmailのプッシュ通知だと、やはり埋もれてしまいます。もれなく気付けるようにしようと思うと、やはり電話をかけるのが良さそうです。
システムから電話をかけるといえば、Twilio。もしかしたら最近はもっと違うのあるのかもしれないですが。
スクリーンショット 2017-06-11 17.00.20
Twilio for KDDI Web Communications | クラウド電話API
トライアルもできるので、とりあえず試してみるのも良いと思います。
こんな感じでHTTPでPOSTするだけで、自分のスマホに着信がきます。

curl -X POST 'https://api.twilio.com/2010-04-01/Accounts/ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/Calls' \
-d 'Url=http://demo.twilio.com/docs/voice.xml' \
-d 'From=%2B815000000000' \
-d 'To=%2B819000000000' \
-d 'Timeout=10' \
-u 'ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'

Twilioのコストですが、電話番号の維持費が毎月100円。携帯電話への発信料が1分あたり15円です。発信料は通話が成立しなければかからないようです。 (詳しくはこちら)
あとは、アラートメールをトリガーにして、これを呼び出せば良いのですが、それをどうするか。

IFTTTを使って、Twilioの発信をトリガーする

10分くらいでできるのは、IFTTTでトリガーする方法です。しかも、この方法だったら、ソースコードも書かなくてよいので、誰でもできます。
スクリーンショット 2017-06-11 17.15.37
Learn how IFTTT works – IFTTT
IFTTTは、サービス間連携のツールで、「Gmailでメールを受信したときにTwitterに投稿する」とかそういう自動化ができます。
事前にこんな感じで、Gmailのフィルタ機能でシステムアラートには、AlertとEmergencyというラベルをつけておき、このラベルのついたメールを受信したときに、Twilioを呼ぶようにします。
スクリーンショット 2017-06-11 17.15.03
設定はこういう感じです。Gmailでラベル付きのメールを受信したときに、WebhookでHTTPリクエストをするだけです。
スライド1
これで、アラートメールをアラート電話に変換することができます!

Google Apps Scriptを使って、複雑な条件を実現

せっかくなので、もう少し欲張った要件で通知してみたいと思います。

  • アラートメールを開封するまで繰り返し電話をする
  • 緊急度の高くないアラート(Alertラベル)は10分に1回電話をする
  • 緊急度の高いアラート(Emergencyラベル)は1分に1回電話をする

これを実現するには、IFTTTでは無理です。レンタルサーバにスクリプトを置いて・・・とかも可能ですが、Gmailへのアクセス権限の取り扱いのしやすさも考えると、Google Apps Scriptが使えそうです。
Google Apps Scriptは、JavaScriptをGoogleのサーバ環境で実行できるもので、Google Driveのメニューから作成することができます。
スクリーンショット 2017-06-11 16.32.19
ここにまだ表示されていない人は、「アプリを追加」から検索して追加してください。

Gmailのメール取得と、HTTPリクエストの送信

作ったソースコードはこんな感じです。Emergencyラベルのメールと、Alertラベルのメールで、電話の発信のしかたを変えています。

function checkMailAndMakePhoneCall() {
  var emergencyThreads = getLabeledUnreadThreads('Emergency');
  Logger.log('Emergency mail count: ' + emergencyThreads.length);
  // Emergencyの通知があれば30秒の通話を発信する
  if (emergencyThreads.length > 0) {
    Logger.log('Make a 30-second phone call.');
    makePhoneCall(30);
    return;
  }
  var alertThreads = getLabeledUnreadThreads('Alert');
  Logger.log('Alert mail count: ' + alertThreads.length);
  for(var i in alertThreads) {
    var alertThread = alertThreads[i];
    // Alertの通知があれば、10分に1回、10秒の通話を発信する
    if(Math.floor((new Date().getTime() - alertThread.getLastMessageDate().getTime()) / (60*1000)) % 10 == 0) {
      Logger.log('Make a 10-second phone call.');
      makePhoneCall(10);
      return;
    }
  }
}

メールの確認は、GmailApp.getInboxThreadsというメソッドを使って行います。受信箱から、指定のラベルがついているか確認して、さらに未読であれば取り出して返します。

function getLabeledUnreadThreads(labelName) {
  var labeledUnreadThreads = [];
  var threads = GmailApp.getInboxThreads();
  for (var i in threads) {
    var thread = threads[i];
    if (!thread.isUnread()) {
      continue;
    }
    var labels = thread.getLabels();
    for (var j in labels) {
      var label = labels[j];
      if (label.getName() == labelName) {
        labeledUnreadThreads.push(thread);
      }
    }
  }
  return labeledUnreadThreads;
}

TwilioへのHTTPリクエストは、UrlFetchApp.fetchメソッドを使います。これはただHTTPリクエストをするだけです。発信時間を引数で変えられるようにしています。

function makePhoneCall(timeout) {
  var options = {
    'method': 'post',
    'headers': {
      'Authorization': 'Basic ' + Utilities.base64Encode('ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx')
    },
    'payload' : {
      'Url': 'http://demo.twilio.com/docs/voice.xml',
      'From': '+815000000000',
      'To': '+819000000000',
      'Timeout': timeout.toString()
    }
  };
  UrlFetchApp.fetch('https://api.twilio.com/2010-04-01/Accounts/ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/Calls', options);
}

Google Apps Scriptは周期実行ができるので、1分に1回、このcheckMailAndMakePhoneCall関数を実行するように設定します。
スクリーンショット 2017-06-11 16.33.26 2
これで設定は終わり!

システムアラートを100%気付ける環境の完成

アラートのメールがきたときに気づいて開封すればそれで終わりです。
メールの通知に気づいていないときは、Twilioで管理している050の電話番号から、着信がきます。
Screenshot_20170611-162757 2
それでも気づいていなくて、メールが開封されないままだと、何回か発信を繰り返してくれます。スクリプトは使い勝手を見ながら更新していこうと思います。
※ ところで、みなさんはどうやって重要なメールを見逃さないようにしているのでしょうか。ここまでしなくても、何か良いアプリとかがあったりして・・・。

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