【Rails】Action Mailerでメール送信機能を作ろう

# 初めに
Railsを使って自分のアプリケーションを作っていると、「会員登録したら自動でご案内のメールが届く」とか「商品を購入したら自動で注文内容の確認メールが届く」などの機能を実装してみたい！と思ったりしていませんか？ そういう機能をRailsで作る方法について学習した内容について纏めてみました。

※内容に間違いなどがある場合はご指摘をよろしくお願いします。

# 目次
- Action Mailerとは
- 導入する方法
- 参考サイト

# Action Mailerとは
Action Mailerについて公式ドキュメントでは、以下のように紹介しています。
> Action Mailer allows you to send emails from your application using mailer classes and views.

つまり、Railsのメールクラスとビューを使ってE-mailを送ることが出来るRailsの機能の一つです。

# 導入する方法
✅ Mailerを生成する
rails gコマンドで「rails g mailer mailer名」で生成します。「mailer名」は任意であり、好きなお名前で構いませんが、作りたい機能が分かりやすい名前がいいです。ここでは例として「TestMailer」とします。

```terminal
❯ rails g mailer TestMailer
Running via Spring preloader in process 13084
      create  app/mailers/test_mailer.rb
      invoke  erb
      create    app/views/test_mailer
      invoke  rspec
      create    spec/mailers/test_mailer_spec.rb
      create    spec/mailers/previews/test_mailer_preview.rb
```
rspec用のテストファイルまで自動で生成されます。
mailerのコントローラー的な機能をする①「app/mailers/test_mailer.rb」とメールの本文が格納されるフォルダー②「app/views/test_mailer」です。これらは後で詳しくみていきます。

その他のアプリのテストに必要な③「spec/mailers/test_mailer_spec.rb」や
④「spec/mailers/previews/test_mailer_preview.rb」については割愛します。
気になる方は下記の記事をご覧ください。

- https://qiita.com/jnchito/items/42193d066bd61c740612
- https://qiita.com/tatsurou313/items/c923338d2e3c07dfd9ee

✅ メールを送る側（sender)のsettingをする
メールを送信するためにはご自身の利用しているメールアカウントの情報が必要です。Mailer自体でメールを送信するのではなく、アプリの開発者が登録した任意のメールサービス（GmailやYahooなどのAPI)を通してMailを送信します。なので、その設定を行う必要があります。
①「development.rb」の修正
railsの「config/environments/development.rb」で以下のような設定を追記します。

```ruby
  config.action_mailer.default_url_options = { host: 'localhost:3000' }
  config.action_mailer.raise_delivery_errors = true
  config.action_mailer.delivery_method = :smtp
  config.action_mailer.perform_caching = true
  config.action_mailer.smtp_settings = {
    port:                 587,     
    address:              'smtp.gmail.com',
    domain:               'gmail.com',
    user_name:            'user_name@gmail.com',    #ご自身のメールアドレス
    password:             'hogohogo',  #ご自身のパスワードですが、再設定が必要です
    authentication:       'login',
    enable_starttls_auto: true
  }
```
本番環境の場合は、production.rbファイルをいじりますが、同じ書き方で大丈夫です。
メールのやり取りにはSMTP (Simple Mail Transfer Protocol)を利用します。他には「IMAP」「POP」などがありますが、基本STMPです。
>参考サイト：https://www.kagoya.jp/howto/rentalserver/smtpserver/

port番号やaddressなどはメールサービスを提供する企業の製品ごとに決まっています。設定方法などについては下記のサイトをご覧ください。公式ドキュメントでは25番以外はどの番号でも大丈夫とされています。

>参考サイト：https://gitlab-docs.creationline.com/omnibus/settings/smtp.html

ちなみにyahooメールで設定してみたんですが、メールを送信した際にtimeoutエラーが出ました。ネットワークの環境問題なので仕方ないと思います。おすすめはやはりGmailです。

②Gmailはパスワードの再設定（２段認証）が必要
手順１：２段階認証の設定を行う
下記のサイトを参考に２段階認証の設定を行います。
https://enjoypclife.net/google-account-gmail-2-step-verification/
手順２：アプリパスワードを入手する
gmailに接続したら、Googleアカウントを管理をクリックします。
![スクリーンショット 2021-04-24 8.42.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/966135/e3c3001f-fcfd-e961-5725-9d32d34e4e15.png)
セキュリティの「アプリパスワード」をクリックして新しいパスワードを入手します。デバイス（mac,iphoneなどなど）色々ありますが、何でも構いません。パスワードを発行したらコピーしておきます。
![スクリーンショット 2021-04-24 8.54.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/966135/3cefc0e0-52b7-f23d-0f71-8b12363f628a.png)

③development.rbのpasswordを新しいパスワードに変更
先ほどコピーしたアプリパスワードをdevelopment.rbのpassword欄に入力します。

```
 password:           'hogehoge',  #２段階認証で発行した新しいパスワードにかきかえます
```
これでメールを送信する基本設定は完了です。

✅ test_email.rbファイルを修正
「app/mailers/」ディレクトリのtest_email.rbにメールを送信する処理を記述します。
TestMailerクラスの関数を定義します。関数名は何でも大丈夫ですが、分かりやすい名前で統一します。
また、引数としてuserを指定しました。引数を指定しなくても動かすには問題はありません。

```ruby
class TestMailer < ApplicationMailer

  def test_email(user)
    @user =  user
    @url  = 'http://localhost:3000/'
    # mail(to: @user.email, subject: '私の素敵なサイトへようこそ')
    mail(to:'target@yahoo.co.jp', subject: 'Action Mailerからのお知らせ')
  end

end
```
ここで宣言した変数@userや@urlなどはviewファイルで使用できます。変数を使うとメールの本文となるviewファイルで使うことが出来るので便利です。これもお好みで設定しましょう。
ここで重要なのは「mail( )」のところです。メールを送る時の送信者やメールのタイトルなどを指定できます。オプションは以下の通りです。
>to: メールの宛先
from: メールの送信者
cc: Cc 
bcc: Bcc
subject: メールのタイトル
date: 送信日時
reply_to: 返信用のメールアドレス

ここではto:には送信先のメールアドレス（'target@yahoo.co.jp'）を、subject:にはメールのタイトル（'Action Mailerからのお知らせ'）をそれぞれ入力しました。

✅ コントローラー（トリガー）に実行文を追記
メールを送信する処理をtest_email.rbファイルに「test_email(user)」という関数名で用意しましたが、関数を呼び出す実行する処理を記述する必要があります。やり方は簡単で「TestMailer」クラスで定義した「test_email(user)」関数を好きなコントローラーのアクション（関数）に追記するだけです。
例としてツイッターを投稿した場合にメールを送信したいため、対象のコントローラーに次のように追記しました。

```ruby
 def create
    @tweet = Tweet.create(tweet_params)
    if @tweet.valid?
      @tweet.save
      TestMailer.test_email("テスト").deliver  #ここに追記
      redirect_to root_path
  end
```
「TestMailer.test_email("テスト").deliver」のところですが、TestMailerというクラスのtest_email(user)を呼び出し、deliverメソッドを実行しています。TestMailer？？test_email(user)？？ってなんぞや？と思われるかもしれませんが、これは先ほど作成したtest_email.rbに書いてある通りです。

```ruby
class TestMailer < ApplicationMailer

  def test_email(user)
```
引数として"テスト"を渡しています。

✅ メールの本文（viewファイル）を用意する
自動生成されたviewフォルダー（app/views/test_mailer)のところにメールの本文となるviewファイルを作ります。ファイル名は「test_email.html.erb」と「test_email.text.erb」２つ用意します。railsの特徴としてtest_email.rbで宣言したメソッド名とviewファイル名は同じでなければならない点に注意してください。違う名前だと認識できません。２つ用意する理由はhtml形式の本文が読めないメールサービスもあるからです。action mailerは優先的にhtmlを先に探し、なければtextファイルを探します。これはとても便利な機能ですね。また、test_email.rbの変数をそのままviewファイルでも使えます。

```ruby
#test_email.html.erb
<!DOCTYPE html>
<html>
  <head>
    <meta content='text/html; charset=UTF-8' http-equiv='Content-Type' />
  </head>
  <body>
    <h1><%= @user %>様、example.comへようこそ。</h1>
      <p>
      example.comへのサインアップが成功しました。
      <br>
    </p>
    <p>
      このサイトにログインするには、<%= @url %>をクリックしてください。
    </p>
    <p>これでテストは終了です！おめでとう！</p>
  </body>
</html>
```
```ruby
#test_email.text.erb
<%= @user %>様、example.comへようこそ。
===============================================
example.comへのサインアップが成功しました。
このサイトにログインするには、<%= @url %>をクリックしてください。
これでテストは終了です！おめでとう！
```

✅ railsを起動してツイッターを投稿してみる
ご自身で作成したアプリなどでコントローラーの機能を実行します。今回の場合はツイッターに投稿してみました。投稿が成功するとメールが送信される形になります。
![スクリーンショット 2021-04-24 10.06.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/966135/a45bab3b-15b4-f508-2646-962e179914b3.png)

viewファイルで書いた内容通り、メールが届きました。

# 参考サイト
https://railsguides.jp/action_mailer_basics.html
https://railsguides.jp/configuring.html
https://www.sejuku.net/blog/48739
https://qiita.com/annaaida/items/81d8a3f1b7ae3b52dc2b
https://stackoverflow.com/questions/31009419/connection-refused-connect2-for-localhost-port-25-rails/31009864
https://teratail.com/questions/44816
http://tatsuya1970.com/?p=7542
https://guides.rubyonrails.org/action_mailer_basics.html
https://dharmdip.wordpress.com/2012/03/22/rails-actionmailer-setup-with-yahoo-smtp-setting/