Gmailに届くメールを宛先別に分類してGoogle SpreadSheetに書き出す方法

#やりたいこと
- Gmailに日々大量のメールが届く
- どんなメールが、どのくらい届いているのか可視化したい
    - まずは宛先別に分類してみる
    - 日別にどの宛先に何件届いているのか集計してグラフ化する


#完成したコード
```javascript:Code.gs
//実行時間を細かく制御するための関数
//https://qiita.com/sumi-engraphia/items/465dd027e17f44da4d6a
function setTrigger() {
  var triggerDay = new Date();
  triggerDay.setHours(23);
  triggerDay.setMinutes(59);
  ScriptApp.newTrigger('aggregateGmail').timeBased().at(triggerDay).create();
}
 // その日のトリガーを削除する関数(消さないと残る)
function deleteTrigger() {
  var triggers = ScriptApp.getProjectTriggers();
  for(var i=0; i < triggers.length; i++) {
    if (triggers[i].getHandlerFunction() == 'aggregateGmail') {
      ScriptApp.deleteTrigger(triggers[i]);
    }
  }
}

// Gmailから特定条件のスレッドを検索しメールを取り出す
function aggregateGmail() {
  var date = new Date();

  //メールの検索条件
  var strTerms00 = 'newer_than:1d -label:chats'; //全ての宛先（ハングアウトを除く。以下同）  
  var strTerms01 = 'newer_than:1d to:グループアドレス01 -label:chats'; //グループアドレス01宛
  var strTerms02 = 'newer_than:1d to:me -label:chats'; //個人宛
  
  //条件にマッチしたスレッドを取得
  var myThreads00 = GmailApp.search(strTerms00); 
  var myThreads01 = GmailApp.search(strTerms01);
  var myThreads02 = GmailApp.search(strTerms02);

  //スレッドからメールを取得する　→二次元配列で格納
  var myMsgs00 = GmailApp.getMessagesForThreads(myThreads00);
  var myMsgs01 = GmailApp.getMessagesForThreads(myThreads01);
  var myMsgs02 = GmailApp.getMessagesForThreads(myThreads02);
  
 // スプレッドシートに出力
 if(myMsgs00.length>0){
    var mySheet=SpreadsheetApp.getActiveSpreadsheet().getSheetByName('aggregateGmail'); //シートを取得
    mySheet.insertRowAfter(1); //常に2行目に値をセットするため、1行追加する。
    mySheet.getRange(2, 1).setValue(date); //Scriptが起動した日時をA列に記載
    //メールの件数をB列以降に記載
    mySheet.getRange(2, 2).setValue(myMsgs00.length +1);  
    mySheet.getRange(2, 3).setValue(myMsgs01.length +1);
    mySheet.getRange(2, 4).setValue(myMsgs02.length +1); 
  }
}
```
#コードの説明
```javascript:Code.gs
//実行時間を細かく制御するための関数
//https://qiita.com/sumi-engraphia/items/465dd027e17f44da4d6a
function setTrigger() {
  var triggerDay = new Date();
  triggerDay.setHours(23);
  triggerDay.setMinutes(59);
  ScriptApp.newTrigger('aggregateGmail').timeBased().at(triggerDay).create();
}
 // その日のトリガーを削除する関数(消さないと残る)
function deleteTrigger() {
  var triggers = ScriptApp.getProjectTriggers();
  for(var i=0; i < triggers.length; i++) {
    if (triggers[i].getHandlerFunction() == 'aggregateGmail') {
      ScriptApp.deleteTrigger(triggers[i]);
    }
  }
}
```
日別に集計するために、1日1回トリガーでスクリプトを起動させます。

Google Apps Script規定のトリガーでは、1時間単位（例：23:00〜0:00の間）でしか指定できません。
すると最大1時間分のメールが抜け落ちてしまいます。
このため、下記の記事にある方法で、起動時間を分単位で制御します。

- [Google Apps Scriptの日毎のトリガーで時間をもっと細かく設定する - Qiita](https://qiita.com/sumi-engraphia/items/465dd027e17f44da4d6a)

```javascript:Code.gs
// Gmailから特定条件のスレッドを検索しメールを取り出す
function aggregateGmail() {
  var date = new Date();

  //メールの検索条件
  var strTerms00 = 'newer_than:1d -label:chats'; //全ての宛先（ハングアウトを除く。以下同）  
  var strTerms01 = 'newer_than:1d to:グループアドレス01 -label:chats'; //グループアドレス01宛
  var strTerms02 = 'newer_than:1d to:me -label:chats'; //個人宛
  
  //条件にマッチしたスレッドを取得
  var myThreads00 = GmailApp.search(strTerms00); 
  var myThreads01 = GmailApp.search(strTerms01);
  var myThreads02 = GmailApp.search(strTerms02);

  //スレッドからメールを取得する　→二次元配列で格納
  var myMsgs00 = GmailApp.getMessagesForThreads(myThreads00);
  var myMsgs01 = GmailApp.getMessagesForThreads(myThreads01);
  var myMsgs02 = GmailApp.getMessagesForThreads(myThreads02);
```

集計対象のメールを検索する条件を定義し、中身を取り出します。
Gmailで通常使用する検索条件が利用できます。

- [Gmail で使用できる検索演算子 - Gmail ヘルプ](https://support.google.com/mail/answer/7190?hl=ja)


前述の通り、1日1回起動させるため、`newer_than:1d`としています。また`-label:chats`として、ハングアウトの履歴を除外しています。
（今回は検索条件ごとに都度検索して配列に格納していますが、もう少しエレガントな方法があるように感じています。）

```javascript:Code.gs
// スプレッドシートに出力
 if(myMsgs00.length>0){
    var mySheet=SpreadsheetApp.getActiveSpreadsheet().getSheetByName('aggregateGmail'); //シートを取得
    mySheet.insertRowAfter(1); //常に2行目に値をセットするため、1行追加する。
    mySheet.getRange(2, 1).setValue(date); //Scriptが起動した日時をA列に記載
    //メールの件数をB列以降に記載
    mySheet.getRange(2, 2).setValue(myMsgs00.length +1);  
    mySheet.getRange(2, 3).setValue(myMsgs01.length +1);
    mySheet.getRange(2, 4).setValue(myMsgs02.length +1); 
  }
}
```
取得したメールの情報をスプレッドシートに書き出します。

このようなケースで、最終行を取得してその下に追加することが多い印象がありますが、値をセットする場所は固定にして一行追加（`mySheet.insertRowAfter(1)`）した方が、処理がシンプルで個人的には好みです。

##出来上がりイメージ

| 日付|All|グループアドレス01|個人宛|
|:--|:--:|:------------------:|:--:|
| 2018/07/09       | 312 |        101       |14| 
| 2018/07/08           |   331|       90       |20|
|2018/07/07|268|60|9|

あとはスプレッドシートでグラフ化すればOKです。

#参考サイト
- [Google Apps Scriptの日毎のトリガーで時間をもっと細かく設定する - Qiita](https://qiita.com/sumi-engraphia/items/465dd027e17f44da4d6a)
- [Gmail で使用できる検索演算子 - Gmail ヘルプ](https://support.google.com/mail/answer/7190?hl=ja)