TL;DR
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の使い方の説明になっています。
ActionMailboxはたしかに素晴らしい機能ですが、Rails6(以上)を使っていない方には導入コストが重過ぎです。仮にRails6(以上)を使っているとしても、MailgunやMandrillのような有料の特定のサービスを契約しないと使えません。
実はかの有名Gem mikel/mail を使えば、OutlookやThunderbirdのように、既存のEmailアカウントからメールを読み取ることもできるのです。
方法解説
[非推奨] retriever_method
について
GitHubのReadmeもGoogle先生の検索結果も、ほとんどは下記のようなコードが提示されています。
Mail.defaults do
retriever_method :imap, address: 'imap.mailbox.org',
user_name: '<username>', password: '<password>',
port: 993, enable_ssl: true
end
しかし上記書き方だと、接続情報がグローバルに設定されて、複数のアカウントを扱う際は不便です。
Rubydocを読む、下記の書き方もできるとわかりました。
[推奨] IMAPで受信
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, # 最大10メールを取得する
read_only: true, # メールを取得する際、サーバーに「既読」をつかない(IMAPのみ)
keys: ['FROM', 'microsoft'] # 差出人に「microsoft」の文字列があるか検索(IMAPのみ)
)
emails[0].subject
=> "Microsoft アカウントのセキュリティ情報の確認"
emails[0].from
=> ["account-security-noreply@accountprotection.microsoft.com"]
参考:
[非推奨] POP3で受信
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 アカウントへようこそ"
余談
IMAPかPOP3か
結論言うと、IMAPが使える時は断然にIMAPを選ぶべきです、なぜなら「検索条件で一部のメールのみ取得」ができるです。
IMAPの検索条件について
添付ファイルを持つメールのみ抽出したい
こちらの記事によるとHEADER Content-Type multipart/mixed
という条件が良さそうです。
一部画像付きメールでは.attachments
で画像も反応してしまうので、multipart/mixed
で抽出した方は「ザ添付ファイル」のみ検出できるのです。
複数条件で検索したい
IMAPの検索条件はポーランド記法を用いられています。
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
日本語で検索したい
残念ながら難しいそうです。Outlookの場合はsearch_charset: 'UTF-8'
を設定すると、下記のエラーが返ってきました。
Net::IMAP::NoResponseError: The specified charset is not supported.
なぜHotmail(Outlook)が例
Gmailさんも手軽で良さそうですが、プログラムで触る際に、アプリパスワードが必要です。アプリパスワードをONにするには、2段階認証が必要です。また、GmailはデフォルトPOP3もIMAPもオフにしているので、設定も面倒です。
現段階デモストレーション用にすぐ取得できるメールはHotmail(Outlook)のみです。(Yahooメールも携帯番号が必要となったので)