GoogleAppsScriptでいろいろな条件を指定してメールを取得する

# 前書き

GoogleAppsScriptを使ってGmailを取得してスプレッドシートに貼り付けるというコードを書いていた時に「yyyy/MM/dd〜yyyy/MM/ddの期間」という指定で取得したい時がありました。でもそれをどうやって書くのかがわからなかったので、どのように指定すればどんなメールが取得できるのかを調べました。

条件指定以前にGmailをスプレッドシートに貼り付ける方法がわからない、という方は[備忘録：Gmailで受け取った内容をGoogleスプレッドシートに自動で読み込んで管理する方法](http://webimemo.com/web/8403)という記事を読むとわかると思います。この記事でも一番最後にコード全体像は記載します。

# 条件指定のフォーマット

```
var threads = GmailApp.search(' 何か ');
```

ちょっとネットで調べるとqueryの部分に`in:inbox is:read`などと書いているコードが見つかります。でもこれがなんなのかがわからなかったので公式ページを見てみると上記の[GmailApp.search( )](https://developers.google.com/apps-script/reference/gmail/gmail-app#search(String))が見つかりました。ここを見るとsearchの引数はクエリであると書かれています。なのでGmailで検索窓に入れる時の記法で書けば良い、ということになります。

ちなみに以下のように書いても条件を指定してメールを取得できます。

```
var threads = GmailApp.search(query, start, max);
```

startの部分には最初のスレッドのインデックスを、maxの部分には返すべきスレッド数の最大値を指定します。maxは仕様で最大500と決まっているようです。

# 指定できる条件

Gmailヘルプの[Gmail で使用できる検索演算子](https://support.google.com/mail/answer/7190?hl=ja)や[Gmailで知らないと損する10種類の検索コマンド──フィルタ作成にも便利](http://appllio.com/gmail-advanced-search-filtering-technics)というページを見ればどのように条件を書いたら良いのかがわかってしまうので私はあまり書くことがありません。
なのでこの記事では特にどう書くのか、そもそもどうやってそのようなメールを作るのか気になったものだけ紹介します。

## ラベル --- label:

書き方：`label:[ラベル名]`

メールにラベルを付ける方法については[Gmailのラベル（フォルダ）と自動振り分け設定のやり方を知らないと受信トレイがアレになるよ](https://thedog8.com/1622.html)を見るとラベルの付け方、さらには自動で振り分ける方法について書かれています。

## グループ化 --- (  )

書き方：`([keyword1] [keyword2])`

グループ化という言葉を見ると何か大層なものに思えてしまいますが、通常思い描いているような()の用法と同じです。以下に例を示します。
`GmailApp.search('subject:(keyword1 keyword2)')`
この場合は件名にkeyword1とkeyword2が入っているメールを取得する指定の仕方になります。

一方で以下の場合はどうなるでしょうか。
`GmailApp.search('subject:keyword1 keyword2')`
この場合は件名検索はkeyword1だけ行われ、keyword2は通常のキーワード検索が行われるため、件名にkeyword2が入っていなくても本文にkeyword2が入っていればヒットします。

## 色アイコン --- has:

書き方：`has:[color]`

デフォルトでは黄色の星しか設定されていないと思いますが、スターの種類は増やすことができます。[Gmail でのスター付きメール](https://support.google.com/mail/answer/5904?co=GENIE.Platform%3DDesktop&hl=ja)に書かれているように、以下の箇所でスターの種類は増やすことができます。
![スクリーンショット 2016-10-29 22.54.01.png](https://qiita-image-store.s3.amazonaws.com/0/100736/a61bc485-c545-3018-f14e-4656f2bcf8cb.png)
ここでスター4個などと設定しておくと他の色のスターも使えるのでこのような表示が可能になります。
![スクリーンショット 2016-10-29 22.59.04.png](https://qiita-image-store.s3.amazonaws.com/0/100736/1f0376d6-eb02-67f1-2a0d-31fd7458f915.png)
このスターが何かという条件を指定して検索をかけるのがこの`has`になります。それぞれのスターの名称はマウスオンの通りで`yellow-star` / `red-star` / `orange-star` / `green-star` / `blue-star` / `purple-star` / `red-bang` / `orange-guillemot` / `yellow-bang` / `green-check` / `blue-info` / `purple-question`です。

# コードと解説

では最後にコードとさらっとした解説を載せて終わろうと思います。例として、ある8月1日から10月1日にYouTubeから届いたメールを取得してスプレッドシートに貼り付けるコードを載せてみます。

```js
function writeGmailToSpreadSheet() {
  var sheet = SpreadsheetApp.getActiveSheet().clear();
  var threads = GmailApp.search('from:noreply@youtube.com after:2016/8/1 before:2016/10/1');
  var row = 2; // 1行目はヘッダ
 
  for(var n in threads){
    var thread = threads[n];   
    var msgs = thread.getMessages();
    for(m in msgs){
      var msg = msgs[m];
      var date = msg.getDate();
      var subject = msg.getSubject();
     
      sheet.getRange(row,1).setValue(date);
      sheet.getRange(row,2).setValue(subject);
      row++;
    }
  }
}
```

■コンテンツをクリアしている部分について

上記のコードでは`.clear()`を使って綺麗さっぱり消してからシートに書き込んでいますが、元々セルに書き込んだ関数は消して欲しくない、という場合は`.clearContents()`を使えば実現できます。

消す範囲を指定することもできて、上記の場合だとアクティブなシート全体をクリアするようになっていますが、`sheet.getRange("A1:A10").clear();`などのように範囲を指定すればその部分だけ消すことも出来ます。

それと今回の場合は毎回コンテンツを消すという処理にしていますが、前回の続きから追加で書き込みたいという場合は2行目を`var sheet = SpreadsheetApp.getActiveSheet();`、4行目を`var row = sheet.getLastRow() + 1;`にすればOKです。

■情報の取得部分について

今回のコードでは日付と件名しか取得していませんが、本文、Bccなどを取得することもできます。詳しくは[このページ](https://developers.google.com/apps-script/reference/gmail/gmail-message)のメソッドを御覧ください。