HerokuからエックスサーバーのSMTPサーバーを使ってメール送信する方法

この記事では、Heroku の Rails アプリから エックスサーバーの SMTP サーバーを使ってメールを送信する方法を解説します。

ローカルでは Docker の Rails 環境で開発し、本番運用は Heroku にデプロイするケースを想定していますが、ローカルの方は Docker を使っていないくても同じようにできることでしょう。

HerokuからエックスサーバーのSMTPサーバーを使ってメール送信する方法

1. 開発環境のメール送信

まずは、開発環境のメール送信の設定です。

config/environments/development.rb に次のように記述します。

  config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
  config.action_mailer.raise_delivery_errors = true
  config.action_mailer.delivery_method = :smtp
  config.action_mailer.smtp_settings = {
    :address => "<エックスサーバーのサーバー名>",
    :port => 587,
    :user_name => "<送信元メールアドレス>",
    :password => "<メールのパスワード>",
    :authentication => :plain,
    :enable_starttls_auto => true
  }

エックスサーバーのサーバー名は、エックスサーバーのサーバーパネルの [サーバー情報] – [ホスト名] から確認できます。

送信元メールアドレスは、 あらかじめエックスサーバーのサーバーパネルの [メールアカウント設定] で作成しておく必要があります。
パスワードは、エックスサーバーのサーバーパネルでメールアドレスを作成したときに指定したものを指定します。

送信するコードのサンプルは下記です。

app/controllers/mailers/message_mailer.rb

class MessageMailer < ApplicationMailer
  default to: '<送信先アドレス (例) info@example.com>'

  def received_email(message)
    @message = message
    mail(subject: 'example.comよりメッセージが届きました') do |format|
      format.text
    end
  end
end

app/controllers/messages_controller.rb

require_relative './mailers/message_mailer'

class MessagesController < ApplicationController
    def index
      @message = Message.new
    end

    def confirm
      @message = Message.new(message_params)
      if @message.valid?
        render :action => 'confirm'
      else
        render :action => 'index'
      end
    end

    def done
      @message = Message.new(message_params)
      if params[:back]
        render :action => 'index'
      else
        MessageMailer.received_email(@message).deliver_now
        render :action => 'done'
      end
    end

    private
    def message_params
      params.require(:message).permit(:name, :email, :content)
    end
end

2. Heroku でのメール送信

本番環境でメールを送信する設定を記述します。

config/environments/production.rb

  config.action_mailer.default_url_options = { host: '<自分の独自ドメイン (例) example.com'>' }
  config.action_mailer.raise_delivery_errors = true
  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 => "<エックスサーバーのサーバー名>",
    :port => 587,
    :user_name => "<送信元メールアドレス>",
    :password => "<メールのパスワード>",
    :authentication => :plain,
    :enable_starttls_auto => true
  }

これで Rails 側の設定は完了です。

しかし、メールを送信してみると、下記のエラーが出ます。

Errno::ECONNREFUSED (Connection refused – connect(2) for “localhost” port 25):

これは、Heroku のサーバーが海外にあり、エックスサーバーの SMTP はデフォルトで海外からのアクセスを制限しているために発生します。

そこで、エックスサーバーの設定を変更します。

[SMTP認証の国外アクセス制限設定]を開き、OFF に変更します。

再度、Heroku にデプロイしたアプリからメールを送信すると、正しく送れるはずです。