ウェブサイトの会員登録なんかでメール送信をプログラムで書く機会は結構あると思います。
基本的に他所に書かれてある物を集めただけですが紹介したいと思います。主に自分参照用に。
Mailライブラリーを使う
TMailには伝統がありますが、使い方が結構難しかった記憶があるので、今のRailsで使っているというMailというライブラリーを使ってみます。
gem install mail
でインストールできます。
1. メールを作る
メール本文のオブジェクトを作ります。
require 'mail'
mail = Mail.new do
from 'KitaitiMakoto@example.net'
to 'KitaitiMakoto@example.net'
subject 'Mail from Mail'
body 'There is a body.'
end
2. メールを送る
SMTPの設定をした後で、#deliver!
を呼び出します。
mail.delivery_method :smtp, { address: 'smtp.example.net',
port: 587,
domain: 'example',
user_name: 'KitaitiMakoto',
password: ($stderr.print 'password> '; gets.chomp) }
mail.deliver!
これを実行すると、メールが送れます。
ruby ./mail.rb
パスワードをエコーバックしないとか、環境変数や設定ファイルで設定するとか、そういう処理くらいは入れたほうがいいですかね?
3. クラスメソッドを使う
クラスメソッドだけで送信処理をすることもできます。
require 'mail'
Mail.defaults do
delivery_method :smtp, { address: 'smtp.example.net',
port: 587,
domain: 'example',
user_name: 'KitaitiMakoto',
password: ($stderr.print 'password> '; gets.chomp) }
end
Mail.deliver do
from 'KitaitiMakoto@example.net'
to 'KitaitiMakoto@example.net'
subject 'Mail from Mail'
body 'There is a body.'
end
4. オフラインで確認する
僕はオフラインで開発をすることが多いので、また、そうではなくても一々メールサーバーに接続したくないことも多いでしょう。テストの時など。
そういう時には、メールメッセージの送り先や内容だけを確認できます。
puts mail.to
puts mail.body
変数を使ってtoやbodyを指定している場合に便利でしょう。
ActionMailerを使う
RailsではMail gemを直接触ることはなくて、実際にはActionMailerを触ることになると思います。
これは、勿論Railsを使っていなくても便利な物です。
gem install actionmailer
でインストールします。
1. 環境の設定
設定はActionMailer::Base
のクラスメソッドを通して行います。
require 'action_mailer'
ActionMailer::Base.delivery_method = :smtp
ActionMailer::Base.smtp_settings = {
address: 'smtp.example.net',
port: 587,
domain: 'example',
user_name: 'KitaitiMakoto',
password: ($stderr.print 'password> '; gets.chomp)
}
2. メール送信用クラスの作成
メール送信内容はActionMailer::Base
の子クラスを通じて組み立てます。
class SampleMailer < ActionMailer::Base
def first_example(body)
mail(
to: 'KitaitiMakoto@example.net',
from: 'KitaitiMakoto@example.net',
subject: 'Mail from SampleMailer',
body: body.to_s
)
end
end
3. メールを送る
(mail
メソッドを呼んでいるだけですが)メール送信処理はインスタンスメソッドとして定義していますが、呼び出す時にはクラスメソッドを使います。
require 'English'
if File.basename($PROGRAM_NAME) == File.basename(__FILE__)
SampleMailer.first_example('There is a body.').deliver
end
ruby ./actionmailer.rb
でメールを送ります。
テンプレートファイルを使う
メール本文をプログラムにハードコードするのはあり得ないので、テンプレートを使いたいですよね(送信先等の管理は特別なことが無いので省略)。
1. テンプレートファイルの場所を指定
ActionMailer::Baseのクラスメソッドを使って、テンプレートファイル(を探す起点)の場所を指定します。
require 'action_mailer'
ActionMailer::Base.prepend_view_path File.expand_path('../templates', __FILE__)
# (その他設定)
2. メール送信メソッドをテンプレート版に対応させる
RailsのActionControllerのrespond_to
のようにして「テンプレートを使う」ということを指定できます。
これもRailsのビューテンプレートと同じように、インスタンス変数をテンプレート側でも使えます。
class TemplateMailer < ActionMailer::Base
def template_example(name)
@name = name
mail(
to: 'KitaitiMakoto@example.net',
from: 'KitaitiMakoto@example.net',
subject: 'Mail from TemplateMailer',
) do |format|
format.text
end
end
end
format.html
と書くとHTMLメールを送ってくれるようです。
3. テンプレートファイルを作る
1.で指定したように、テンプレートファイルは(ここでは)templates
ディレクトリー以下に作ります。
ディレクトリー名にはクラス名をスネークケースにした物、ファイル名にはメソッド名を使います。テキストメールには.text.erb
を、HTMLメールには.html.erb
を付けます。
上の例だと
templates/template_mailer/template_example.text.erb
というファイル名になります。
There is <%= @name %>'s body.
4. メールを送る
メールの送信方法は変わりません。ので、送信せずに内容だけ確認するようにする、ということに挑戦してみましょう。
こうすればテストもしやすくなります。
require 'English'
if File.basename($PROGRAM_NAME) == File.basename(__FILE__)
mail = TemplateMailer.template_example('北市真')
puts mail.body
end
deliver
を呼ばずに body
属性を確認します。
ruby ./template.rb
で実行できます。
password>
There is 北市真's body.
あ、SMTP関係の設定はいりませんね。
ネストしたモジュールでのテンプレートファイル
さて、バッチ処理でメールを送る場合など、クラスがモジュールの中にあることも多いと思います。
# ActionMailerの設定色々
# ActionMailer::Base...
module Batch
class Aggregate
# ...
# 色々のバッチ処理
# ...
def report_done
Mailer.done.deliver
end
def report_error(exception)
# 例外情報からエラーメッセージを作る
# error_message = ...
Mailer.error(error_message).deliver
end
class Mailer < ActionMailer::Base
def done
# 正常終了を報告するメールを送る
end
def error(error_message)
# エラーを報告するメールを送る
end
end
end
end
こういう時のテンプレートの場所は、モジュールのネスト分だけディレクトリーを掘った物になります。上の例だと、
- templates/batch/aggregate/mailer/done.text.erb
- templates/batch/aggregate/mailer/error.text.erb
の二つのファイルを使うことになります。
参考
Mailライブラリーについてはライブラリーその物のREADMEが充分わかり易い物です。
ActionMailer
ActionMailerについては、日記「発狂する近況」の記事(「RubyからGMailにメールを送る テキスト編」と「html編」)がとても参考になりました。
テンプレートファイルを置く場所については、ActionMailerのエラーメッセージを見て理解しました。