AR ホームベーカリー

オイラのアウトプット用ホームベーカリー!

Rails の delivery_method で AWS SES を指定してメール送信する

だいぶ悩んでしまったのと、ググると出てくる例が delivery_method をオーバーライドしてるものが多いのでという気持ち。

TLDR

aws-sdk-rails gem を追加して、 config.action_mailer.delivery_method = :ses を指定しておけばとりあえずオッケー。

AWS SES でメール送信

以下の手順で行います。

  1. AWS SES でドメイン検証を済ませ、インフラ的にオッケーの状態にしておく
  2. config/initializers/aws.rbAWS へアクセスするクレデンシャルを用意する
  3. config/environments/ 以下、 AWS SES を利用する ENV のコンフィグを記述する
    • 今回は config/environments/production.rb と仮定します
  4. デプロイして送信できるかテストする
    • 今回は rails console から送信確認を行います

AWS SES でドメイン検証を済ませ、インフラ的に送信オッケーの状態にしておく

マネジメントコンソールなり IaC なりなんでもいいので、 AWS SES を利用できるようにしておいてください。

サンドボックス外への移動も忘れないよう、検証済みドメインが用意できたら AWS くんへ申請もしておきましょう。

config/initializers/aws.rbAWS へアクセスするクレデンシャルを用意する

利用するアプリケーションが、クレデンシャルを通して AWS リソースにアクセスできるようにします。

以下の例では、クレデンシャルを config/credentials/production.yml.enc から読み込んでいます。

config/initializers/aws.rb
# frozen_string_literal: true

require 'aws-sdk-core'

Rails.application.config.after_initialize do
  credentials = Rails.application.credentials[:aws] || {}
  Aws.config.update(
    region: 'ap-northeast-1',
    credentials: Aws::Credentials.new(credentials[:access_key_id], credentials[:secret_access_key])
  )
end
config/credentials/production.yml.enc
aws:
  access_key_id: AKIAなんとか
  secret_access_key: ご機嫌な文字列

config/environments/ 以下、 AWS SES を利用する ENV のコンフィグを記述する

今回は RAILS_ENV=production の場合です。

config.action_mailer.default_url_options には、 0. で検証済みのドメインを記述しましょう。

config/environments/production.rb
Rails.application.configure do

...

  # Amazon SESでメール送信の設定
  config.action_mailer.default_url_options = { host: 'example.com' }
  config.action_mailer.delivery_method = :ses
  config.action_mailer.perform_deliveries = true
  config.action_mailer.perform_caching = false
  config.action_mailer.raise_delivery_errors = true
end

デプロイして送信できるかテストする

これで送信できるようになりますが、デプロイした後アプリケーションから実行する前に、 console から素朴に送信出来ることを確認しておきましょう。

[user@localhost ~]$ cd ${RAILS_ROOT}
[user@localhost ~]$ bundle exec rails c
irb> ActionMailer::Base.mail(to: "送信先メールアドレス", from: "no-reply@example.com", subject: "題名", body: "本文").deliver_now

from はドメインさえ合っていれば、ユーザ名は (存在していなくても) なんでも大丈夫です。 上記は定番の no-reply としています。

これで送信できたらオッケーです。

オーバーライドについて

以下に書いてあるとおり、 delivery_method をオーバーライドして、 SES 送信部のみ任意のクレデンシャルを設定できるようですが、なんかうまくいかなかったので僕は利用していません。

github.com

参考

github.com