AWS SESを使ってRailsから送信元が独自ドメインのメールを送ってみた - Rails 6, Credentials 仕様-
IAMユーザーを使用する方法で私の環境と同じエラーが散見され
EC2にroleをアタッチする方法などを試みていたが
公式のSDKを使用することで解決できたので書き留めます
環境
Rails: 6.0.3
Ruby: 2.7.1
事前準備
- SES、ドメインの設定
- SES関連の権限が付与されたIAMユーザー
- 上記ユーザーのaccess_key_id, secret_access_keyを取得
ここまでは下記ページを参考にしました
【AWS】Amazon SES / Messaging・Route53を用いてドメインメールを送信する - Qiita
以下、参考ページからの変更点
-
Rails 6のcredentialsを使用する
-
SESのリージョンを
ap-northeast-1
に変更 -
AWS公式のSDKを使用
特にここが重要で私の環境では一通り設定した後の送信テストで次のエラーが
AWS::SES::ResponseError (AWS::SES Response Error: InvalidClientTokenId - The security token included in the request is invalid.)
以下のSDKが使用されているところを
gem 'aws-ses', '~> 0.6'
version 0.6.0が2014年アップデートのため
gem 'aws-ses', '~> 0.7'
0.7.0 - September 03, 2020
を試したものの変化なしAWS公式のSDKがあることがわかったのでこちらを試したところ解決しました
Ruby on Rails で SDK を使用する - AWS SDK for Rubyaws-sdk-rails/README.md at master · aws/aws-sdk-rails
gem 'aws-sdk-rails', '~> 3'
credentials.yml.encにAWSにアクセスするための情報を記述
EDITOR=vim rails credentials:edit
credentials.yml.encは直接開けず、master keyで復号化する必要があるため上記コマンドで。EDITORの指定は必須、Dockerでalpineイメージを使っているなど、場合によってEDITOR=vi
aws:
の部分のコメントアウトを解除しaccess_key_id
, secret_access_key
を追加
aws:
access_key_id: YOUR_KEY_ID
secret_access_key: YOUR_ACCESS_KEY
# Used as the base secret for all MessageVerifiers in Rails, including the one prote
secret_key_base:***********************************
Action mailerの設定
config/initializers/aws.rb (新規作成)
credentialsからaccess_key_id, secret_access_keyを呼び出しています
creds = Aws::Credentials.new(Rails.application.credentials[:aws][:access_key_id], Rails.application.credentials[:aws][:secret_access_key])
Aws::Rails.add_action_mailer_delivery_method(
:ses,
credentials: creds,
region: 'ap-northeast-1' #AWS SESで設定したregion
)
config/environments/development.rb
config.action_mailer.delivery_method = :ses
動作確認
テスト用のmailerを作ってみます
rails g mailer TestMailer test
app/mailers/test_mailer.rb
class DefaultMailer < ApplicationMailer
default from: 'example.com <noreply@example.com>' #example.comに自分のドメインを追加
# Subject can be set in your I18n file at config/locales/en.yml
# with the following lookup:
#
# en.default_mailer.test.subject
#
def test
@greeting = "Hi"
mail to: "テストメールを受信するアドレス" #追加
end
end
Rails c
TestMailer.test.deliver_now
これでnoreply@...
からメールが送信されるはずです
お掃除
rails d mailer TestMailer
Troubleshoot
テスト送信がうまく行かない場合は以下のオプションでデバックに必要な情報が得られるかもしれません
config/environments/development.rb
config.action_mailer.raise_delivery_errors = true
インターフェイス
formからpost :send_mailで受けて
controller
def send_mail
@user = User.new(user_params)
DefaultMailer.test(@user).deliver_now
redirect_to ...
end
app/mailers/default_mailer.rb
class DefaultMailer < ApplicationMailer
default from: 'example.com <noreply@example.com>'
# Subject can be set in your I18n file at config/locales/en.yml
# with the following lookup:
#
# en.default_mailer.test.subject
#
def test(user)
@user = user
@greeting = "Hi"
mail to: @user.email
end
end
app/views/default_mailer/test.html.erb
<h1>Default#test</h1>
<p>
<%= @greeting %>, <%= @user.name%> Thank you for counfirm!
</p>