Google Apps Script @福岡

GASで面白Webサービス&コスト削減や!

Google Apps Script 講座中級編「GASでGmailを検索してLINEで通知する」

はじめに

後藤銃士です。正月から始めた、FGO、なかなか★5が引けませんね。課金する人の気持ちが少しわかりました…。

さてようやく前回、前々回からやってきたことの集大成、「GASでGmailを検索してLINEで通知する」を実装します。いままでやってきたことの寄せ集めなので、基本難しいところはありません。やっていることは、

  • Gmailを検索する
  • 目的のメールが見つかったら、記録していたスプレッドシートをチェック

  • チェックがあればスルー。

  • チェックがなければまだLINEで通知をしてないので通知し、スプレッドシートに記録しておく。

という流れになります。また時間よる定期チェックは以前解説した「トリガー機能」をつかいます。

はい、それでは早速やっていきましょう。

前提条件

LINE Notify が動くように設定してあること

jijyoron.hatenablog.com

この機能が役に立つのは

Gmail を GAS で Gmail と LINE とトリガー機能のコラボを理解したい人

講座スタート

いつもどおりコピペだけで大丈夫です。が、その前に空のスプレッドシートを用意して下さい。

用意が出来ましたか?では、

新しくタブを開き「script.google.com」を入力してコードを書ける状態にして下さい。

そしてコード.gs に

function myFunction() {
   
  // スプレッドシート検索
  var spreadsheet = SpreadsheetApp.openByUrl('あなたのスプレッドシートURL'); 
  var sheet = spreadsheet.getSheetByName("シート1");
  var lastrow = sheet.getLastRow();
  Logger.log(lastrow);
  
  // 登録済スレッドID一覧取得
  var range = [[""]];
  if (lastrow > 0){
    range = sheet.getRange(1, 1, lastrow).getValues();
  }
  
  // メール検索
  var query = 'subject:メルカリ subject:発送をお願いします';
  var threads = GmailApp.search(query, 0, 3);
  
  // スレッド毎に件名をチェック
  threads.forEach(function(thread, i, array){
    Logger.log(thread.getId());
    Logger.log(thread.getLastMessageDate());
    Logger.log(thread.getFirstMessageSubject());

    // 件名の存在確認
    var exists = range.filter(function(item, index){
      if (item[0].indexOf(thread.getId()) >= 0) return true;
    });

    // 存在しない場合
    if(exists.length == 0){
      // LINE通知
      sendHttpPost(thread.getFirstMessageSubject());
      // スプレッドシート追記
      lastrow = sheet.getLastRow();
      sheet.getRange(lastrow +1, 1).setValue(thread.getId());
    }
  });
}

function sendHttpPost(message){
  var token = "あなたのトークン";
  var options =
   {
     "method"  : "post",
     "payload" : "message=" + message,
     "headers" : {"Authorization" : "Bearer "+ token}

   };

   UrlFetchApp.fetch("https://notify-api.line.me/api/notify",options);
}

をコピペして保存します。

f:id:jijyoronn:20190115215858p:plain

f:id:jijyoronn:20190115215912p:plain

実行の前に

を設定しておいて下さい。

件名の検索

  var query = 'subject:メルカリ subject:発送をお願いします';

検索条件の設定ですが、上記の例は、件名に「メルカリ」と「発送をお願いします」が両方入っているもの(いわゆる AND条件)を検索しています。 条件が1つだけで良ければ

  var query = 'subject:メルカリ';

だけでよいですし、どちらか(いわゆる OR条件)の場合は、

  var query = 'subject:メルカリ OR subject:発送をお願いします';

でいけます。

設定ができましたら実行してみましょう。実行対象は myFunction になります。

すると検索対象になったメールがあったら、LINE通知が来ているはずです。来ていますか?

f:id:jijyoronn:20190115220030p:plain

次にスプレッドシートをみると、対象となったスレッドIDが登録されているのがわかると思います。

f:id:jijyoronn:20190115220043p:plain

ではもう一度実行してみましょう。すると何も反応がないはず。

それはLINEに通知する際に、一度スプレッドシートのスレッドIDをチェックしているから、なんですね。

今回のポイントの1つに、配列の要素をチェックする、ということをやっています。それが以下。

    // 件名の存在確認
    var exists = range.filter(function(item, index){
      if (item[0].indexOf(thread.getId()) >= 0) return true;
    });

最新の JS では気の利いたメソッドが実装されているようなんですが、GAS は古い JS をベースにしているので昔のテクニックでチェックしています。range にはスプレッドシートのA行目のデータが配列形式2次元で入ってます。

[["16847532765d0d1f"],["16844cebe50ddbc8"]]

で、filter メソッドを利用し、配列の配列の0番目つまり"16847532765d0d1f" や "16844cebe50ddbc8" を idndexOf を使い thread.getId() の内容を含んでいるかを判定しています、っていわれてもわからん場合は、「そんなもんか」と思っておくか改めて自分で調べるかして下さい(投げやり)。

というわけで、私の場合、メルカリに注文があった場合、LINEに通知がくるようになりました。目的は図書館の予約本到着メールなので、これも一緒に組み込むことにしています。

みなさんも件名の検索文字列を工夫して、自分のメールがいつ到着したかを LINE でチェック出来るようにしておくと便利だと思いますよ。あー、当然このソースは、トリガー設定しておくんですよ?私は4時間単位でチェックさせるようにしています。

jijyoron.hatenablog.com

今回は以上となります。

それでは、ご覧いただきありがとうございました。