メールが来ていないことを通知する

朝、以下の tweet を見かけて面白そうだったので考えてみた。

IFTTT はアカウントは作ったものの、ほとんど使っていなかったな。 活用したら便利なのかも。

で、軽く触ってみた限りでは IFTTT の機能だけでは上記を実現するのは難しそう。

来るべきメールが来ていないことを知るには、最後にそのメールが来た時点からの経過時間を所定の閾値と比較すればよいのではないだろうか、と考えて、頭の体操がてら、Google Apps Script で書いてみた。

Google ドライブ新規 -> その他 -> Google Apps Script を選択して、下記コードを貼り付けて保存すると動かせると思う。

// Gmail の検索クエリ
var query = 'newer_than:1d 何とかの通知';

// 何分以上前かの閾値
var threshold = 120;

// 結果の通知を送るメールアドレス
var adminAddress = 'test@example.com';


/**
 * エントリポイント
 * この関数にトリガーを設定して毎日実行する
 * 
 * 例えば、通常 8:00-9:00 の間に通知メールが来るのであれば、
 * トリガーを「日タイマー: 9:00〜10:00」に、 threshold を 120 に設定すれば
 * 来るべきメールが来ていないことを検知できるのではないだろうか。
 */
function main() {
  var d = getLatestMailDate(query);
  if (isLongerPeriod(d, threshold)) {
    sendNotificationMail();
  }
}

/**
 * 指定したアドレスへメールを送る
 */
function sendNotificationMail() {
  var subject = '直近 ' + threshold + ' 分以内にメールはありませんでした。(クエリ: ' + query + ' )';
  var body = 'Hello world!';
  GmailApp.sendEmail(adminAddress, subject, body);
}

/**
 * クエリで検索したメールのスレッドから最新のメールを取り出し、日時を取得する
 * @param {String} q - 検索クエリ文字列
 * @return {Date}
 */
function getLatestMailDate(q) {
  var threads = GmailApp.search(q);
  var latestThread = threads[0];
  var messages = latestThread.getMessages();

  // 配列の最後の要素(メール)  
  var latestMessage = messages[messages.length - 1];
  var d = latestMessage.getDate();
  return d;
}

/**
 * 実行時の現在時刻との差分が指定値よりも大きいか比較する
 * @param {Date} d - 日時オブジェクト
 * @param {Number} t - 何分以上前か
 * @return {Boolean}
 */
function isLongerPeriod(d, t) {
  var now = new Date();

  // 現在時刻との差分(単位はミリ秒)
  var diff = now.getTime() - d.getTime();
 
  // 分に換算
  var minutes = diff / (1000 * 60);
  return minutes > t;
}

あとはこの通知メールの受信を IFTTT で LINE に通知すればよいのではないか。たぶん。

初回実行時の手順

GAS から Gmail にアクセスするために初回実行時には認証ダイアログが表示される。

GAS のトリガー設定

毎日繰り返し実行する場合、実行タイミングは 1 時間の幅を持たせて指定する形になる。

https://gyazo.com/9fb8af857d229de347bbf33a88c5ddb6