electronでメールクライアントを作ってみる(IMAP(Gmail)サーバに接続する編)


# 前回までのあらすじ

* そういえばelectronデモしか触ってない
* よし、ひとまずどんなもの作りたいのか洗い出してみるか。
* electronが動く環境を作ったよ！

# 今回の目標

IMAPでgmailにあるメールを一覧で表示する。
(タイトルからお察しの通り、今回そこまで行けていません。)

# Node.jsのライブラリを選定する

いくつか候補はあるようなのだが、今回は簡単に書けるinboxを利用してみる。
[メールをトリガーにした処理がかんたんにかけるNode.jsの「inbox」](http://ayapi.github.io/posts/observingimaponnode/)

# ライブラリ導入

開発するプロジェクトまでディレクトリ移動して以下コマンドを打てばOK
Node環境構築とかは以下の記事に書いた。

(electronでメールクライアントソフトを作ってみる(環境構築編)[http://qiita.com/hitenkoku/items/d6bc59dd6e6477c70723]

```bash
$ npm install inbox
```

# Gmailにアクセスをしてみる

inboxの使い方を以下URLソースコードとinboxのGitHubに記載されているreadmeをもとに作ってみる。

* [Gmailの新着メールをNode.jsを使って受信する](http://qiita.com/daikissdd/items/0773eb24b236c23b9ec8)
* [inbox(GitHub)](https://github.com/pipedrive/inbox)

```javascript:mailconnector.js
var inbox = require('inbox');
var client = inbox.createConnection(false, 'imap.gmail.com', {
     secureConnection: true
    ,auth: {
         user:'(gmailメールアドレス)'
        ,pass:'(パスワード)'
    }
});

client.connect();

client.on('connect', function() {
    console.log('connected');
    client.close();
});

client.on('close', function() {
    console.log('disconnected');
});
```

つないでそのあとに切断するだけという簡単なコード。
connectedとdisconnectedが出てくれば問題ないはず。

以下コマンドで実行してみる。

```bash
$ node mailconnect.js
disconnected
```
ん？connectされてない……

connectされずにdisconnectだけされるのは現実だけで十分なんだｙ(ry)

とりあえず色々情報収集をしてみたところ
Google側のセキュリティ強化が原因のようです。
まぁ、セキュリティがらみだし、しかたないところかと。

* [GmailのIMAPログインに失敗した時の対処法](http://qiita.com/piyo7/items/080cbb297e2326c9497c)

* [メーラーからGmailへの接続時に認証（パスワード）のエラーが生じる場合の対処方法 (1/2)](http://www.atmarkit.co.jp/ait/articles/1409/03/news109.html)

「安全性の低いアプリの許可」を出すのもどうかと思うので
以下記事を参考にしてOAuth2によるログインをできるようにします。

* [Google APIのAccess Tokenをお手軽に取得する](http://qiita.com/shin1ogawa/items/49a076f62e5f17f18fe5)

* [Using OAuth 2.0 for Mobile and Desktop Applications](https://developers.google.com/identity/protocols/OAuth2InstalledApp#choosingredirecturi)

* [Google Gmail APIでメールを取得する](http://qiita.com/ryurock/items/4b063372ede81780c3c8)

* [Choose Auth Scopes(Gmail API)](https://developers.google.com/gmail/api/auth/scopes)

Qiitaの記事では許可リクエストページに遷移するためのredirect_uriはデスクトップだったらurn:ietf:wg:oauth:2.0:oobで固定だよ書いてありましたがGoogle側でこの値は受け持たなくなったようです。

私はredirect_uriはhttp://127.0.0.1 を指定して変なところには飛ばないようにしておきました。一端scopeはメッセージの読み込み、書き込み等をに利用させると思われる以下の通り設定しました。
```
scope=https://www.googleapis.com/auth/gmail.compose
```

ブラウザで許可リクエストの画面が出てきました。

そのページで許可を出すとリダイレクトで127.0.0.1?code=...のURLにリダイレクトされます。codeの部分はrefreshToken発行のために必要になりますので、どっかメモ帳にでもコピーしておきます。

そしてrefreshToken取得のためにPOSTでAPIをたたきに行きます。
redirect_uriは許可リクエスト時に利用したものを出さないとエラーとなります。

```bash
$ curl https://www.googleapis.com/oauth2/v4/token  -X POST -d code=(コード) -d client_id=(クライアントID) -d client_secret=(クライアント秘密鍵) -d redirect_uri=(リダイレクトURL) -d grant_type=authorization_code -d access_type=offline
```

受理されると以下のようなレスポンスが帰ってくる。

```json
{
  "access_token":"(アクセストークン)",
  "expires_in":(アクセストークンの生存時間[秒]),
  "token_type":"Bearer",
  "refresh_token":"(リフレッシュトークン)"
}
```

これをinboxに食わせてみる

```javascript:mailconnector.js
var inbox = require('inbox');

var client = inbox.createConnection(false , 'imap.gmail.com', {
	 secureConnection: true
	,auth: {
		XOAuth2: {
			user:：'(gmailメールアドレス'
		 ,clientId: '(クライアントID)'
		 ,clientSecret: '(クライアント秘密鍵)'
		 ,refreshToken: '(リフレッシュトークン)'
		 ,accessToken: '(アクセストークン)'
		 ,timeout: 3600
		}
	}
});

client.connect();

client.on('connect', function() {
    console.log('connected');
    client.close();
});

client.on('close', function() {
    console.log('disconnected');
});
```

これでもう1回テストしてみる。

```bash
$ node mailconnector.js
events.js:141
      throw er; // Unhandled 'error' event
      ^

Error: Authentication failed
(以下省略)
```
ん？なんぞおかしい。キーも確認してみたがあってるっぽい。
もう少しログがほしいのでdebugをオンにしてみる。オンにするのは以下の通り
debug: trueを明記してもう一回動かしてみる

```javascript:変更箇所
var client = inbox.createConnection(false , 'imap.gmail.com', {
	 secureConnection: true
	,auth: {
		XOAuth2: {
			user:'(gmailメールアドレス'
		 ,clientId: '(クライアントID)'
		 ,clientSecret: '(クライアント秘密鍵)'
		 ,refreshToken: '(リフレッシュトークン)'
		 ,accessToken: '(アクセストークン)'
		 ,timeout: 3600
		}
	}
    ,debug: true
});
```

```bash
$ node mailconnector.js
(省略)
SERVER: A4 NO [AUTHENTICATIONFAILED] Invalid credentials (Failure)

```

Invalid Credentialとのこと。調査をしていたらgmailのアカウントロックされているとかあったが、どうも当てはまらない。もうだめぽと思っていたが、
以下inboxのissueに書いてあった。どうやら与える権限はフルコントロールよこせや！とのことらしい。

[Authentication failed with XOAuth2 createConnection · Issue #108 · pipedrive/inbox · GitHub](https://github.com/pipedrive/inbox/issues/108)

もう一回scopeを再設定して、キーを取得して実行する(debugを外しても外さなくてもOK.)
```bash
$ node mailconnector.js
connected
(省略)
disconnected
```

つながったやったー！
かなり長くなってしまったのでひとまず今回はここまでとします。
進捗もう息してません。

# 次回目標
* gmailアカウント情報別ファイル化。
* IMAPに接続してメール一覧取得(メイン画面に表示)
* クリックしたメール内容を表示