SendGridの導入

SendGridの導入

Railsの本番環境でメールを送信するようにする為には、一般的にSendGridorGmailを使います。
今回は、SendGridでメールを送信できるようにする為の方法を備忘録としてこちらにまとめます。

まずSendGridに登録します。
下記URLより新規登録が必要になります。
Email Delivery, API, Marketing Service | SendGrid


・Herokuのアドオン経由でも登録できますが、SendGridのアカウントが凍結される可能性が高いのでSendGridの公式から直接登録する方が良いです!!
・SendGridの登録には、フィッシング詐欺の観点などから比較的に厳しい審査があります。
SendGridを使用してメールを使うWebサイトのドメインと自分の名前が紐付いて分かるような画像などが必要になります。


SendGridのメール差出人情報を登録しておく必要があります。
まず、SendGridにログインしてAccount Detailsをクリックしてタイムゾーンとメールアドレス(ユーザー名)が正しく設定されていることを確認する。
これらの情報は、宛先リストのアップロード完了通知メールや、スケジュール配信に使われます。
以下の手順で差出人情報を登録します。
①Marketing > Sendersをクリック

②Sender Management画面の右上のCreate New Senderをクリック

③以下の情報を登録する
・From Name(From名):受信者に表示される送信者の名前
・From Email Address(Fromメールアドレス):メール送信者のメールアドレスとして表示される(自分のGmailなどを記載すると、そのGmailに認証のメールが届く)
・Reply-To Email Address(Reply-Toメールアドレス):受信者がメールの返信をする時に返信先のアドレスになる
・Company Address, City, State, Zip Code, Country(会社所在地):会社の所在地
・Nickname(一意な名前):差出人情報を識別するための名前(この名前が受信者に表示されることはない)


Fromアドレス宛に認証メールが届くので、Verify Sender Identityをクリック

これで差出人情報の登録は、終了


SendGridのAPIキーを発行します。
手順は、以下のようになります。
①SendGridのマイページでSettingsAPI Keysをクリック


Create API Keyをクリック


API Key Nameに作成するAPIキーの名前を入力
して、API Key PermissionsはデフォルトのFull Accessのままにして、Create & Viewをクリック
APIキーが発行されるので、コピーして安全な場所に保存する
Doneをクリック

これでAPIキーの発行は、終了


メール送信サーバーの設定は、以下のようになります。
コードは、以下のようになります。

[app/mailers/application_mailer.rb]

class ApplicationMailer < ActionMailer::Base
  default from: Rails.application.credentials.sendgrid.dig(:sender_address)    # 送信するアドレスを記載(このように記載している理由は、後で説明します)
  layout 'mailer'
end

念の為、開発環境でSendGridを利用する際の設定も以下に記載しておきます。

[config/environments/development.rb]

  config.action_mailer.perform_caching = false

  host = 'localhost:3000'

  config.action_mailer.default_url_options = { host: host, protocol: 'http' }

  config.action_mailer.raise_delivery_errors = true

  config.action_mailer.delivery_method = :smtp


  config.action_mailer.smtp_settings = {
    :address => 'smtp.sendgrid.net',
    :port => 587,
    :domain => 'localhost',
    :user_name => 'apikey',    #  user_nameは、apikeyにする
    :password => Rails.application.credentials.sendgrid.dig(:sendgrid_api_key),   #  パスワードには、発行したAPIキーを入力(この記載は、後で説明します)
    :authentication => :plain,
    :enable_starttls_auto => true
  }
[config/environments/production.rb]

  config.action_mailer.default_url_options = { host: '自分のアプリのURL' }

  config.action_mailer.perform_caching = false

  config.action_mailer.delivery_method = :smtp

  config.action_mailer.perform_deliveries = true

  config.action_mailer.default :charset => "utf-8"

  config.action_mailer.smtp_settings = {
    address:              'smtp.sendgrid.net',
    port:                 587,
    domain:               'heroku.com',
    user_name:            'apikey',   #  user_nameは、apikeyにする
    password:             Rails.application.credentials.sendgrid.dig(:sendgrid_api_key),    #  パスワードには、発行したAPIキーを入力(この記載は、後で説明します)
    authentication:       'plain',
    enable_starttls_auto: true }

これで使用するメールサーバーの設定は、終了


送信元のアドレスとメールサーバー設定のパスワードで、Rails.application.credentialsを用いているがこれは、config/credentials.yml.encに記載されている暗号化された値を復号して読み取る記述になる。
config/credentials.yml.encには、暗号化されたものが記載されている。
そもそもなぜ、config/credentials.yml.encのように暗号化されたものが必要になるかというと、APIキーやパスワード、メールアドレスなどの個人情報を設定ファイルなどに直接書き込むと、それをGitHubやサーバーにアップするのは、セキュリティ上危険なので、それらの値を暗号化したconfig/credentials.yml.encファイルを設置しておき、それらの値を読み込みたい時は、config/credentials.yml.encからmaster.keyで復号して読み込むようにする。
つまり、master.keyGitHubに公開したり、盗まれたりなどすると個人情報やAPIキーなどの重要情報がダダ漏れの状態になってしまう!!
その為、Railsでは通常.gitignoremaster.keyファイルが記載されて、リモートにアップされないようになっている。
以下にconfig/credentials.yml.encに値を設定して、それらを暗号化しそれを読み出すまでの流れを以下に示します。

①以下でconfig/credentials.yml.encを編集

$ EDITOR="vi" bin/rails credentials:edit

vimでファイルが開き、以下のように記載して設定する。

aws:
   access_key_id: aaabbbcccddd
   secret_access_key: eeefffggghhh

sendgrid:
   sendgrid_api_key: iiijjjkkklllmmm
   sender_address: nnnooopppqqq

secret_key_base: rrrssstttuuu

保存して閉じるとconfig/credentials.yml.encが更新されて違う暗号となる。
上記のようにconfig/credentials.yml.encに設定した値がconfig/credentials.yml.encに暗号化されて記載されるが、これを復号して読み込む方法は、以下のようになる。

[1] pry(main)> Rails.application.credentials.aws[:access_key_id]
=> aaabbbcccddd

[2] pry(main)> Rails.application.credentials.aws[:secret_access_key]
=> eeefffggghhh

[3] pry(main)> Rails.application.credentials.sendgrid[:sendgrid_api_key]
=> iiijjjkkklllmmm

[4] pry(main)> Rails.application.credentials.sendgrid[:sender_address]
=> nnnooopppqqq

[4] pry(main)> Rails.application.credentials.secret_key_base
=> rrrssstttuuu

これでAPIキーやメールアドレスを暗号化しての記載は、終了


herokuへデプロイする際は、.gitignoremaster.keyファイルを記載している為、herokuへmaster.keyがアップされないので、Rails.application.credentialsconfig/credentials.yml.encに記載されている暗号を復号できない。
herokuでは、以下のようにして復号化キーを環境変数RAILS_MASTER_KEYに登録する

heroku config:set RAILS_MASTER_KEY=********************************

ポイント
・Credentialsは、最初にconfig/master.keyに復号化キーを探索しにいき、そこになければ次に環境変数RAILS_MASTER_KEYを探索しにいく。
そこにも復号化キーがなければ復号化に失敗し、nilが返却される。
config/credentials.yml.encは、secret_key_baseによって暗号化される。
Credentialsにはsecret_key_baseが初めから登録されている。
これは、Cookieの暗号化に使用される文字列になります。
使わないからと言って削除しないように気を付けてください。

参考記事

[【Rails7】開発環境、本番環境でメール送信できるようにする(SendGrid, Gmail) | こばっちブログ

Rails5.2から追加された credentials.yml.enc のキホン - Qiita

Rails5.2でSendGridをつかってメールを送信する設定 | 煩悩八百万クリエイター戦記

本番環境とcredentials.yml.enc - Qiita

【Rails】Credentialsを使用した機密情報の保護 - AUTOVICE | 坂井光太郎のポートフォリオサイト

Heroku Addons で SendGrid を使ってる方が必要な年内対応 - ボクココ

SendGridとの連携 - ドキュメント | SendGrid

差出人情報(Senders)の管理 - ドキュメント | SendGrid