Action Mailer の基礎

本章では、アプリケーションでメールの送受信を行えるようにするために必要なすべての事項と、Action Mailerのさまざまな内部情報を提供します。また、メイラーのテスト方法についても説明します。

このガイドの内容:

1 はじめに

Action Mailerを使うと、アプリケーションのメイラークラスやビューでメールを送信することができます。メイラーの動作はコントローラときわめて似通っています。メイラーはActionMailer::Baseを継承し、app/mailersに配置され、app/viewsにあるビューと結び付けられます。

2 メールを送信する

このセクションでは、メイラーとビューの作成方法を手順を追って説明します。

2.1 メイラー生成の全手順

2.1.1 メイラーを作成する
$ bin/rails generate mailer UserMailer
create  app/mailers/user_mailer.rb
create  app/mailers/application_mailer.rb
invoke  erb
create    app/views/user_mailer
create    app/views/layouts/mailer.text.erb
create    app/views/layouts/mailer.html.erb
invoke  test_unit
create    test/mailers/user_mailer_test.rb
create    test/mailers/previews/user_mailer_preview.rb

# app/mailers/application_mailer.rb
class ApplicationMailer < ActionMailer::Base
  default from: "from@example.com"
  layout 'mailer'
end

# app/mailers/user_mailer.rb
class UserMailer < ApplicationMailer
end

上に示したとおり、Railsの他のジェネレータ同様の方法でメイラーを生成できます。メイラーは概念上コントローラと似通っており、メイラーを生成すると (コントローラと同様に) ビューのディレクトリとテストも同時に生成されます。

ジェネレータを使いたくない場合は、app/mailersディレクトリ以下にファイルを作成し、ActionMailer::Baseを継承してください。

class MyMailer < ActionMailer::Base
end
2.1.2 メイラーを編集する

メイラーはRailsのコントローラと非常に似通っています。メイラーには「アクション」と呼ばれるメソッドがあり、メールのコンテンツを構成するのにビューを使います。コントローラでHTMLなどのメールコンテンツを生成して顧客に送信したい場合、その箇所でメイラーを使って、送信したいメッセージを作成します。

app/mailers/user_mailer.rbには空のメイラーがあります。

class UserMailer < ApplicationMailer
end

welcome_emailという名前のメソッドを追加し、ユーザーが登録したメールアドレスにメールを送信できるようにしてみましょう。

class UserMailer < ApplicationMailer
  default from: 'notifications@example.com'

  def welcome_email
    @user = params[:user]
    @url  = 'http://example.com/login'
    mail(to: @user.email, subject: '私の素敵なサイトへようこそ')
  end
end

上のメソッドで使われている項目について簡単に説明します。利用可能なすべてのオプションについては、「Action Mailerの全メソッド」セクションでユーザー設定可能な属性を参照してください。

  • default Hash - メイラーから送信するあらゆるメールで使われるデフォルト値のハッシュです。上の例の場合、:fromヘッダーにこのクラスのすべてのメッセージで使う値を1つ設定しています。この値はメールごとに上書きすることもできます。
  • mail - 実際のメール・メッセージです。ここでは:toヘッダーと:subjectヘッダーを渡しています。

コントローラの場合と同様、メイラーのメソッド内で定義されたすべてのインスタンス変数はそのままビューで使えます。

2.1.3 メイラービューを作成する

app/views/user_mailer/ディレクトリでwelcome_email.html.erbというファイルを1つ作成してください。このファイルを、HTMLでフォーマットされたメールテンプレートにします。

<!DOCTYPE html>
<html>
  <head>
    <meta content='text/html; charset=UTF-8' http-equiv='Content-Type' />
  </head>
  <body>
    <h1><%= @user.name %>様、example.comへようこそ。</h1>
      <p>
      example.comへのサインアップが成功しました。
      your username is: <%= @user.login %>.<br>
    </p>
    <p>
      このサイトにログインするには、<%= @url %>をクリックしてください。
    </p>
    <p>ご入会ありがとうございます。どうぞお楽しみくださいませ。</p>
  </body>
</html>

続いて、同じ内容のテキストメールも作成しましょう。顧客によってはHTMLフォーマットのメールを受け取りたくない人もいるので、テキストメールも作成しておくのが最善です。これを行なうには、app/views/user_mailer/ディレクトリでwelcome_email.text.erbというファイルを以下の内容で作成してください。

<%= @user.name %>様、example.comへようこそ。
===============================================

example.comへのサインアップが成功しました。ユーザー名は「<%= @user.login %>」です。

このサイトにログインするには、<%= @url %>をクリックしてください。

本サイトにユーザー登録いただきありがとうございます。

現在のAction Mailerでは、mailメソッドを呼び出すと2種類のテンプレート (テキストおよびHTML) があるかどうかを探し、multipart/alternative形式のメールを自動生成します。

2.1.4 メイラーを呼び出す

Railsのメイラーは、ビューのレンダリングと本質的に同じことを行っています。ビューのレンダリングではHTTPプロトコルとして送信されますが、メイラーではメールのプロトコルを経由して送信する点のみが異なります。従って、ユーザー作成に成功したときにメールを送信するようコントローラからメイラーに指示するだけで機能するようになります。

メイラー呼び出しは非常に簡単です。

例として、最初にscaffoldでUserを作成してみましょう。

$ bin/rails generate scaffold user name email login
$ bin/rails db:migrate

説明用のユーザーモデルを作成したので、続いてapp/controllers/users_controller.rbを編集し、新規ユーザーの保存成功直後にUserMailerUserMailer.with(user: @user)を用いてそのユーザーにメールが送信されるようにしましょう。

Action MailerはActive Jobとうまく統合されているので、Webのリクエスト/レスポンスサイクルの外で非同期にメールを送信できます。このおかげで、ユーザーは送信完了を待つ必要がありません。

class UsersController < ApplicationController
  # POST /users
  # POST /users.json
  def create
    @user = User.new(params[:user])

    respond_to do |format|
      if @user.save
        # 保存後にUserMailerを使ってwelcomeメールを送信
        UserMailer.with(user: @user).welcome_email.deliver_later

        format.html { redirect_to(@user, notice: 'ユーザーが正常に作成されました。') }
        format.json { render json: @user, status: :created, location: @user }
      else
        format.html { render action: 'new' }
        format.json { render json: @user.errors, status: :unprocessable_entity }
      end
    end
  end
end

Active Jobはデフォルトでジョブを:asyncで実行します。したがって、この時点でメールをdeliver_laterで送信できます。 Active Jobのデフォルトのアダプタの実行では、インプロセスのスレッドプールが用いられます。これは外部のインフラを一切必要としないので、development/test環境に適しています。しかし、ペンディング中のジョブが再起動時に削除されるため、productionには不向きです。永続的なバックエンドが必要な場合は、永続的なバックエンドを用いるActive Jobアダプタ(SidekiqやResqueなど)を使う必要があります。

メールをcronjobなどから今すぐ送信したい場合は、deliver_nowを呼び出すだけで済みます。

class SendWeeklySummary
  def run
    User.find_each do |user|
      UserMailer.with(user: user).weekly_summary.deliver_now
    end
  end
end

withに渡されるキーの値は、メイラーアクションでは単なるparamsになります。つまり、with(user: @user, account: @user.account)とすることでメイラーアクションでparams[:user]params[:account]を使えるようになります。ちょうどコントローラのparamsと同じ要領です。

このwelcome_emailメソッドはActionMailer::MessageDeliveryオブジェクトを1つ返します。このオブジェクトは、そのメール自身が送信対象であることをdeliver_nowdeliver_laterに伝えます。ActionMailer::MessageDeliveryオブジェクトは、Mail::Messageをラップしています。内部のMail::Messageオブジェクトの表示や変更などを行いたい場合は、ActionMailer::MessageDeliveryオブジェクトのmessageメソッドにアクセスします。

2.2 ヘッダーの値を自動エンコードする

Action Mailerは、メールのヘッダーや本文のマルチバイト文字を自動的にエンコードします。

別の文字セットを定義したい場合や、事前に手動で別のエンコードを行っておきたい場合などの複雑な事例については、Mailライブラリを参照してください。

2.3 Action Mailerの全メソッド

以下の3つのメソッドを使えば、ほとんどのメール送信をカバーできます。

  • headers - メールに追加したいヘッダーを指定します。メールヘッダーのフィールド名と値のペアをハッシュにまとめて渡すこともできますし、headers[:field_name] = 'value'のように呼び出すこともできます。
  • attachments - メールにファイルを添付します。attachments['file-name.jpg'] = File.read('file-name.jpg')のように記述します。
  • mail - 実際のメール自身を送信します。このメソッドにはヘッダーのハッシュをパラメータとして渡すことができます。メソッドを呼び出すと、定義しておいたメールテンプレートに応じて、プレーンテキストメールまたはマルチパートメールを送信します。
2.3.1 ファイルを添付する

Action Mailerではファイルを簡単に添付できます。

  • ファイル名とコンテンツを渡すと、Action MailerとMail gemが自動的にmime_typeを推測し、エンコードを設定してファイルを添付します。

    attachments['filename.jpg'] = File.read('/path/to/filename.jpg')
    

mailメソッドをトリガーすると、マルチパート形式のメールが1つ送信されます。送信されるメールは、トップレベルがmultipart/mixedで最初のパートがmultipart/alternativeという正しい形式でネストしている、プレーンテキストメールまたはHTMLメールです。

メールに添付されるファイルは自動的にBase64でエンコードされます。他のエンコードを使いたい場合、事前に好みのエンコードを適用したコンテンツをHashでエンコードしてからattachmentsに渡します。

  • ヘッダーとコンテンツを指定してファイル名を渡すと、それらの設定がAction MailerとMailによって使われます。

    encoded_content = SpecialEncode(File.read('/path/to/filename.jpg'))
    attachments['filename.jpg'] = {
      mime_type: 'application/gzip',
      encoding: 'SpecialEncoding',
      content: encoded_content
    }
    

エンコーディングの種類を指定すると、Mailはコンテンツが既にエンコード済みであると判断し、Base64によるエンコードを行いません。

2.3.2 ファイルをインラインで添付する

Action Mailer 3.0はファイルをインライン添付できます。この機能は3.0より前に行われた多数のハックを基に、理想に近づけるべくシンプルな実装にしたものです。

  • インライン添付を利用することをMailに指示するには、Mailer内のattachmentsメソッドに対して#inlineを呼び出すだけで済みます。

    def welcome
      attachments.inline['image.jpg'] = File.read('/path/to/image.jpg')
    end
    
  • 続いて、ビューでattachmentsをハッシュとして参照し、表示したい添付ファイルを指定することができます。これを行なうには、attachmentsに対してurlを呼び出し、その結果をimage_tagメソッドに渡します。

    <p>Hello there, this is our image</p>
    
    <%= image_tag attachments['image.jpg'].url %>
    
  • これはimage_tagに対する標準的な呼び出しであるため、画像ファイルを扱う時と同様、添付URLの後にもオプションのハッシュを1つ置くことができます。

    <p>こんにちは、以下の写真です。</p>
    
    <%= image_tag attachments['image.jpg'].url, alt: 'My Photo', class: 'photos' %>
    
2.3.3 メールを複数の相手に送信する

1つのメールを複数の相手に送信することももちろん可能です (サインアップが新規に行われたことを全管理者に通知するなど)。これを行なうには、メールのリストを:toキーに設定します。メールのリストの形式は、メールアドレスの配列でも、メールアドレスをカンマで区切った文字列でも構いません。

class AdminMailer < ApplicationMailer
  default to: -> { Admin.pluck(:email) },
          from: 'notification@example.com'

  def new_registration(user)
    @user = user
    mail(subject: "New User Signup: #{@user.email}")
  end
end

CC (カーボンコピー) やBCC (ブラインドカーボンコピー) アドレスを指定する場合にも同じ形式を使えます。それぞれ:ccキーと:bccキーを使います。

2.3.4 メールアドレスを名前で表示する

受信者のメールアドレスをメールにそのまま表示するのではなく、受信者の名前で表示したいことがあります。これを行なうには、メールアドレスを"フルネーム" <メールアドレス>の形式で指定します。

def welcome_email
  @user = params[:user]
  email_with_name = %("#{@user.name}" <#{@user.email}>)
  mail(to: email_with_name, subject: '私の素敵なサイトへようこそ')
end

2.4 メイラーのビュー

メイラーのビューはapp/views/name_of_mailer_classディレクトリに置かれます。個別のメイラービューは、その名前がメイラーメソッドと同じになるので、クラスから認識できます。先の例の場合、welcome_emailメソッドで使うメイラービューは、HTML版であればapp/views/user_mailer/welcome_email.html.erbが使われ、プレーンテキストであればwelcome_email.text.erbが使われます。

アクションで使うデフォルトのメイラービューを変更するには、たとえば以下のようにします。

class UserMailer < ApplicationMailer
  default from: 'notifications@example.com'

  def welcome_email
    @user = params[:user]
    @url  = 'http://example.com/login'
    mail(to: @user.email,
         subject: '私の素敵なサイトへようこそ',
         template_path: 'notifications',
         template_name: 'another')
  end
end

上のコードは、anotherという名前のテンプレートをapp/views/notificationsディレクトリ以下から探索します。template_pathにはパスの配列を指定することもできます。この場合探索は配列順に沿って行われます。

より柔軟性の高い方法を使いたい場合は、ブロックを1つ渡して特定のテンプレートをレンダリングしたり、テンプレートを使わずにインラインまたはテキストでレンダリングすることもできます。

class UserMailer < ApplicationMailer
  default from: 'notifications@example.com'

  def welcome_email
    @user = params[:user]
    @url  = 'http://example.com/login'
    mail(to: @user.email,
         subject: '私の素敵なサイトへようこそ') do |format|
      format.html { render 'another_template' }
      format.text { render plain: 'Render text' }
    end
  end
end

上のコードは、HTMLの部分を'another_template.html.erb'テンプレートでレンダリングし、テキスト部分を:textでレンダリングしています。レンダリングのコマンドはAction Controllerで使われているものと同じなので、:text:inlineなどのオプションもすべて同様に利用できます。

2.4.1 メイラービューをキャッシュする

cacheメソッドを用いるアプリケーションビューと同じように、メイラービューでもフラグメントキャッシュを利用できます。

<% cache do %>
  <%= @company.name %>
<% end %>

この機能を使うには、アプリケーションで次の設定が必要です。

  config.action_mailer.perform_caching = true

フラグメントキャッシュはメールがマルチパートの場合にもサポートされています。詳しくはRails caching guideを参照してください。

2.5 Action Mailerのレイアウト

メイラーもコントローラのビューと同様の方法でレイアウトを設定できます。メイラーで使うレイアウト名はメイラーと同じ名前にする必要があります。たとえば、user_mailer.html.erbuser_mailer.text.erbというレイアウトは自動的にメイラーでレイアウトとして認識されます。

別のレイアウトファイルを明示的に指定したい場合は、メイラーでlayoutを呼び出します。

class UserMailer < ApplicationMailer
  layout 'awesome' # awesome.(html|text).erbをレイアウトとして使う
end

レイアウト内のビューは、コントローラのビューと同様にyieldでレンダリングできます。

formatブロック内のrenderメソッド呼び出しにlayout: 'layout_name'オプションを渡すことで、フォーマットごとに異なるレイアウトを指定することもできます。

class UserMailer < ApplicationMailer
  def welcome_email
    mail(to: params[:user].email) do |format|
      format.html { render layout: 'my_layout' }
      format.text
    end
  end
end

上のコードは、HTMLの部分についてはmy_layout.html.erbレイアウトファイルを明示的に用いてレンダリングし、テキストの部分については通常のuser_mailer.text.erbがあればそれを使ってレンダリングします。

2.6 メールのプレビュー

Action Mailerのプレビュー機能は、レンダリング用のURLを開くことでメールの外観を確認する方法を提供します。上の例のUserMailerクラスは、プレビューではUserMailerPreviewという名前にしてtest/mailers/previews/user_mailer_preview.rbに配置すべきです。welcome_emailのプレビューを表示するには、同じ名前のメソッドを実装してUserMailer.welcome_emailを呼び出します。

class UserMailerPreview < ActionMailer::Preview
  def welcome_email
    UserMailer.with(user: User.first).welcome_email
  end
end

これで、http://localhost:3000/rails/mailers/user_mailer/welcome_emailにアクセスしてプレビューを表示できます。

app/views/user_mailer/welcome_email.html.erbやメイラー自身に何らかの変更を加えると自動的に再読み込みしてレンダリングされるので、スタイル変更を画面ですぐ確認できます。利用可能なプレビューのリストはhttp://localhost:3000/rails/mailersで表示できます。

これらのプレビュー用クラスは、デフォルトではtest/mailers/previewsに配置されます。このパスはpreview_pathオプションで設定できます。たとえばlib/mailer_previewsに変更したい場合はconfig/application.rbに以下の設定を追加します。

config.action_mailer.preview_path = "#{Rails.root}/lib/mailer_previews"

2.7 Action MailerのビューでURLを生成する

メイラーがコントローラと異なる点のひとつは、メイラーのインスタンスはサーバーに届くHTTPリクエストのコンテキストと無関係であることです。アプリケーションのホスト情報をメイラー内で使いたい場合は:hostパラメータを明示的に指定します。

:hostに指定する値はそのアプリケーション内で共通であるのが普通なので、config/application.rbに以下の記述を追加してグローバルに利用できるようにします。

config.action_mailer.default_url_options = { host: 'example.com' }

*_pathヘルパーは、動作の性質上メール内では一切利用できない点にご注意ください。メールでURLが必要な場合は*_urlヘルパーを使ってください。以下に例を示します。

<%= link_to 'ようこそ', welcome_path %>

上のコードの代りに、以下のコードを使う必要があります。

<%= link_to 'ようこそ', welcome_url %>

こうすることでフルパスのURLが引用され、メールのURLが正常に機能するようになります。

2.7.1 url_forでURLを生成する

テンプレートでurl_forを用いて生成されるURLはデフォルトでフルパスになります。

:hostオプションをグローバルに設定していない場合は、url_for:hostオプションを明示的に渡す必要があることにご注意ください。

<%= url_for(host: 'example.com',
            controller: 'welcome',
            action: 'greeting') %>
2.7.2 名前付きルーティングでURLを生成する

メールクライアントはWebサーバーのコンテキストから切り離されているので、メールに記載するパスではWebのアドレスのベースURLは補完されません。従って、名前付きルーティングヘルパーについても「_path」ではなく「_url」を使う必要があります。

:hostオプションをグローバルに設定していない場合は、「*_url」ヘルパーに:hostオプションを明示的に渡す必要があることにご注意ください。

<%= user_url(@user, host: 'example.com') %>

GET以外のリンクが機能するにはrails-ujsまたはjQuery UJSが必須です。また、これらはメイラーテンプレートでは機能しません(通常のGETリクエストが出力されます)。

2.8 Action Mailerのビューに画像を追加する

コントローラの場合と異なり、メイラーのインスタンスには受け取ったリクエストのコンテキストが一切含まれません。このため、:asset_hostパラメータを自分で指定する必要があります。

:asset_hostが(多くの場合)アプリケーション全体で一貫しているのと同様、config/application.rbでグローバルな設定を行えます。

config.action_mailer.asset_host = 'http://example.com'

後は以下のようにしてメール内に画像を表示できます。

<%= image_tag 'image.jpg' %>

2.9 マルチパートメールを送信する

あるアクションに複数の異なるテンプレートがあると、Action Mailerによって自動的にマルチパート形式のメールが送信されます。UserMailerを例にとって説明します。app/views/user_mailerディレクトリにwelcome_email.text.erbwelcome_email.html.erbというテンプレートがあると、Action MailerはそれぞれのテンプレートからHTMLメールとテキストメールを生成し、マルチパート形式のメールとしてひとつにまとめて自動的に送信します。

マルチパートメールに挿入されるパートの順序はActionMailer::Base.defaultメソッドの:parts_orderによって決まります。

2.10 メール送信時に配信オプションを動的に変更する

SMTP認証情報などのデフォルトの配信オプションをメール配信時に上書きしたい場合、メイラーのアクションでdelivery_method_optionsを使って変更できます。

class UserMailer < ApplicationMailer
  def welcome_email
    @user = params[:user]
    @url  = user_url(@user)
    delivery_options = { user_name: params[:company].smtp_user,
                         password: params[:company].smtp_password,
                         address: params[:company].smtp_host }
    mail(to: @user.email,
         subject: "添付の利用規約を参照してください",
         delivery_method_options: delivery_options)
  end
end

2.11 テンプレートをレンダリングせずにメール送信する

メール送信時にテンプレートのレンダリングをスキップしてメール本文を単なる文字列にしたくなることがあります。このような場合には:bodyオプションを使えます。このオプションを使う場合は、必ず:content_typeオプションも指定してください。指定しなかった場合はデフォルトのtext/plainが適用されます。

class UserMailer < ApplicationMailer
  def welcome_email
    mail(to: params[:user].email,
         body: params[:email_body],
         content_type: "text/html",
         subject: "レンダリングしました")
  end
end

3 メールを受信する

Action Mailerを使うメールの受信と解析は、メール送信に比べてやや複雑です。Railsアプリケーションでメールを受信できるようにするためには、その前にメール受信待ちするRailsアプリケーションに何らかの形でメールが転送されるようにしておく必要があります。Railsアプリケーションでメールを受信できるようにするためには、以下の作業が必要になります。

  • メイラーにreceiveメソッドを実装する

  • /(アプリケーションのパス)/bin/rails runner 'UserMailer.receive(STDIN.read)'でメールを受信するアプリケーションに、メールサーバーからメールを転送する。

いずれかのメイラーにreceiveメソッドを定義すると、受信した生のメールはAction Mailerによって解析され、emailオブジェクトに変換されてデコードされた後、メイラーが新たにインスタンス化され、そのメイラーのreceiveインスタンスメソッドに渡されます。以下に例を示します。

class UserMailer < ApplicationMailer
  def receive(email)
    page = Page.find_by(address: email.to.first)
    page.emails.create(
      subject: email.subject,
      body: email.body
    )

    if email.has_attachments?
      email.attachments.each do |attachment|
        page.attachments.create({
          file: attachment,
          description: email.subject
        })
      end
    end
  end
end

4 Action Mailerのコールバック

Action Mailerではbefore_actionafter_actionおよびaround_actionというコールバックを指定できます。

  • コントローラと同様、メイラークラスのメソッドにもフィルタ付きのブロックまたはシンボルを1つ指定することができます。

  • before_actionコールバックを使ってmailオブジェクトにデフォルト値やdelivery_method_optionsを与えたり、デフォルトのヘッダと添付を挿入することもできます。

class InvitationsMailer < ApplicationMailer
  before_action { @inviter, @invitee = params[:inviter], params[:invitee] }
  before_action { @account = params[:inviter].account }

  default to:       -> { @invitee.email_address },
          from:     -> { common_address(@inviter) },
          reply_to: -> { @inviter.email_address_with_name }

  def account_invitation
    mail subject: "#{@inviter.name} invited you to their Basecamp (#{@account.name})"
  end

  def project_invitation
    @project    = params[:project]
    @summarizer = ProjectInvitationSummarizer.new(@project.bucket)

    mail subject: "#{@inviter.name.familiar} added you to a project in Basecamp (#{@account.name})"
  end
end
  • after_actionコールバックもbefore_actionと同様の設定を行いますが、メイラーのアクション内のインスタンス変数を使います。
class UserMailer < ApplicationMailer
  before_action { @business, @user = params[:business], params[:user] }

  after_action :set_delivery_options,
               :prevent_delivery_to_guests,
               :set_business_headers

  def feedback_message
  end

  def campaign_message
  end

  private

    def set_delivery_options
      # ここではメールのインスタンスや
      # @businessや@userインスタンス変数にアクセスできる
      if @business && @business.has_smtp_settings?
        mail.delivery_method.settings.merge!(@business.smtp_settings)
      end
    end

    def prevent_delivery_to_guests
      if @user && @user.guest?
        mail.perform_deliveries = false
      end
    end

    def set_business_headers
      if @business
        headers["X-SMTPAPI-CATEGORY"] = @business.code
      end
    end
end
  • メールのbodyにnil以外の値が設定されている場合、Mailer Filtersは処理を中止します。

5 Action Mailerヘルパーを使う

Action MailerはAbstractControllerを継承しているので、Action Controllerと同様に一般的なヘルパーメソッドを使えます。

6 Action Mailerを設定する

以下の設定オプションは、environment.rbやproduction.rbなどの環境設定ファイルのいずれかで利用するのが最適です。

設定 説明
logger 可能であればメール送受信に関する情報を生成します。nilを指定するとログ出力を行わなくなります。Ruby自身のLoggerロガーおよびLog4rロガーのどちらとも互換性があります。
smtp_settings :smtpの配信メソッドの詳細設定を行います。
  • :address - リモートメールサーバーの利用を許可する。デフォルトは"localhost"であり、必要に応じて変更する。
  • :port - メールサーバーが万一ポート25番で動作していない場合はここで変更する。
  • :domain - HELOドメインを指定する必要がある場合はここで行なう。
  • :user_name - メールサーバーで認証が必要な場合はここでユーザー名を指定する。
  • :password - メールサーバーで認証が必要な場合はここでパスワードを指定する。
  • :authentication - メールサーバーで認証が必要な場合はここで認証の種類を指定する。:plain(パスワードを平文で送信)、:login(パスワードをBase64でエンコードする)、:cram_md5(チャレンジ/レスポンスによる情報交換と、MD5アルゴリズムによる重要情報のハッシュ化の組み合わせ)のいずれかのシンボルを指定する。
  • :enable_starttls_auto - SMTPサーバーでSTARTTLSが有効かどうかを検出して有効にする。デフォルトはtrue
  • :openssl_verify_mode - TLSを利用する場合にOpenSSLが認証をチェックする方法を指定できる。自己署名証明書やワイルドカード証明書でバリデーションを行う必要がある場合に非常に有用。OpenSSL検証定数の名前('none'、'peer'、'client_once'、'fail_if_no_peer_cert')を用いることも、この定数を直接用いることもできる(OpenSSL::SSL::VERIFY_NONEOpenSSL::SSL::VERIFY_PEERなど)
sendmail_settings :sendmailの配信オプションを上書きします。
  • :location - sendmailの実行可能ファイルの場所を指定する。デフォルトは/usr/sbin/sendmail
  • :arguments - sendmailに渡すコマンドライン引数を指定する。デフォルトは-i
raise_delivery_errors メール配信に失敗した場合にエラーを発生するかどうかを指定します。このオプションは、外部のメールサーバーが即時配信を行っている場合にのみ機能します。
delivery_method 配信方法を指定します。以下の配信方法を指定可能です。
  • :smtp (default) -- config.action_mailer.smtp_settingsで設定可能。
  • :sendmail -- config.action_mailer.sendmail_settingsで設定可能。
  • :file: -- メールをファイルとして保存する。config.action_mailer.file_settingsで設定可能。
  • :test: -- メールを配列ActionMailer::Base.deliveriesに保存する。
詳細についてはAPIドキュメントを参照。
perform_deliveries Mailのメッセージにdeliverメソッドを実行したときに実際にメール配信を行なうかどうかを指定します。デフォルトでは配信が行われます。機能テストなどで配信を一時的にオフにしたい場合に便利です。
deliveries delivery_method :testを用いてAction Mailerから送信されたメールの配列を保持します。単体テストおよび機能テストで最も便利です。
default_options mailメソッドオプション (:from:reply_toなど)のデフォルト値を設定します。

設定オプションの完全な説明については「Railsアプリケーションを設定する」ガイドのAction Mailerを設定するを参照してください。

6.1 Action Mailerの設定例

適切なconfig/environments/$RAILS_ENV.rbファイルに追加する設定の例を以下に示します。

config.action_mailer.delivery_method = :sendmail
# デフォルトは以下のとおりです。
# config.action_mailer.sendmail_settings = {
#   location: '/usr/sbin/sendmail',
#   arguments: '-i'
# }
config.action_mailer.perform_deliveries = true
config.action_mailer.raise_delivery_errors = true
config.action_mailer.default_options = {from: 'no-reply@example.com'}

6.2 Gmail用のAction Mailer設定

Action MailerにMail gemが導入されたので、config/environments/$RAILS_ENV.rbファイルの設定は以下のように非常に簡単になりました。

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

Note: Googleは2014年7月15日より同社のセキュリティ対策を引き上げ、「安全性が低い」とみなされたアプリケーションからの試行をブロックするようになりました。

Gmailの設定については、ここでこの試行を許可できます。利用するGmailアカウントで2要素認証が有効になっている場合は、アプリケーションのパスワードを設定して通常のパスワードの代わりに使う必要があります。または、メール送信をsmtp.gmail.comから、プロバイダが提供する別のESPに置き換える方法もあります。

7 メイラーのテスト

メイラーのテスト方法の詳細についてはテスティングガイドのメイラーをテストするを参照してください。

8 メールを配信直前に加工する

メールを配信する前に何らかの編集を加えたいことがあります。幸い、Action Mailerにはすべてのメールの配信前に処理を加えるためのフックが提供されています。これを使って、メールが配信エージェントに最終的に渡される直前にメールの内容を変更するためのインターセプタを登録することができます。

class SandboxEmailInterceptor
  def self.delivering_email(message)
    message.to = ['sandbox@example.com']
  end
end

インターセプタが動作するようにするには、Action Mailerフレームワークに登録する必要があります。これは、以下のようにイニシャライザファイルconfig/initializers/sandbox_email_interceptor.rbで行います。

ActionMailer::Base.register_interceptor(SandboxEmailInterceptor) if Rails.env.staging?

上の例では"staging"というカスタマイズした環境を使っています。これは本番 (production環境) に準じた状態でテストを行うための環境です。Railsのカスタム環境についてはRails環境を作成するを参照してください。