Rubyでメールをシンプルに受信したい時

# TL;DR
```rb
require 'mail' # Railsは不要

# 接続情報の設定
imap_handler = Mail::IMAP.new(
  address: 'outlook.office365.com', user_name: '<username>', password: '<password>',
  port: 993, enable_ssl: true,
)
# 特定条件でメールを検索(ここの条件は`未読かつ添付ファイル付き`)
emails = imap_handler.find(read_only: true, keys: 'UNSEEN HEADER Content-Type multipart/mixed')

emails.size
=> 1
emails[0].subject
=> "添付ファイルテスト"
emails[0].attachments
=> [#<Mail::Part:70339964299180, Multipart: false, Headers: <Content-Type: application/pdf; name="test.pdf">, <Content-Transfer-Encoding: base64>, <Content-Disposition: attachment; filename="test.pdf">, <Content-ID: <f_ljl7cuad0>>, <X-Attachment-Id: f_ljl7cuad0>>]
```

# はじめに
RubyやRailsで`メール受信`をキーワードで検索すると、ほとんどの検索結果が[**ActionMailbox**](https://railsguides.jp/action_mailbox_basics.html)の使い方の説明になっています。
ActionMailboxはたしかに素晴らしい機能ですが、Rails6(以上)を使っていない方には導入コストが重過ぎです。仮にRails６(以上)を使っているとしても、[Mailgun](https://www.mailgun.com/)や[Mandrill](https://mandrillapp.com/login/)のような有料の特定のサービスを契約しないと使えません。
実はかの有名Gem **[mikel/mail](https://github.com/mikel/mail)** を使えば、OutlookやThunderbirdのように、既存のEmailアカウントからメールを読み取ることもできるのです。

# 方法解説
## [非推奨] `retriever_method`について
GitHubのReadmeもGoogle先生の検索結果も、ほとんどは下記のようなコードが提示されています。

```rb
Mail.defaults do
  retriever_method :imap, address: 'imap.mailbox.org',
                          user_name: '<username>', password: '<password>',
                          port: 993, enable_ssl: true
end
```

しかし上記書き方だと、接続情報がグローバルに設定されて、複数のアカウントを扱う際は不便です。
Rubydocを読む、下記の書き方もできるとわかりました。

## [推奨] IMAPで受信
```rb
imap_handler = Mail::IMAP.new(
  address: 'outlook.office365.com', user_name: '<username>', password: '<password>',
  port: 993, enable_ssl: true,
)
emails = imap_handler.find(
  what: :last, # 新しいほうのメールを取得する
  order: :desc, # 取得したメールは新しい順で並び替える
  count: 10, # 最大１０メールを取得する
  read_only: true, # メールを取得する際、サーバーに「既読」をつかない(IMAPのみ)
  keys: ['FROM', 'microsoft'] # 差出人に「microsoft」の文字列があるか検索(IMAPのみ)
)
emails[0].subject
=> "Microsoft アカウントのセキュリティ情報の確認"
emails[0].from
=> ["account-security-noreply@accountprotection.microsoft.com"]
```
参考: 
- [Class: Mail::IMAP](https://rubydoc.info/github/mikel/mail/Mail/IMAP#initialize-instance_method)
- [IMAP4のSEARCH検索条件の一覧](https://atmarkit.itmedia.co.jp/fnetwork/rensai/netpro09/imap4-searchoption.html)


## [非推奨] POP3で受信
```rb
pop3_handler = Mail::POP3.new(
  address: 'outlook.office365.com', user_name: '<username>', password: '<password>',
  port: 995, enable_ssl: true,
)
emails = pop3_handler.find(what: :first, count: 50, delete_after_find: true)

emails[0].subject
=> "新しい Outlook.com アカウントへようこそ"
```
参考: [Class: Mail::POP3](https://rubydoc.info/github/mikel/mail/Mail/POP3#initialize-instance_method)


# 余談
## IMAPかPOP3か
結論言うと、IMAPが使える時は断然にIMAPを選ぶべきです、なぜなら「[検索条件](https://atmarkit.itmedia.co.jp/fnetwork/rensai/netpro09/imap4-searchoption.html)で一部のメールのみ取得」ができるです。

## IMAPの検索条件について
### 添付ファイルを持つメールのみ抽出したい
[こちらの記事](https://mailbeenet.wordpress.com/2015/07/21/search-imap-folder-for-messages-with-attachments/)によると`HEADER Content-Type multipart/mixed`という条件が良さそうです。
一部画像付きメールでは`.attachments`で画像も反応してしまうので、`multipart/mixed`で抽出した方は「ザ添付ファイル」のみ検出できるのです。

### 複数条件で検索したい
IMAPの検索条件は[ポーランド記法](https://ja.wikipedia.org/wiki/%E3%83%9D%E3%83%BC%E3%83%A9%E3%83%B3%E3%83%89%E8%A8%98%E6%B3%95)を用いられています。
#### `AND`条件
デフォルトは`AND`になっているので、下記の書き方で十分です。

```
FROM microsoft SUBJECT Outlook
```

#### `OR`条件
予め`OR`をつけるべきです。

```
OR FROM microsoft SUBJECT Outlook
```

条件が多い場合はその分`OR`も複数書きます。
```
OR OR BODY Android SUBJECT Outlook FROM microsoft
```

#### 複合条件
```
OR (FROM microsoft SUBJECT Outlook) BODY Android
```
*※ 差出人に`microsoft`を含み、***かつ***件名に`Outlook`が入っているメール、***又は***本文に`Android`が存在するメールを検索します。*

参考: [IMAP search requires parentheses](https://www.limilabs.com/blog/imap-search-requires-parentheses)

#### 日本語で検索したい
残念ながら難しいそうです。Outlookの場合は`search_charset: 'UTF-8'`を設定すると、下記のエラーが返ってきました。

```
Net::IMAP::NoResponseError:  The specified charset is not supported.
```

## なぜHotmail(Outlook)が例
Gmailさんも手軽で良さそうですが、プログラムで触る際に、[アプリパスワード](https://support.google.com/mail/answer/185833?hl=ja)が必要です。アプリパスワードをONにするには、２段階認証が必要です。また、GmailはデフォルトPOP3もIMAPもオフにしているので、設定も面倒です。
現段階デモストレーション用にすぐ取得できるメールはHotmail(Outlook)のみです。（Yahooメールも携帯番号が必要となったので）


# 参考
- [mikel/mail](https://github.com/mikel/mail)
- [Class: Mail::IMAP](https://rubydoc.info/github/mikel/mail/Mail/IMAP#initialize-instance_method)
- [Class: Mail::POP3](https://rubydoc.info/github/mikel/mail/Mail/POP3#initialize-instance_method)
- [Class: Mail::Message](https://www.rubydoc.info/github/mikel/mail/Mail/Message)
- [メールアカウント設定時の「IMAP」と「POP3」の選び方](https://pr.toriaez.jp/navi/howto/2117.html)
- [IMAP4のSEARCH検索条件の一覧](https://atmarkit.itmedia.co.jp/fnetwork/rensai/netpro09/imap4-searchoption.html)
- [SEARCH IMAP FOLDER FOR MESSAGES WITH ATTACHMENTS](https://mailbeenet.wordpress.com/2015/07/21/search-imap-folder-for-messages-with-attachments/)
- [IMAP search requires parentheses](https://www.limilabs.com/blog/imap-search-requires-parentheses)
- [Ruby mail gem でPOP3メール受信＆削除＆添付保存](https://qiita.com/abeshi01/items/4e8b5e84b4ee9247890b)