【Rails】ActionMailer実装時にLetterOpnerWebが非常に便利だった。

#はじめに
RailsでActionMailer実装時にお試しでletter_opner_webと言うのを使ってみました。
非常に手軽で便利だったので、使い方などの整理と振り返り用のメモです。
※Rails標準にも「MailerPreview」と言う機能があるみたいなのですが、テスト利用を想定して作られたものみたいだったので、こちらのgemを使うことにしました。

間違えている所などあれば、ご指摘・指南いただければ嬉しいです。
（未解決課題なんかもあり、、、）

# Letter_opner_web
擬似的にメールの受信や閲覧ができる便利なgemです。
GitHubは[コチラ](https://github.com/fgrehm/letter_opener_web)

前提：開発環境での利用に特化
　　 ※テスト環境でも行けそうな気はするけど、それこそ「MailerPreview」か（・ω・）

# デモのご紹介
letter_opner_webはデモサイトが用意されています。
実装前にどんなものか気になる方は触ってみてください。

デモサイト：http://letter-opener-web.herokuapp.com/

**【 利用手順 】**
**①受信・閲覧のためのメール送信からスタート**
下記画面で[Email]と[Message]を入力して[Send mail]をクリック！
※Emailは存在しないものでも問題ありません
[![Image from Gyazo](https://i.gyazo.com/5ac9c05f6942de40fa3c95c7b33590d3.png)](https://gyazo.com/5ac9c05f6942de40fa3c95c7b33590d3)
**②画面下部に成功メッセージを確認**
下図のようなメッセージが出ていれば、送信に成功しています。
[![Image from Gyazo](https://i.gyazo.com/4ac5da851670e110c461dbcc2da8eaf3.png)](https://gyazo.com/4ac5da851670e110c461dbcc2da8eaf3)
**③letter_opner_web画面を開く**
デモ画面の"[Click here](http://letter-opener-web.herokuapp.com/inbox/) to see sent mails"のリンクをクリックすれば、letter_opner_webで実際に見れる画面が表示されます！
なお、EmailアドレスごとにメッセージBOXが存在するわけではなく、送信した全てのEmailアドレスのメール内容がここから確認できます。
（本番で使ったらセキュリティリスク高めな感じですね笑）
[![Image from Gyazo](https://i.gyazo.com/1a6e303e8174aada2f1675bbba2056e9.png)](https://gyazo.com/1a6e303e8174aada2f1675bbba2056e9)
**④テストメッセージ削除**
確認が完了したら、念のため画面左上の[Clear]ボタンでメール削除しておきましょう。
[![Image from Gyazo](https://i.gyazo.com/48efd1772e776f4b943e7f699c6d37c8.png)](https://gyazo.com/48efd1772e776f4b943e7f699c6d37c8)

こんな感じで、開発時にメールサーバなどを用意するのが手間だなと思ったら、まずはletter_opner_webでお試ししてみるのも良いかと^^
ありえないEmail宛のメッセージでも許容してくれるので、手軽さが増します。

# 設定方法（開発環境）
以下、letter_opner_webの設定方法をザクっとご説明。

## Gemfile追加
gemファイルに設定を追加して``bundle install``を実行してください。

```Gemfile
group ：development  do 
  gem ' letter_opener_web '、'〜> 1.0 '
end
```
## 設定ファイル追加
開発環境の環境設定ファイルにメーラの設定を追加します。

```config/environments/development.rb
config.action_mailer.default_url_options = {  host: 'localhost', port: 3000 }
ActionMailer::Base.delivery_method = :letter_opener
```

## ルーティング設定
画面を持っているものなので、ルーティングの設定が必要になります。
下記のように設定追加してください。

```config/routes.rb
Rails.application.routes.draw do
  # 足すのは↓の行だけです！
  mount LetterOpenerWeb::Engine, at: "/letter_opener" if Rails.env.development?
end
```

これでletter_opner_webの設定は終わり！
超簡単！あとは下記のアドレスにアクセス知れば確認ができます！！

letter_opner_web: http://localhost:3000/letter_opener

　↓　実際に開いてみるとこんな感じ　↓
[![Image from Gyazo](https://i.gyazo.com/00bde5a89c7942b70fb98403d82b578f.png)](https://gyazo.com/00bde5a89c7942b70fb98403d82b578f)

# 動作確認
設定はできたものの出来ればメールが飛ぶか見てみたいですよね。
と言う事で、サクッとメールも飛ばしてみましょう。

## ActionMailer作成
コンソールから、controller作るときと同じ要領でActionMailer作ります。
※公式ドキュメントには”SampleMailer”のように指定するように記述がありますが”Mailer"部分はジェネレートする際に勝手に付与されます。知らずにやるとSampleMailerMailerみたいに残念なフォルダやクラスが作成されるので注意です笑

```ターミナル
 $ rails g mailer Sample
 Running via Spring preloader in process 15548
      create  app/mailers/sample_mailer.rb
      invoke  haml
      create    app/views/sample_mailer
      invoke  test_unit
      create    test/mailers/sample_mailer_test.rb
      create    test/mailers/previews/sample_mailer_preview.rb
```

なお、controllerと同じく``rails d mailer Sample``で削除も可能です。

## ActionMailerを編集する
**①共通部**
Application_mailers.rbは、ActionMailer全体で適用されます。
初期状態で以下のように送信元メールアドレスとメールフォームが設定されています。
もし、送信元メールアドレスを変更したいのであれば、下記の``default from:``を編集してください。
※各Mailerで個別に送信元を編集することもできるようです

``` app/mailers/application_mailers.rb
class ApplicationMailer < ActionMailer::Base
  default from: 'from@example.com'      # 送信元メールアドレス
  layout 'mailer'                       # メール全体に適用されるメールフォーム（Viewsのapplication.html.hamlなどと共通の原理かと）
end
```
**②SampleActionMailer**
ここで送信メソッドを定義します。メソッド名は自由に決めちゃって良いかと思います。
今回メソッド内で設定するのはメールヘッダ部分のみです。
（body部も書けますが、管理が煩雑になるので基本的には切り出すようです）

``` app/mailers/sample_mailer.rb
class SampleMailer < ApplicationMailer
  attr_accessor :email,:title,:name
  def sample_mail(email,title,name)      #仮引数に@付きのインスタンス変数は指定できませんので注意
    @email = email                       #インスタンス変数に格納
    @title = title                       #インスタンス変数に格納
    @name  = name                        #インスタンス変数に格納
    mail  to: @email,                    #メールの宛先を指定
          subject: "【テストメール】#{@title}" #メールのタイトルを指定
  end
end
```
※モデルを使用していないため、無理やり項目作っていますが、普通は@userとかかと。


## メールフォーム（body部）を編集する
メールのbody部は、Viewsフォルダ配下に作成します。
``rails g``コマンドで実行した時点で、該当のActionMailerに対応するフォルダが、Viewsフォルダ配下に作成されています。このフォルダ配下に**ActionMailerで作成したメソッドと同名のファイルを作成**し、body部を記述します。

記述方法は、基本的にviews作成時と同じ感じです。
（プレーンテキストとhtmlで切り替えできそうですが、htmlのみを対象としています。）

```app/views/sample_mailer/sample_mail.html.haml
= "#{@name}さん"
%br
%p
  Hello World!!
```

設定自体はこれで完了です。
controllerなどからActionMailerを呼び出せばOK。
この部分ちょっと端折って、コンソールから検証してみます。
※今回端折りますが下図[4]のようにcontrollerなどに記載すればメール送信可能になります

```コンソール.railsc
#引数を下準備
[1] pry(main)> email = "test@gmail.ccooom"
=> "test@gmail.ccooom"
[2] pry(main)> title = "Hello World"
=> "Hello World"
[3] pry(main)> name = "はむすけ"
=> "はむすけ"
#ActionMailerを実行してみる（最後に”.deliver”付けないと送信されません！！！)
[4] pry(main)> SampleMailer.sample_mail(email,title,name).deliver
```
実行結果を見ると、どう言う順で読み込まれてるか、何となくイメージが湧きますね。

```コンソール.実行結果
Rendering sample_mailer/sample_mail.html.haml within layouts/mailer
Rendered sample_mailer/sample_mail.html.haml within layouts/mailer (9.2ms)
SampleMailer#sample_mail: processed outbound mail in 5075.2ms
Sent mail to test@gmail.ccooom (37.0ms)
Date: Sun, 15 Sep 2019 14:23:42 +0900
From: from@example.com
To: test@gmail.ccooom
Message-ID: <5d7dcade41695_3f143fbfadc14e5c744d@user-nameMacBook-Air.local.mail>
Subject: =?UTF-8?Q?=E3=80=90=E3=83=86=E3=82=B9=E3=83=88=E3=83=A1=E3=83=BC=E3=83=AB=E3=80=91Hello?=
 =?UTF-8?Q?_World?=
Mime-Version: 1.0
Content-Type: text/html;
 charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<!DOCTYPE html>=0D
<html>=0D
<head>=0D
<meta content=3D'text/html; charset=3Dutf-8' http-equiv=3D'Content-Type'>=
=0D
<style>=0D
  /* Email styles need to be inline */=0D
</style>=0D
</head>=0D
<body>=0D
=E3=81=AF=E3=82=80=E3=81=99=E3=81=91=E3=81=95=E3=82=93=0D
<br>=0D
<p>=0D
Hello World!!=0D
</p>=0D
=0D
</body>=0D
</html>=0D

=> #<Mail::Message:70092500977860, Multipart: false, Headers: <Date: Sun, 15 Sep 2019 14:23:42 +0900>, <From: from@example.com>, <To: test@gmail.ccooom>, <Message-ID: <5d7dcade41695_3f143fbfadc14e5c744d@user-nameMacBook-Air.local.mail>>, <Subject: 【テストメール】Hello World>, <Mime-Version: 1.0>, <Content-Type: text/html>, <Content-Transfer-Encoding: quoted-printable>>
```

この結果、下記の画面が開きます。
[![Image from Gyazo](https://i.gyazo.com/cd6fd41a2a7afe60bb88cf0a0545c3cf.png)](https://gyazo.com/cd6fd41a2a7afe60bb88cf0a0545c3cf)
成功はしているみたいですが、``rails s``してないからletter_opner_web自体は開けません（：_；)
と言うことで、``rails s``してから、適当なところでbinding.pryしてみましょう（あくまで面倒臭がる）

```コンソール.binding.pry
    5: def index
 => 6:   binding.pry

[1] pry(#<PostsController>)> email = "test@gmail.ccooom"
=> "test@gmail.ccooom"
[2] pry(#<PostsController>)> title = "Hello World"
=> "Hello World"
[3] pry(#<PostsController>)> name = "はむすけ"
=> "はむすけ"
[4] pry(#<PostsController>)> SampleMailer.sample_mail(email,title,name).deliver
```

この状態で[letter_opner_web](http://localhost:3000/letter_opener)にアクセスしてみましょう。今度はアクセスできるはず。
[![Image from Gyazo](https://i.gyazo.com/a55f8313a0af9d09ca9938bb63014469.png)](https://gyazo.com/a55f8313a0af9d09ca9938bb63014469)

#補足（課題込み）
letter_opner_webはプロジェクト単位でメールデータを保持しているようです。
上の図で``rails c``で試したメールも残っていることから、サーバ起動、停止などを繰り返しても消えることは無いようです。プロジェクトフォルダが肥大化しないよう注意が必要かなと思いました。

ちなみに送信メールの保存場所は「tmp/letter_opner/」配下です。
(デフォルトでgitignore対象となっています）
もし、保存場所を変えたい場合は、initilizerにletter_opner_web用のファイルを作成し、そこで定義すればOKみたいです。

```config/initializers/letter_opner_web.rb
LetterOpenerWeb.configure do |config|
  config.letters_location = Rails.root.join('public', 'email')
  # 上記パスの中身"#<Pathname:/Users/user-name/projects/miniblog/public/mail>"
end
```

※当方うまく設定できてません。試したところ、こうなります。

**＜それぞれの挙動＞**
　メールデータ格納先
　　→デフォルトの「tmp/letter_opner」のまま。フォルダ消しても蘇ってきます笑
　letter_opner_web参照先
　　→設定が効いているのか、何も見えなくなる笑

…畜生め（TωT)!!!
と思いつつ、configの設定がうまくいっていないのか・・・?!
と思い``rails s``した時点で、configの設定状況を確認してみる（↓）。
うん、想定通りに読み込まれてる。指定のパスもcdで行ける。（思考停止）

```console.
[1] pry(#<PostsController>)> LetterOpenerWeb.config.letters_location
=> #<Pathname:/Users/user-name/projects/miniblog/public/mail>
[2] pry(#<PostsController>)> LetterOpenerWeb.config
=> #<LetterOpenerWeb::Config:0x00007fb9d9ee2948
 @letters_location=#<Pathname:/Users/user-name/projects/miniblog/public/mail>>
```

ここに時間を割き過ぎるのもなので、一旦ここまで。
もう少しinitilizerとかconfigとか、理解が進めば思い返してみることもあるかも。。。

#まとめ
手軽にメール機能を試せるのは、いいな〜と感じました。
ただ、色々試していると基礎知識がまだまだ足りないな〜と思い知らされます^^;
今後も、より深くrubyやrailsを知っていけるように頑張ります。。


#参考
[GitHub:letter_opner_web](https://github.com/fgrehm/letter_opener_web)
[Rails公式ガイド：Action Mailer の基礎](https://railsguides.jp/action_mailer_basics.html)
[開発中にrailsから送信したメールを確認する](https://qiita.com/k-shogo/items/d85905535a64e82a3b2b)