CoDMONの登園降園通知をLINEグループに転送する

# この記事の対象者 
 - 保育園・幼稚園に通園している未就学児がいる
 - 在籍園が[CoDMON](https://www.codmon.com/)を導入し、登降園をアプリ管理している
 - 登降園通知メールをLINEに転送したい

# はじめに
子供の在籍園がCoDMONを導入したのですが、子供の祖父母がスマホを使いこなせないため、
祖父母による送迎時の登降園手続きは物理カードで代用しています。
祖父母はLINEなら使えるので、登園降園通知をLINEのpush通知で配信したい！と思い作成しました。
GmailとLINEのアカウント、PCがあれば無料で実装できます。

# 準備するもの
 - Gmailのアカウント
 - LINEのアカウント

# 手順（あとでスクショ足します）
### gmailでCodMONから来るメールにラベルが来るように設定する
1. gmailのメールアドレスでCodMONに登録し、登園降園のお知らせがメールで来るように設定する
1. gmailでCoDMONから送られてくるメールに「コドモン通知」タグがつくように設定する　[参考手順](https://support.google.com/mail/answer/6579?hl=ja)　
### LINE Notifyでアクセストークンを発行する
1. [ LINE Notify](https://notify-bot.line.me/ja/)にログイン
1. 通知したい相手もしくはグループを選択し、アクセストークンを発行する
　　　　　※一度発行したトークンは再確認できないので注意
　　　　　※LINE Notifyを祖父母も入ったLINEグループに招待するのがおすすめ

### GASでトリガーを設定する
1. [GAS](https://script.google.com/home)にアクセスし、「新しいプロジェクトを作成する」をクリックする
1. 下のコードをコピペして、1行目の「AAAAAA」部分を取得したトークンに差し変え、「保存する」をクリック
1. 「トリガー」→「トリガーを追加」をクリックし、
   実行する関数を「main」
   実行するデプロイを「Head」
   イベントのソースを「時間主導型」
　　　　　時間ベースのトリガーのタイプを「分ベースのタイマー」
　　　　　時間の間隔を「5分おき」に設定し、「保存」をクリック

### LINE Notifyをグループに招待する
対象のLINEグループに「LINE Notify」を招待する。

# コード
```codmon_gmail_to_line.js
var lineToken = "AAAAAAAAAA";  // LINE Notifyのトークン。ここを書き換えてください
var intervalMinute = 5; //5分前～現在の新着メールを取得 #--トリガーの時間間隔をこれに合わせる

/**
 * 取得したメッセージをLINEに転送する
 */
function main() {

  // 転送するメッセージを取得
  var newMessages = fetchMail();
    //console.log("メールを取得しました");

  // 取得したメッセージをLINEに転送
  newMessages.forEach( msg => {
    //console.log("msg: " + msg);
    forwardLine(msg);
  })

}

/**
 * 転送するメッセージを取得する
 */
function fetchMail() {

  // 取得の基準時刻をセット
  var nowTime       = Math.floor( new Date().getTime() / 1000 );  // 現在時刻　 // getTime()はミリ秒を返すので、検索のために秒に変換（÷1000）する
  var referenceTime = nowTime - ( ( intervalMinute * 60 ) + 3 );  // intervalMinuteは分で設定しているので、秒に変換（÷60）し、さらに3秒前に

  // 検索条件を指定
  // NOTE: 「コドモン通知」ラベルをGmailで指定しておくこと
  var strSearch = '(label:コドモン通知 after:' + referenceTime + ')';

  // スレッドを検索して取得
  // NOTE: 複数回登降園タッチする可能性もあるため、念の為4スレッドに制限
  var arrThreads = GmailApp.search(strSearch, 0, 4);

  // スレッドからメッセージを取得
  // NOTE: 二次元配列で、[[スレッドのインデックス][メッセージのインデックス]]で参照できる
  var arrMsgs = GmailApp.getMessagesForThreads(arrThreads);


  // ①基準時刻より後で、②エラーメッセージではないもの（正常メール）を抽出し配列に格納
  var newMsgs = [];

  arrMsgs.forEach( thread => {
    thread.forEach( msg => {

      // ①秒換算し、基準時刻より後かを判定（boolean）
      // getTime()はミリ秒を返すので、検索のために秒に変換（÷1000）する
      var isAfter = ( (msg.getDate() / 1000 - referenceTime ) > 0 );

      // ②正常かを判定（boolean）。コドモンからのメールは【保育所名】で始まるので、「【」から始まるメールを正常メールとして扱う
      var isFine  = msg.getSubject().startsWith('【');

      // メール本文のデバッグ用 //
      //console.log('isAfter: ' + isAfter);
      //console.log('isFine:  ' + isFine);
      //console.log('msg.getDate(): ' + msg.getDate());
      //console.log('msg.getSubject(): ' + msg.getSubject());
      //console.log('msg.getPlainBody(): ' + msg.getPlainBody());


      if (isAfter && isFine) {
        // メッセージ文字列を生成。本文のみでよい。時間や送信者、件名も必要な場合はコメントアウトを消してください
        var strMsg = " "
         　//　 時間。Utilities.formatDate(date, timeZone, format)で日付フォーマットを指定する。 //
        //デフォルトではEastern Standard Timeが指定されているため、'Asia/Tokyo'で日本時間への変更が必要。
          //+ Utilities.formatDate(msg.getDate() , 'Asia/Tokyo', 'MM/dd HH:mm')
          //+ "\n\n[送信者]" + msg.getFrom()
          //+ "\n\n[件名]"   + msg.getSubject()
          //　本文のみ転送 
          +  msg.getPlainBody();
        // 配列に追加
        //console.log(strMsg)
        newMsgs.push(strMsg);
      }

    })
  })

 return newMsgs;
}


/**
 * LINEにメッセージを転送する
 * @param {String} Me メッセージの内容
 */
function forwardLine(Me) {

  var payload = {'message' : Me};
  var options = {
    "method"  : "post",
    "payload" : payload,
    "headers" : {"Authorization" : "Bearer "+ lineToken}  
  };

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

}
```

# 感想
 - 昔はIFTTT使ってたのですが、無料プラン縮小したのとgmailとの連携廃止したのでGASに乗り換えました。
 - 無料でできるの、よい
 - 9時になってもタッチがない場合はアラート出す（送り忘れ防止）とかもそのうち実装したいなぁ


# 参考にした記事
https://qiita.com/hann-solo/items/83208cd686d401bdf800
https://qiita.com/hann-solo/items/5aae93dd9352c21e5a3f