DesignAssembler

備忘録に近い

ActionMailerで環境を判別してメール送信前にsubjectやtoを変更する

Railsから簡単にメールを送信できるActionMailerについてです。

概要

Railsアプリケーションからメールを送る際、production以外の環境ではメールの宛先や件名を変えたい時の構築方法です。
ここではgmailを使用してメールを送信します。

記事書いたらただただActionMailerで遊ぶ記事になっていました。

ActionMailer

RailsにはActionMailerという便利なモジュールがあります。ActionMailer::Baseクラスを継承することで非常に簡単にメールを送信する事が出来るようになります。

ActionMailerについてはrailsguidesに書いてあり、次に紹介するInterceptorは3-8にあります。
Action Mailer の基礎 | Rails ガイド

Interceptor

Interceptor
和訳すると、

【名詞】【可算名詞】
1横取りする人[もの].
2さえぎる人[もの].

とあります。(研究社 新英和中辞典より)

Railsでは2番の"さえぎるもの"の意味でしょう。

ActionMailerのInterceptorは、全てのメール配信直前にその送信するメールを編集する事ができるもので、この機能を使って実装します。


テストアプリケーションの作成

RailsGuidesに沿ってテストアプリケーションを作成していきます。

各種ファイルの生成

$ rails new mailer_test
$ cd mailer_test
$ rails g controller mail index

まずはRailsアプリケーションの作成です。
次にメーラークラスを生成します。

$ rails g mailer SendEmail welcome_email

welcome_emailメソッドを含んだ、ActionMailerクラスを継承したSendEmailクラスを作成します。
以下のような出力になると思います。

      create  app/mailers/send_email.rb
      create  app/mailers/application_mailer.rb
      invoke  erb
      create    app/views/send_email
      create    app/views/layouts/mailer.text.erb
      create    app/views/layouts/mailer.html.erb
      create    app/views/send_email/welcome_email.text.erb
      create    app/views/send_email/welcome_email.html.erb
      invoke  test_unit
      create    test/mailers/send_email_test.rb
      create    test/mailers/previews/send_email_preview.rb

app/views/send_email/以下の2ファイルが送信されるメールテンプレートファイルになります。

.html.erbファイルがhtmlメールのためのテンプレートファイルで、.text.erbファイルがプレーンテキストメールのテンプレートファイルになります。

設定ファイルの記述

config/environments/development.rbに追加します。

#config/environments/development.rb
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
  address:              'smtp.gmail.com',
  port:                 587,
  domain:               'smtp.gmail.com',
  user_name:            '<ユーザー名@gmail.com>',
  password:             '<パスワード>',
  authentication:       'plain',
  enable_starttls_auto: true  }

送信するメールの設定

app/mailers/send_email.rbのwelcome_emailメソッドの中に送信するメールの設定を記述します。

#app/mailers/send_email.rb
class SendEmail < ApplicationMailer

  def welcome_email
    @greeting = "Hi"
    
    mail to: "<送信先メールアドレス>", subject: "Welcome to this app"
  end
end

送信してみる

以下をコンソールに書けばメールを送信できます。

$ rails c
Loading development environment (Rails 4.2.4)
2.1.6 :001 > SendEmail.welcome_email.deliver

確認できました。

f:id:hyottokoaloha:20151010201450p:plain

Net::SMTPAuthenticationErrorが出て送信できない方は以下のページからアクセス許可を行ってください。
*1
Allowing less secure apps to access your account - Accounts Help


controllerから操作する

いちいちコンソール動かすのは面倒くさいので先ほど作ったcontrollerから呼び出します。

app/controllers/mail_controller.rbのindexアクションを以下のように編集します。

#app/controllers/mail_controller.rb
class MailController < ApplicationController
  def index
      SendEmail::welcome_email.deliver
  end
end

これでrails sでサーバーを立ち上げてlocalhost:3000/mail/indexにアクセスすればメールが送信されます。

以上でRailsアプリケーションからメールを送信する仕組みは完成です。次にこの記事のメインであるInterceptorについてです。

interceptor


まずlib/mail_interceptor.rbを新規作成します。

#lib/mail_interceptor.rb
class MailInterceptor

  def self.delivering_email(message)
    message.to = "<メールアドレス>"
    message.subject.insert(0,"[DEVELOPMENT]")
  end

end

件名の先頭に"[DEVELOPMENT]"と付け加えます。

次に、config/initializers/action_mailer.rbを新規作成します。
最初に先ほど作成したMailInterceptorクラスをrequireします。lib以下のクラスはconfig/application.rbにオートロードとして定義しておく方がいいと思います。

#config/initializers/action_mailer.rb
require_relative '../../lib/mail_interceptor'
ActionMailer::Base.register_interceptor(MailInterceptor) unless Rails.env.production?

production環境以外にregister_interceptorを実行します。


メインと言っておきながらかなり手順が少ないですね

localhost:3000/mail/indexにアクセスするとちゃんと送信されていることが確認できました。
f:id:hyottokoaloha:20151010204612p:plain

まとめ

以上によりメール送信の環境による分岐が簡単にできるようになりました。

after_action使ってもできますがこちらの方が簡単です。


github

この記事で作成したRailsアプリケーションをgithubに置いてます。github.com


参考

railsguides.jp

qiita.com

Abort mail delivery with Rails 3 interceptors - The Pug Automatic

wearestac.com


gmailの2段階認証karur4n.hatenablog.com

参考元の方々、非常にためになりました。ありがとうございます。

*1:セキュリティがザルになってしまうのでこのアプリケーションを作った後アクセス不許可にするか、参考より2段階認証をちゃんとする等対処を行ってください。