CTC 教育サービス
[IT研修]注目キーワード Python UiPath(RPA) 最新技術動向 Microsoft Azure Docker Kubernetes
Webアプリケーションの開発をしていると、メールの送受信を扱う機会があると思います。RailsにはActionMailerというライブラリがありますが、今回はその中でも使われているMailライブラリ(*1)をご紹介いたします。
尚、本コラムは以下の環境で動作確認を行っています。
まずはインストールを行いましょう(*2)。以下のコマンドを実行します。
> gem install mail
正常に終了すればインストールの完了です。Rubyスクリプト上で使用するには「require "mail"」でロードします。
Mailクラスをnewすると、メールのひな型となるMail::Messageオブジェクトが生成されます。当該オブジェクトのsetterを利用して値を設定していきます。
require "mail"
mail = Mail.new mail.from = "from@example.co.jp" mail.to = "to@example.co.jp" mail.subject = "subject text" mail.body = "body text"
# newのブロック内で値を設定することも可能 mail = Mail.new do from "from@example.co.jp" to "to@example.co.jp" subject "subject text" body File.read("body.txt") end
# 任意のヘッダを設定 mail["Comments"] = "Some comments"
# SMTPのエンベロープも設定可能 mail.smtp_envelope_from = "envelope_from@example.co.jp" mail.smtp_envelope_to = "envelope_to@example.co.jp"
添付ファイルを設定するには、add_fileメソッドもしくはattachmentsメソッドを使用します。attachmentsを用いる場合には添付するデータそのものを渡す必要がありますが、add_fileの場合はファイルパスでOKです。
# カレントディレクトリのpicture.jpgを添付 mail.add_file = "./picture.jpg"
# カレントディレクトリのpicture.jpgをphoto.jpgとして添付 mail.attachments["photo.jpg"] = File.binread("./picture.jpg")
# add_fileはnewのブロック内でも使用可能 mail = Mail.new do add_file "./picture.jpg" end
text/plainなメールだけではなく、text/htmlを含むmultipart/alternativeなメールを作成することもできます。
mail = Mail.new do # text/plain部分 text_part do body "ruby mail text/plain" end
# text/html部分 html_part do body "<h1>ruby mail text/html</h1>" end end
# ブロック外で定義する場合はMail::Partクラスを使用 text_plain = Mail::Part.new do body "ruby mail text/plain" end
text_html = Mail::Part.new do body "<h1>ruby mail text/html</h1>" end
mail.text_part = text_plain mail.html_part = text_html
ローカルにあるファイルや文字列からMail::Messageオブジェクトを生成することができます。
# カレントディレクトリのmail.emlを取り込み local_mail = Mail.read("./mail.eml")
# 標準入力で受けたメール文字列の取り込み string_mail = Mail.new(STDIN.read)
作成したメールオブジェクトのdeliverメソッドを呼び出すことで、メールの送信が行えます。
mail = Mail.new do from "from@example.co.jp" to "to@example.co.jp" subject "subject text" body File.read("body.txt") end
mail.deliver
# Mailクラスの特異メソッドdeliverを使って、以下のようにも記述可能 Mail.deliver do from "from@example.co.jp" to "to@example.co.jp" subject "subject text" body File.read("body.txt") end
デフォルトでは以下の条件でメールを送信します。
接続先などを変更するには、delivery_methodを使用します。
mail.delivery_method(:smtp, address: "example.co.jp", port: 587, domain: "example.co.jp", authentication: :login, user_name: "<user_name>", password: "<password>" ) mail.deliver
第1引数にはsmtpやsendmailといった送信メソッド、第2引数には送信メソッドに対応する送信オプションを設定します。
以下にSMTP使用時の送信オプションを示します。
オプション | 内容 | 初期値 |
address | 接続先アドレスを設定 | localhost |
port | 接続ポートを設定 | 25 |
domain | HELOドメイン名を設定 | localhost.localdomain |
authentication | 認証方法を設定
|
nil |
user_name | 認証時のユーザ名を指定 | nil |
password | 認証時のパスワードを指定 | nil |
ssl(tlsでも可) | true設定時、SMTPSを使用 | nil |
enable_starttls_auto | true設定時、STARTTLSが使用可能な場合にSTARTTLSを使用 | true |
openssl_verify_mode | OpenSSLの検証モードを設定(*3) | nil |
また、Mail.defaultsを用いることでデフォルトの挙動を変更することができます。
Mail.defaults do delivery_method(:smtp, address: "example.co.jp", port: 587, domain: "example.co.jp", authentication: :login, user_name: "<user_name>", password: "<password>" ) end
# example.co.jpサーバ宛てにメールを送信 Mail.deliver do from "from@example.co.jp" to "to@example.co.jp" subject "subject text" body File.read("body.txt") end
受信用のメソッドを使用することで、メールサーバからメールを取得することができます。
Mail.all # 全件取得 Mail.first # 先頭1件取得 Mail.last # 末尾1件取得
# オプションを指定してメールを受信することも可能 Mail.find(count: 5, order: :desc, what: :all)
findに設定できる条件は、以下のようなものがあります。
オプション | 内容 | 初期値 |
count | 取得件数を設定 | 10 |
order | 取得順を設定
|
asc |
what | 取得方法を設定
|
first |
delete_after_find | true設定時、取得後にメールをサーバ上から削除 | false |
また、デフォルトでは以下の条件でメールサーバへの接続を行います。
接続先などを変更するにはretriever_methodを使用します。
Mail.defaults do retriever_method(:pop3, address: "example.co.jp", port: 110, user_name: "<user_name>", password: "<password>" ) end
Mail.all # example.co.jp上のメールを受信
送信時と同様に、第1引数にpop3やimapといった受信メソッド、第2引数に対応するオプションを設定します。
以下にPOP3使用時の受信オプションを示します。
オプション | 内容 | 初期値 |
address | 接続先アドレスを設定 | localhost |
port | 接続ポートを設定 | 110 |
user_name | 認証時のユーザ名を指定 | nil |
password | 認証時のパスワードを指定 | nil |
enable_ssl | true設定時、SSLを使用 | false |
メールから件名や本文などといった情報を取り出すには、まず前述の「既存データの取り込み」を行ってMail::Messageオブジェクトを生成します。当該オブジェクトにはsetterに対応するgetterがありますのでそれらを用いて情報を取得します。
尚、ヘッダ外の情報を取得する際はdecodedを使用します。
mail = Mail.read("./mail.eml")
mail.from.first mail.to.first mail.subject mail.date
# ヘッダ外(本文など)はdecodedを使用 mail.body.decoded
# 任意のヘッダ情報を取得 mail.header["X-Mailer"]
# エンベロープの情報を取得 mail.envelope_from mail.envelope_date
また、multipartなメールから情報を取得することもできます。
mail = Mail.read("./multipart_mail.eml") mail.multipart? #=> true
mail.text_part.decoded # text/plain部分の取得 mail.html_part.decoded # text/html部分の取得
# 添付ファイルへのアクセス mail.attachments.first.filename mail.first.mime_type
# 添付ファイルの取得 File.open("picture.jpg", "w+b") do |f| f.write(mail.attachments.first.body.decoded) end
現在の主要なメールクライアントはほとんどUTF-8に対応していると思いますが、それでも何らかの事情でISO-2022-JPのメールを扱わないといけないケースもあるでしょう。Rubyの場合ISO-2022-JPはダミーエンコーディング(*4)となっていることもあり、そのままでは扱いづらいです。
そのような際はmail-iso-2022-jp(*5)というライブラリをお勧めします(*6)。詳しくはmail-iso-2022-jpのGitHubページをご覧ください。
以上、長くなってしまいましたがMailライブラリの説明でした。GitHub上にあるmailのREADMEにも詳しい説明がございますのであわせてご覧ください(*7)。
メールそのものの作成や解析を自前で行うのは、かなり骨の折れる作業だと思います。本ライブラリはメールの送受信も行えますが、そういった部分にこそより力を発揮するのではないでしょうか。Rubyでメールを扱う際には是非Mailライブラリを使ってみてください。
それでは、Enjoy Ruby!
*1:https://github.com/mikel/mail
*2:Rails3以降をお使いであれば、ActionMailerの依存パッケージとしてインストールされていると思います。
*3:詳しくはRubyリファレンスマニュアルOpenSSLをご覧ください。http://doc.ruby-lang.org/ja/1.9.3/class/OpenSSL=3a=3aSSL=3a=3aSSLContext.html#I_VERIFY_MODE--3D
*4:http://doc.ruby-lang.org/ja/1.9.3/doc/spec=2fm17n.html#encoding
*5:https://github.com/kuroda/mail-iso-2022-jp
*6:現在プルリクエスト中みたいですので、そのうちmail本体にマージされるかもしれません。
*7:本コラムを書くにあたっても参考にさせていただきました。
[IT研修]注目キーワード Python UiPath(RPA) 最新技術動向 Microsoft Azure Docker Kubernetes