[Rails6対応, 公式SDK] AWS SESを使ってRailsから送信元が独自ドメインのメールを送ってみた

# 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](https://qiita.com/tanakaworld/items/94f1ba66801100f6a44f)

**以下、参考ページからの変更点**

- 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 Ruby](https://docs.aws.amazon.com/ja_jp/sdk-for-ruby/v3/developer-guide/rails.html)

    [aws-sdk-rails/README.md at master · aws/aws-sdk-rails](https://github.com/aws/aws-sdk-rails/blob/master/README.md)

    ```
    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

```ruby
def send_mail
  @user = User.new(user_params)
  DefaultMailer.test(@user).deliver_now
  redirect_to ...
end
```

app/mailers/default_mailer.rb

```ruby

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

```ruby
<h1>Default#test</h1>

<p>
  <%= @greeting %>, <%= @user.name%> Thank you for counfirm!
</p>
```