Rails 「Action Mailer × Gmail × Heroku」でメール送信機能を実装する

Railsアプリケーションでメール送信機能を実装する方法を説明します。
Herokuの本番環境では、SendGridを用いることが多いと思いますが、今回は開発/本番環境どちらもGmailを使って実装します。
なお、HerokuとGoogleのアカウント取得、およびHerokuでのアプリケーションセットアップが完了している前提で進めます。

環境

ステップ 1: 環境変数の設定

1.1: Googleでアプリパスワードを取得

以下の順にアクセスして、アプリパスワードを取得します。

  1. Googleアカウントを管理
  2. セキュリティ
  3. Googleにログインする方法 > 2段階認証プロセス
  4. アプリパスワード で任意のApp nameを入力しパスワードを作成

1.2: gem dotenv-rails をインストール

セキュリティを確保するために、Gmailのユーザー名とパスワードは環境変数に保存します。
Railsでアプリケーションでgem 'dotenv-rails'をGemfileに追加し、bundle installを実行して、dotenvをアプリケーションにインストールします。

1.3: .envファイルにメールアドレスとパスワードを設定

以下のように.envファイルに環境変数を追加しましょう。

EMAIL_USER=your-email@gmail.com
EMAIL_PASSWORD=your-email-password

your-email-passwordには、先ほどGoogleアカウントで作成したアプリパスワードを記述します。

ステップ 2: Action Mailerの設定

今回は、ユーザーが商品を購入したら、購入明細をメールで送信するようにします。
app/mailers/checkout_mailer.rbメーラークラスを作成し、購入確認メールを定義します。

class CheckoutMailer < ApplicationMailer
  default from: ENV['EMAIL_USER']

  def checkout_confirmation(order)
    @order = order
    mail(to: @order.billing_address.email, subject: '購入が完了しました')
  end
end

メールの送信元として、先ほど.envファイルに記述した環境変数を設定します。
checkout_confirmation(order)では、引数で購入内容の情報を取得します。
インスタンス変数@orderにすることで、メールの本文で使用できるようになります。 mail(to: )には購入内容の情報から、購入者のメールアドレスを設定します。

ステップ 3: メールビューの作成

HTMLとテキスト形式の両方でメールを作成します。
これはapp/views/checkout_mailerディレクトリに配置します。

HTML

<!DOCTYPE html>
<html>
<head>
    <meta content='text/html; charset=UTF-8' http-equiv='Content-Type' />
</head>
<body>
    <h1>購入が完了しました</h1>
    <p>購入明細:</p>
    <ul>
        <% @order.order_items.each do |item| %>
            <li><%= item.product.name %> - <%= item.quantity %> x <%= number_to_currency(item.price) %></li>
        <% end %>
    </ul>
    <p>Total: <%= number_to_currency(@order.total_price) %></p>
</body>
</html>

テキスト形式

購入が完了しました
購入明細:

<% @order.order_items.each do |item| %>
  <%= item.product.name %> - <%= item.quantity %> x <%= number_to_currency(item.price) %>
<% end %>

Total: <%= number_to_currency(@order.total_price) %>

ステップ 4: 開発環境の設定

開発環境では、config/environments/development.rbにメール送信の設定を追加します。

config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
  address: 'smtp.gmail.com',
  port: 587,
  domain: 'gmail.com',
  user_name: ENV['EMAIL_USER'],
  password: ENV['EMAIL_PASSWORD'],
  authentication: 'plain',
  enable_starttls_auto: true
}

ステップ 5: 本番環境の設定

本番環境でHerokuを使用する場合、config/environments/production.rbに以下のように設定を追加します。

config.action_mailer.default_url_options = { host: 'https://your-app-name.herokuapp.com', protocol: 'https' }
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
  address: 'smtp.gmail.com',
  port: 587,
  domain: 'gmail.com',
  user_name: ENV['EMAIL_USER'],
  password: ENV['EMAIL_PASSWORD'],
  authentication: :plain,
  enable_starttls_auto: true
}

また、Herokuの管理画面(Setting > Config Vars)にて環境変数(EMAIL_USER, EMAIL_PASSWORD)を追加します。

ステップ 6: メール送信のトリガーを設定

今回は、購入が完了したタイミングでメールを送信します。

OrdersController内で、注文が正常に保存された後にメールを送信するようにします。

if @order.save
  CheckoutMailer.checkout_confirmation(@order).deliver_now
  # その他の処理...
end

先ほど作成したcheckout_confirmationアクションに、保存したorderを引数として渡すことで、購入内容をメールで使用できます。

ステップ 7: テストとデプロイ

開発環境でメールが正しく送信されることを確認したら、本番環境にデプロイします。

これで、RailsアプリケーションからGmailを介してメールを送信することができます。