LoginSignup
6
5

More than 3 years have passed since last update.

Rails6 アプリからメールを送信する デプロイ環境編

Last updated at Posted at 2020-01-20

目的

  • Rails6で作成したアプリをデプロイした時に当該アプリからメールを送信する方法をまとめる。

前提条件

作業期待値

作業前にちょっと聞いてほしいこと

考え方

  • ローカル開発環境のメールサーバ設定はheroku環境だとそのまま流用できないので専用のメールサーバ設定が必要となる。
  • heroku上のアプリからメールを送るには専用の設定ファイルが必要と覚えておいてほしい。
  • デプロイ中は前述した専用の設定ファイルから自動で設定が読まれる。
  • 下記に前述の内容の簡易図を記載する。

スクリーンショット 2020-01-21 0.49.22.png

作業概要

  1. SendGridの有効化とAPI鍵作成
  2. デプロイアプリとAPI鍵の紐付け
  3. メール確認

作業詳細

  1. SendGridの有効化とAPI鍵作成

    1. 下記コマンドを実行してSendGridを有効化する。

      $ heroku addons:create sendgrid:starter
      
    2. herokuにログインする。

    3. デプロイしているアプリ名をクリックする。

    4. 「Add ons」にある「SendGrid」をクリックする。
      スクリーンショット 2020-01-20 23.15.14.png

    5. 下記画面になったら確認用のメールアドレスを記入しメールを送るボタンをクリックする。(本メールアドレスはアプリからの送受信には全く関係ない。あくまでSendGridの確認用のアドレスである。)
      スクリーンショット 2020-01-20 23.16.13.png

    6. 下記の画面になったことを確認し、先に入力したメールアドレスの受信ボックスを確認する。
      スクリーンショット 2020-01-20 23.16.18.png

    7. 受信ボックスに下記のようなメールが届いていることを確認して、「Confirm Email Address」をクリックする。
      スクリーンショット 2020-01-20 23.16.36.png

    8. 前述の作業を実施後下記の画面に遷移する。
      スクリーンショット 2020-01-20 23.17.48.png

    9. 画面左下のバーの「Settings」→「API Keys」をクリックする。
      スクリーンショット 2020-01-20 23.18.26.png

    10. 下記の画面になったことを確認し、画面右上の「Create API Key」をクリックする。
      スクリーンショット 2020-01-20 23.18.36.png

    11. 「API Key Name」に認識しやすい任意のAPI鍵の名前を入力、(自分がわかるならなんでもOK)「API Key Permissions」は「Full Accesss」を選択し内容を確認後「Create & View」をクリックする。
      スクリーンショット 2020-01-20 23.19.41.png

    12. 表示された鍵をスクリーンショットやテキストコピーでメモしておく
      スクリーンショット 2020-01-20 23.20.33.png

  2. デプロイアプリとAPI鍵の紐付け

    1. 下記コマンドを実行してAPI鍵をherokuの変数に格納する。(本作業で自動的にメールサーバ用のパスワードとユーザ名が自動生成される)

      $ heroku config:set SENDGRID_API_KEY=XXXXXXXXXXXXXXXXXXXX6NDlg.J1bMNO_jbeepuH8LOYFwkMKFcOKoQ5vZ8z9axkzMyWU
      
  3. メールサーバの設定

    1. 下記に存在する送信先を指定するファイルproduct.rbをエディタで開く
      • アプリ名フォルダ/config/environments
        • product.rb
    2. ファイルproduct.rbを下記のように修正してSentGridからメールを送信できるようにする。(下記のように設定すると、先の作業で登録したAPI鍵からuser_nameとpasswordが自動生成されそれぞれ環境変数SENDGRID_USERNAMEとSENDGRID_PASSWORDに格納され、それを読んでメールを送るようになる。)

      Rails.application.configure do
        # Settings specified here will take precedence over those in config/application.rb.
      
        # Code is not reloaded between requests.
        config.cache_classes = true
      
        # Eager load code on boot. This eager loads most of Rails and
        # your application in memory, allowing both threaded web servers
        # and those relying on copy on write to perform better.
        # Rake tasks automatically ignore this option for performance.
        config.eager_load = true
      
        # Full error reports are disabled and caching is turned on.
        config.consider_all_requests_local       = false
        config.action_controller.perform_caching = true
      
        # Ensures that a master key has been made available in either ENV["RAILS_MASTER_KEY"]
        # or in config/master.key. This key is used to decrypt credentials (and other encrypted files).
        # config.require_master_key = true
      
        # Disable serving static files from the `/public` folder by default since
        # Apache or NGINX already handles this.
        config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].present?
      
        # Compress CSS using a preprocessor.
        # config.assets.css_compressor = :sass
      
        # Do not fallback to assets pipeline if a precompiled asset is missed.
        config.assets.compile = false
      
        # Enable serving of images, stylesheets, and JavaScripts from an asset server.
        # config.action_controller.asset_host = 'http://assets.example.com'
      
        # Specifies the header that your server uses for sending files.
        # config.action_dispatch.x_sendfile_header = 'X-Sendfile' # for Apache
        # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for NGINX
      
        # Store uploaded files on the local file system (see config/storage.yml for options).
        config.active_storage.service = :local
      
        # Mount Action Cable outside main process or domain.
        # config.action_cable.mount_path = nil
        # config.action_cable.url = 'wss://example.com/cable'
        # config.action_cable.allowed_request_origins = [ 'http://example.com', /http:\/\/example.*/ ]
      
        # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
        # config.force_ssl = true
      
        # Use the lowest log level to ensure availability of diagnostic information
        # when problems arise.
        config.log_level = :debug
      
        # Prepend all log lines with the following tags.
        config.log_tags = [ :request_id ]
      
        # Use a different cache store in production.
        # config.cache_store = :mem_cache_store
      
        # Use a real queuing backend for Active Job (and separate queues per environment).
        # config.active_job.queue_adapter     = :resque
        # config.active_job.queue_name_prefix = "eveyDayStudy_production"
        config.action_mailer.perform_caching = false
      
        # Ignore bad email addresses and do not raise email delivery errors.
        # Set this to true and configure the email server for immediate delivery to raise delivery errors.
        # config.action_mailer.raise_delivery_errors = false
      
        # Enable locale fallbacks for I18n (makes lookups for any locale fall back to
        # the I18n.default_locale when a translation cannot be found).
        config.i18n.fallbacks = true
      
        # Send deprecation notices to registered listeners.
        config.active_support.deprecation = :notify
      
        # Use default logging formatter so that PID and timestamp are not suppressed.
        config.log_formatter = ::Logger::Formatter.new
      
        # Use a different logger for distributed setups.
        # require 'syslog/logger'
        # config.logger = ActiveSupport::TaggedLogging.new(Syslog::Logger.new 'app-name')
      
        if ENV["RAILS_LOG_TO_STDOUT"].present?
          logger           = ActiveSupport::Logger.new(STDOUT)
          logger.formatter = config.log_formatter
          config.logger    = ActiveSupport::TaggedLogging.new(logger)
        end
      
        # Do not dump schema after migrations.
        config.active_record.dump_schema_after_migration = false
      
        # Inserts middleware to perform automatic connection switching.
        # The `database_selector` hash is used to pass options to the DatabaseSelector
        # middleware. The `delay` is used to determine how long to wait after a write
        # to send a subsequent read to the primary.
        #
        # The `database_resolver` class is used by the middleware to determine which
        # database is appropriate to use based on the time delay.
        #
        # The `database_resolver_context` class is used by the middleware to set
        # timestamps for the last write to the primary. The resolver uses the context
        # class timestamps to determine how long to wait before reading from the
        # replica.
        #
        # By default Rails will store a last write timestamp in the session. The
        # DatabaseSelector middleware is designed as such you can define your own
        # strategy for connection switching and pass that into the middleware through
        # these configuration options.
        # config.active_record.database_selector = { delay: 2.seconds }
        # config.active_record.database_resolver = ActiveRecord::Middleware::DatabaseSelector::Resolver
        # config.active_record.database_resolver_context = ActiveRecord::Middleware::DatabaseSelector::Resolver::Session
      end
      

      ↓修正

      Rails.application.configure do
        # Settings specified here will take precedence over those in config/application.rb.
      
        # Code is not reloaded between requests.
        config.cache_classes = true
      
        # Eager load code on boot. This eager loads most of Rails and
        # your application in memory, allowing both threaded web servers
        # and those relying on copy on write to perform better.
        # Rake tasks automatically ignore this option for performance.
        config.eager_load = true
      
        # Full error reports are disabled and caching is turned on.
        config.consider_all_requests_local       = false
        config.action_controller.perform_caching = true
      
        # Ensures that a master key has been made available in either ENV["RAILS_MASTER_KEY"]
        # or in config/master.key. This key is used to decrypt credentials (and other encrypted files).
        # config.require_master_key = true
      
        # Disable serving static files from the `/public` folder by default since
        # Apache or NGINX already handles this.
        config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].present?
      
        # Compress CSS using a preprocessor.
        # config.assets.css_compressor = :sass
      
        # Do not fallback to assets pipeline if a precompiled asset is missed.
        config.assets.compile = false
      
        # Enable serving of images, stylesheets, and JavaScripts from an asset server.
        # config.action_controller.asset_host = 'http://assets.example.com'
      
        # Specifies the header that your server uses for sending files.
        # config.action_dispatch.x_sendfile_header = 'X-Sendfile' # for Apache
        # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for NGINX
      
        # Store uploaded files on the local file system (see config/storage.yml for options).
        config.active_storage.service = :local
      
        # Mount Action Cable outside main process or domain.
        # config.action_cable.mount_path = nil
        # config.action_cable.url = 'wss://example.com/cable'
        # config.action_cable.allowed_request_origins = [ 'http://example.com', /http:\/\/example.*/ ]
      
        # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
        # config.force_ssl = true
      
        # Use the lowest log level to ensure availability of diagnostic information
        # when problems arise.
        config.log_level = :debug
      
        # Prepend all log lines with the following tags.
        config.log_tags = [ :request_id ]
      
        # Use a different cache store in production.
        # config.cache_store = :mem_cache_store
      
        # Use a real queuing backend for Active Job (and separate queues per environment).
        # config.active_job.queue_adapter     = :resque
        # config.active_job.queue_name_prefix = "eveyDayStudy_production"
      
        config.action_mailer.perform_caching = false
        config.action_mailer.delivery_method = :smtp
        config.action_mailer.perform_deliveries = true
        config.action_mailer.smtp_settings = {
          :enable_starttls_auto => true,
          :address => 'smtp.sendgrid.net',
          :port => 587,
          :domain => 'herokuapp.com',
          :authentication => :plain,
          :user_name => ENV['SENDGRID_USERNAME'],
          :password => ENV['SENDGRID_PASSWORD'],
        }
      
        # Ignore bad email addresses and do not raise email delivery errors.
        # Set this to true and configure the email server for immediate delivery to raise delivery errors.
        # config.action_mailer.raise_delivery_errors = false
      
        # Enable locale fallbacks for I18n (makes lookups for any locale fall back to
        # the I18n.default_locale when a translation cannot be found).
        config.i18n.fallbacks = true
      
        # Send deprecation notices to registered listeners.
        config.active_support.deprecation = :notify
      
        # Use default logging formatter so that PID and timestamp are not suppressed.
        config.log_formatter = ::Logger::Formatter.new
      
        # Use a different logger for distributed setups.
        # require 'syslog/logger'
        # config.logger = ActiveSupport::TaggedLogging.new(Syslog::Logger.new 'app-name')
      
        if ENV["RAILS_LOG_TO_STDOUT"].present?
          logger           = ActiveSupport::Logger.new(STDOUT)
          logger.formatter = config.log_formatter
          config.logger    = ActiveSupport::TaggedLogging.new(logger)
        end
      
        # Do not dump schema after migrations.
        config.active_record.dump_schema_after_migration = false
      
        # Inserts middleware to perform automatic connection switching.
        # The `database_selector` hash is used to pass options to the DatabaseSelector
        # middleware. The `delay` is used to determine how long to wait after a write
        # to send a subsequent read to the primary.
        #
        # The `database_resolver` class is used by the middleware to determine which
        # database is appropriate to use based on the time delay.
        #
        # The `database_resolver_context` class is used by the middleware to set
        # timestamps for the last write to the primary. The resolver uses the context
        # class timestamps to determine how long to wait before reading from the
        # replica.
        #
        # By default Rails will store a last write timestamp in the session. The
        # DatabaseSelector middleware is designed as such you can define your own
        # strategy for connection switching and pass that into the middleware through
        # these configuration options.
        # config.active_record.database_selector = { delay: 2.seconds }
        # config.active_record.database_resolver = ActiveRecord::Middleware::DatabaseSelector::Resolver
        # config.active_record.database_resolver_context = ActiveRecord::Middleware::DatabaseSelector::Resolver::Session
      end
      
  4. メール確認

    1. 下記のメール送信トリガーコードが記載されているコントローラが実行されるような操作を行う
      • NoticeMailer.greeting.deliver_now
    2. Rails6 アプリからGmailのメールサーバからメールを送信する ローカル環境編の対応で筆者の環境ではhttp://localhost:3000/posts/index/:idにアクセスした時にメールが送信されるようにトリガーコードを設置している。
    3. 筆者の場合herokuのパスに置き換えhttps://study-record.herokuapp.com/posts/index/:idにアクセスしエラーが出ないことを確認する。
    4. テストメール送信先アドレスを確認し下記のようなメールを受信していることを確認する。 スクリーンショット 2020-01-21 1.37.56.png
6
5
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
5