🐘

Action Mailer + letter_opener_web を使って開発環境のメール送信機能を実装する

2024/01/01に公開

概要

今回は Rails のデフォルトの機能である ActionMailer と、letter_opener_web gem を使って、
開発環境でメール送信を確認できるようにしていきます。

環境

ruby 3.1.2
rails 7.0.8
letter_opener_web 2.0.0

この記事のゴール

  • 以下のようなコードでメールを送信できるようにすること
SampleMailer.welcome.deliver_now!
  • 送信されたメールが、以下のようにブラウザで確認することができること

そもそもなぜ letter_opener_web が必要なのか

実際にメールを送信するには外部のメールサーバーを(SMTPサーバー)が必要になります。
主に使用されるサービスとして以下が挙げられます。

  • Gmail
  • SendGrid
  • Amazon SES
  • Mailgun

ただ、開発している時にいちいちメールサーバーを立てて、メールが実際に送信されるかみたいなことをやるのは非常に面倒です。

そこで、letter_opener_web gem を使うことで、以下のことができるようになります。

  • メールの送信を実際に行ったように見せかける
  • ブラウザ上で送信したメール内容を確認する

https://github.com/fgrehm/letter_opener_web

letter_opener_web の導入

必要な gem のインストール

Gemfile の development のグループに以下を追記して bundle install してください。

gem 'letter_opener_web'

ブラウザで確認できるようにルーティングを設定

開発環境でのみこのルーティングを使用します。

  if Rails.env.development?
    mount LetterOpenerWeb::Engine, at: "/letter_opener"
  end

これで localhost:3000/letter_opener とかで、ブラウザ上で以下のような画面が確認できれば OK です。

メールを送信できるようにする

次は ActionMailer を使ってメーラーを作成していきます。
ここで言うメーラーとは、「メールをメールサーバーに送ってくれるやつ」という理解で大丈夫です。

今回は簡単なメーラーを作成しますが、詳細は Rails ガイドを参考にしてください。
https://railsguides.jp/action_mailer_basics.html

メーラーを作成する

まずは app/mailers/sample_mailer.rb を作成し、以下のように書いていきます。

class SampleMailer < ApplicationMailer
  default from: "hogehoge@example.com"

  def welcome
    @user_name = "佐藤"
    mail(to: "fugafuga@example.com", subject: "subject です")
  end
end

私は ApplicationMailer が既に作成されていたので継承していますが、
作成されていない場合は ActionMailer::Base を継承しても問題ないです。

メーラービューを作成する

次に、メーラーに対応するテンプレートを用意します。
app/views/sample_mailer/welcome.html.erb を作成し、以下のように記述します。

<h1>
  メールです
</h1>
<div>
  <%= @user_name %> さんへ
</div>
<div>
  テストメールです。
</div>

今回は HTML でフォーマットされたメールテンプレートのみ作成しましたが、
テキストメールも作成しておくといいです。理由については以下、Rails ガイドより引用。

現在のAction Mailerでは、mailメソッドを呼び出すと2種類のテンプレート (テキストおよびHTML) があるかどうかを探し、multipart/alternative形式のメールを自動生成します。

動作確認

ここまで来たら、rails console からメール送信のメソッドを実行してみましょう。
おそらく以下のようなエラーが出ると思います。

> SampleMailer.welcome.deliver_now!
...
'initialize': Cannot assign requested address - connect(2) for "localhost" port 25 (Errno::EADDRNOTAVAIL)

これは ActionMailer の設定で、デフォルトが :smtp になっているのにもかかわらず、
接続先のメールサーバーが存在しないために起きているようです。
参考:

config/environments/development.rb に以下を追記して、
開発環境では letter_opener_web を使うようにしましょう。

config.action_mailer.delivery_method = :letter_opener_web

これで rails を再起動し、再度メール送信のメソッドを実行します。
今度はうまくいっていそうです。

> SampleMailer.welcome.deliver_now!
...
=> #<Mail::Message:174580, Multipart: false, Headers: <Date: Mon, 01 Jan 2024 06:34:48 +0000>, <From: hogehoge@example.com>, <To: fugafuga@example.com>, <Message-ID: <65925d085b235_30e9c45238@83e7cccb0712.mail>>, <Subject: subject です>, <Mime-Version: 1.0>, <Content-Type: text/html>, <Content-Transfer-Encoding: base64>>

localhost:3000/letter_opener に再度アクセスし、「Reflesh」を押して、
送信されたメール内容が確認できれば成功です。

まとめ

今回は letter_opener_web を使って、開発環境でのメール送信の環境を設定しました。
次回は本番環境で実際にメール送信する方法を書いていく予定です!

Discussion