library net/smtp

[edit]

要約

メールを送信するためのプロトコル SMTP (Simple Mail Transfer Protocol) を扱うライブラリです。

ヘッダなどメールのデータを扱うことはできません。 SMTP の実装は [RFC2821] に基いています。

使用例

とにかくメールを送る

SMTP を使ってメールを送るにはまず SMTP.start でセッションを開きます。第一引数がサーバのアドレスで第二引数がポート番号です。ブロックを使うと File.open と同じように終端処理を自動的にやってくれるのでおすすめです。

require 'net/smtp'
Net::SMTP.start( 'smtp.example.com', 25 ) {|smtp|
  # use smtp object only in this block
}

smtp-server.example.com は適切な SMTP サーバのアドレスに読みかえてください。通常は LAN の管理者やプロバイダが SMTP サーバを用意してくれているはずです。

セッションが開いたらあとは Net::SMTP#send_message でメールを流しこむだけです。

require 'net/smtp'

Net::SMTP.start('smtp.example.com', 25) {|smtp|
  smtp.send_message(<<-EndOfMail, 'from@example.com', 'to@example.net')
From: Your Name <from@example.com>
To: Dest Address <to@example.net>
Subject: test mail
Date: Sat, 23 Jun 2001 16:26:43 +0900
Message-Id: <unique.message.id.string@yourhost.example.com>

This is a test mail.
  EndOfMail
}

セッションを終了する

メールを送ったら Net::SMTP#finish を呼んでセッションを終了しなければいけません。 File のように GC 時に勝手に close されることもありません。

# using SMTP#finish
require 'net/smtp'
smtp = Net::SMTP.start('smtp.example.com', 25)
smtp.send_message mail_string, 'from@example.com', 'to@example.net'
smtp.finish

またブロック付きの Net::SMTP.start, Net::SMTP#start を使うと finish を呼んでくれるので便利です。可能な限りブロック付きの start を使うのがよいでしょう。

# using block form of SMTP.start
require 'net/smtp'
Net::SMTP.start('smtp.example.com', 25) {|smtp|
  smtp.send_message mail_string, 'from@example.com', 'to@example.net'
}

文字列以外からの送信

ひとつ上の例では文字列リテラル (ヒアドキュメント) を使って送信しましたが、 each メソッドを持ったオブジェクトからならなんでも送ることができます。以下は File オブジェクトから直接送信する例です。

require 'net/smtp'

Net::SMTP.start('your.smtp.server', 25) {|smtp|
  File.open('Mail/draft/1') {|f|
    smtp.send_message f, 'from@example.com', 'to@example.net'
  }
}

HELO ドメイン

SMTP ではメールを送る側のホストの名前 (HELO ドメインと呼ぶ) を要求されます。HELO ドメインは Net::SMTP.start, Net::SMTP#start のキーワード引数 helo に指定します。たいていの SMTP サーバはこの HELO ドメインによる認証はあまり真面目に行わないので (簡単に偽造できるからです) デフォルト値を用いて問題にならないことが多いのですが、セッションを切られることもあります。そういうときはとりあえず HELO ドメインを与えてみてください。もちろんそれ以外の時も HELO ドメインはちゃんと渡すのがよいでしょう。

require 'net/smtp'
Net::SMTP.start('smtp.example.com', 25, helo: 'yourdomain.example.com')

よくあるダイヤルアップホストの場合、HELO ドメインには ISP のメールサーバのドメインを使っておけばたいてい通ります。

SMTP認証

Net::SMTP は PLAIN, LOGIN, CRAM MD5 の3つの方法で認証をすることができます。 (認証については [RFC2554], [RFC2195] を参照してください)

認証するためには、Net::SMTP.start もしくは Net::SMTP#start の引数に追加の引数を渡してください。

# 例
require 'net/smtp'
Net::SMTP.start('smtp.example.com', 25,
                 user: 'your_account', password: 'your_password', authtype: :cram_md5)

TLSを用いたSMTP通信

Net::SMTP[RFC3207] に基づいた STARTTLS を用いる方法、もしくは [RFC8314] に基づいた方法 (ポート465を用い、通信全体をTLSで包む) によるメール送信の暗号化が可能です。

この2つは排他で、同時に利用できません。

TLSを用いることで、通信相手の認証、および通信経路の暗号化ができます。ただし、現在のメール送信の仕組みとして、あるサーバから別のサーバへの中継を行うことがあります。そこでの通信が認証されているか否か、暗号化されているか否かはこの仕組みの範囲外であり、なんらかの保証があるわけではないことに注意してください。メールそのものの暗号化や、メールを送る人、受け取る人を認証する必要がある場合は別の方法を考える必要があるでしょう。

TLS を使用したい場合は enable_tls を使用します。

require 'net/smtp'
# TLSの例
smtp = Net::SMTP.new('smtp.example.com', 465)
smtp.enable_tls
smtp.start do
  # send messages ...
end

サーバーが STARTTLS をサポートしている場合は自動的に STARTTLS を使用します。サーバーが STARTTLS をサポートしているのに STARTTLS を使用したくない場合は Net::SMTP#disable_starttls を使用します。

require 'net/smtp'
# STARTTLSを使用したくない例
smtp = Net::SMTP.new('smtp.example.com', 25)
smtp.disable_starttls
smtp.start do
  # send messages ...
end

デフォルトではサーバー証明書の検証を行い、正当な証明書でない場合は OpenSSL::SSL::SSLError 例外が発生します。証明書の検証を行いたくない場合は +tls_verify: false+ を指定します。

require 'net/smtp'
# 証明書の検証を行いたくない場合
Net::SMTP.start('192.168.1.1', 25, tls_verify: false) do |smtp|
  # send messages ...
end

サーバー証明書に引数で指定したホスト名が含まれていなければ OpenSSL::SSL::SSLError 例外が発生します。証明書に含まれない名前(IPアドレス等)で接続したい場合は、+tls_hostname+ で証明書のホスト名を指定します。

require 'net/smtp'
# 証明書と異なるホスト名で接続する場合
Net::SMTP.start('192.168.1.1', 25, tls_hostname: 'smtp.example.com') do |smtp|
  # send messages ...
end

クラス

Net::SMTP

SMTP のセッションを表現したクラスです。

Net::SMTP::Response

Net::SMTP の内部用クラスです。

Net::SMTPSession

Alias of Net::SMTP

モジュール

Net::SMTPError

SMTP 関連の例外に include されるモジュールです。

例外クラス

Net::SMTPAuthenticationError

SMTP 認証エラー(エラーコード 530)に対応する例外クラスです。

Net::SMTPFatalError

SMTP 致命的エラー(エラーコード 5xx、 ただし500除く)に対応する例外クラスです。

Net::SMTPServerBusy

SMTP 一時エラーに対応する例外クラスです。 SMTP エラーコード 420, 450 に対応します。

Net::SMTPSyntaxError

SMTP コマンド文法エラー(エラーコード 500) に対応する例外クラスです。

Net::SMTPUnknownError

サーバからの応答コードが予期されていない値であった場合に対応する例外クラスです。サーバもしくはクライアントに何らかのバグがあった場合に発生します。

Net::SMTPUnsupportedCommand

サーバで利用できないコマンドを送ろうとした時に発生する例外のクラスです。