皆さんメール送信のテストはどのように実施していますか?
Mailtrap.io のようなテスト用のFake SMTPサーバーを提供するようなサービスを利用していますか?実はメール送信を上手にコントロールする方法があります、そうRailsならね。
今度、1ヶ月ほど台湾へ行ってくる予定の旅するエンジニア三宅です。
今回紹介するのはメール送信のテストをするためにAction Mailerを上手にコントロールする方法を紹介します。
ActionMailer::Base.register_interceptorの紹介
ステージング環境などでメール送信のテストを行いたいという時に、バッチで実行される一斉メール送信などを確認するのって難しいですよね。
一度に大量にメールが送信されてしまいてんやわんやということにも。
そんなときはRailsに標準で用意されているActionMailer::Base.register_interceptor
を使ってみましょう。
Action Mailer Basics — Ruby on Rails Guides
http://guides.rubyonrails.org/v4.2/action_mailer_basics.html#intercepting-emails
上記のRails Guideのリンク先を読んでいただければわかると思いますが ActionMailer::Base.register_interceptor
を使うことでメール送信の処理をインターセプトできます。
まずは処理をインターセプトしたときに実行する処理が書かれたクラスを用意します。
# frozen_string_literal: true
class SandboxEmailInterceptor
class << self
def delivering_email(message)
return if allow_to_send_email?(message)
message.perform_deliveries = false
end
private
def allow_to_send_email?(message)
message.to.all? { |email| Settings.action_mailer.allow_to_send_emails.include?(email) }
end
end
end
難しい処理ではありませんが、簡単に説明するとメール送信前にdelivering_email
が呼び出されるので、そこで送信可能なメールアドレスであれば送信するという処理になっています。
上記のコードでは送信先が全て許可されたメールアドレスであることを要求していますが、用途に分けて処理を変えることも可能です。(送信可能な人だけに送信するとか)
perform_deliveries
をfalse
にするとメール送信がキャンセルされるようになっています。
設定にはRailsでの開発ではおなじみのrailsconfig/configを使用しています。
Action Mailer Basics — Ruby on Rails Guides
http://guides.rubyonrails.org/v4.2/action_mailer_basics.html#action-mailer-configuration
あとはinitializersにファイルを作って上記のクラスを使ってメール送信をインターセプトするように設定します。今回の場合はsandbox_email_inceptor.rbと名付けました。
# frozen_string_literal: true
ActionMailer::Base.register_interceptor(SandboxEmailInterceptor) if Settings.action_mailer.sandbox
これで Settings.action_mailer.sandbox
をtrue
にすることで、Settings.action_mailer.allow_to_send_emails
に設定されているメールだけにメールが送信されるようになります。
Appendix
Railsで用意された機能のように書いてありますが、実はAction Mailerでは内部でmikel/mailというgemが使用されており、メール送信をインターセプトする処理も、その中で書かれています。
詳しい処理については知りたい方は、RailsのActionMailer::Base.register_interceptor
からコードを辿っていくと面白いかと思います。
それほど複雑なコードではないので、すぐに流れが追えるのではないかと思います。
内部の処理を読んでみると勉強になることもあるので、自身で読んでみることをオススメします。
最後に
駆け足でActionMailer::Base.register_interceptor
について紹介しましたが、いかがでしたでしょうか?
Railsには便利な仕組みが最初から用意されていて本当に便利ですよね。
皆さんもRails Guideを読み込んでみると、今まで知らなかったような便利な機能が見つかるかもしれません。
Railsって本当に良いもんですね。さよなら、さよなら、さよなら。