Google Gmail APIでメールを取得する


Gmail APIでメールを取得するまで色々苦労したのでメモ
なんか知らないうちにOAuth2やら何やら色々しなくてはいけなくなったのね。。。

## 参考にしたサイト

* [Gmail APIを使ってメール送信するVBAマクロ(2)](http://www.ka-net.org/blog/?p=4538)
* [Gmail の Google API を使ってみました](http://arakanoj.com/gmail-%E3%81%AE-google-api-%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%A6%E3%81%BF%E3%81%BE%E3%81%97%E3%81%9F-1034.html)


## Google Developpers Consoleとは？

Googleの開発者向けに色々設定やら何やらをする所
APIを使いたい場合も必要です

## Google Developpers Consoleでプロジェクトを作成する

https://console.developers.google.com/project

に行くとプロジェクトを作成ボタンがあるので押してプロジェクトを作成してください。
多分いくつでもプロジェクトは作れると思うので自分は適当にAPI Projectとつけました。

## Google Developpers Consoleの【APIと認証 > API】でGmail APIをONにする

Gmail API という項目があるのでデフォルトがOFFになってるのでONにします。

## Google Developpers Consoleの【APIと認証 > 認証情報】のOAuthで新しいクライアントIDを作成する

自分はhubotに食わせるのが目的なのでバックグラウンドで実行するのが目的なので下記で設定をしました。(目的や用途によって選択は変わると思います。

* インストールされているアプリケーション
* インストールされているアプリケーションの種類
 * その他

## OAuthの許可リクエストページからcodeを取得する

https://accounts.google.com/o/oauth2/auth?client_id={OAuthのクライアントID}&redirect_uri=urn:ietf:wg:oauth:2.0:oob&scope=https://www.googleapis.com/auth/gmail.readonly&response_type=code&approval_prompt=force&access_type=offline


上記URLをブラウザで実行すると許可リクエストページに遷移しますので承認を押すと
「このコードをコピーし、アプリケーションに切り替えて貼り付けてください」
という簡素なページに遷移しますのでそのコードを控えて置いてください。

### scopeについて

scopeの値になにを入れればいいかわからず自分はハマりました。
簡単にいうと各APIでのパーミッション権限を指定する必要があります。
今回はgmail APiなので[Gmail scopes](https://developers.google.com/gmail/api/auth/scopes?hl=ja)からリード権限のスコープにしています。


## アクセストークンの取得

API実行時に必要なアクセストークンを取得します

```shell:/path/to/hoge
curl -d client_id={OAuthのクライアントID} -d client_secret={OAuthのクライアントシークレット} -d redirect_uri=urn:ietf:wg:oauth:2.0:oob -d grant_type=authorization_code -d code={さっき取得したコード} https://accounts.google.com/o/oauth2/token

# レスポンス
{
  "access_token" : "xxxxxxxxxxxxxxxxx",
  "token_type" : "Bearer",
  "expires_in" : 3600,
  "refresh_token" : "xxxxxxxxxxxxxxxxxxxxx"
}
```

## リフレッシュトークンからアクセストークンを取得

アクセストークンは30分で切れるらしいので、リフレッシュトークンから新しいトークンを再発行する為の手順です。（別に試すだけならやらなくてもよい)

```shell:/path/to/hoge
curl -d "client_id={OAuthのクライアントID}&client_secret={OAuthのクライアントシークレット}&refresh_token={先ほど取得したrefresh_token}&grant_type=refresh_token" https://accounts.google.com/o/oauth2/token

# レスポンス
{
  "access_token" : "xxxxxxxxxxxxxxxxxxxxxxxx",
  "token_type" : "Bearer",
  "expires_in" : 3600
}
```

このアクセストークンはAPI実行時に毎回必要になります。

### アクセストークンのパーミッションの確認方法

アクセストークンのscopeを適切に設定をしていないとAPIを実行した時に
「insufficientPermissions」というレスポンスが返ってきます。

パーミッションを確認するには

```
https://www.googleapis.com/oauth2/v1/tokeninfo?access_token={アクセストークン}
```

となります。

## Gmail メール一覧の取得

詳細は[Gmail API Users.messages: list](https://developers.google.com/gmail/api/)で


```shell:/path/to/hoge
curl -H "Authorization: Bearer {先ほど取得したアクセストークン}" https://www.googleapis.com/gmail/v1/users/me/messages/

#レスポンス

{
 "messages": [
  {
   "id": "xxxxxx",
   "threadId": "xxxx"
  },
  {
   "id": "xxxxxx",
   "threadId": "xxxx"
  },
  {
   "id": "xxxxxx",
   "threadId": "xxxx"
  },
   .
   .
   .
   .
  {
   "id": "xxxxxx",
   "threadId": "xxxx"
  }
 ],
 "nextPageToken": "xxxxxxxx",
 "resultSizeEstimate": 520
}
```

上記のidで特定のメールのメッセージの詳細を取得できます。

## Gmail メール本文の取得

詳細は[Gmail API Users.messages: get](https://developers.google.com/gmail/api/v1/reference/users/messages/get)で

```shell:/path/to/hoge
curl -H "Authorization: Bearer {先ほど取得したアクセストークン}" https://www.googleapis.com/gmail/v1/users/me/messages/{メール一覧で取得したid}

# レスポンス(一部抜粋)

 "id": "{メール一覧で取得したid}",
 "threadId": "メールのスレッドID",
 "labelIds": [分類されているラベルID1,分類されているラベルID2],
 "snippet": "本文のスニペット",
 "historyId": "9052307",
 "payload": {
  "partId": "",
  "mimeType": "text/plain",
  "filename": "",
  "headers": [
   {
    "name": "Delivered-To",
    "value": "受信者のメールアドレス"
   },
   {
    "name": "Received",
    "value": "by xx.xx.xx.xxx with SMTP id xxxxxx;        Thu, 25 Dec 2014 07:06:06 -0800 (PST)"
   },
   {
    "name": "X-Received",
    "value": "by xx.xx.xx.xxx with SMTP id xxxxxx;        Thu, 25 Dec 2014 07:05:32 -0800 (PST)"
   },
   {
    "name": "Return-Path",
    "value": "返信先のメールアドレス"
   },
   {
    "name": "From",
    "value": "メールアドレス(From)"
   },
   {
    "name": "to",
    "value": "メールアドレス(To)"
   },
   {
    "name": "Cc",
    "value": ""
   },
   {
    "name": "Date",
    "value": "Fri, 26 Dec 2014 00:05:26 +0900"
   },
   {
    "name": "MIME-Version",
    "value": "1.0"
   },
   {
    "name": "Content-Type",
    "value": "text/plain; charset=\"iso-2022-jp\""
   },
   {
    "name": "Content-Transfer-Encoding",
    "value": "7bit"
   },
   {
    "name": "Subject",
    "value": "メールの件名"
   },
   {
    "name": "Reply-To",
    "value": "返信先メールアドレス"
   },
   {
    "name": "X-Mail-Count",
    "value": "2476689"
   },
   {
    "name": "Precedence",
    "value": "bulk"
   },
   {
    "name": "X-QuickML",
    "value": "true"
   }
  ],
  "body": {
   "size": 1288,
   "data": "本文でベース64エンコードされた本文"
  }
 },
 "sizeEstimate": 3933
}
```

* メール件名
 * payload.headers[name: "subject"]
* メール本文
 * payload.body.data(base64urlエンコードされたもの)
 * [Online Base64URL decoder](http://kjur.github.io/jsjws/tool_b64udec.html)あたりで確認してみてください

になります。

なんか以外とメール取るのに苦労しました。。。。。(自分は)