🙆‍♀️

Rails|グループ作成③(通知メールの送付)

2023/08/06に公開

こちらが最新版です。
https://zenn.dev/airiin/articles/18ee443fde6d8c

要件

グループオーナーのみグループ詳細ページに「Notice an Event」リンクを表示させる
「Notice an Event」をクリックすると、メール作成画面に移動
タイトル・本文を入力できるフォームの作成
タイトル・本文を入力後
送信ボタンをクリックすると、グループメンバーにメールが送信される
その後、「送信が完了しました」と表示しその下に内容を記述

開発環境

ruby 3.1.2p20
Rails 6.1.7.4
Cloud9

前提

前回の記事の続きです。
https://zenn.dev/airiin/articles/6ecc7f19dcd467

ActionMailer とは

Ruby on Rails に組み込まれているメール送信機能のこと。
Action Mailer を使うと、Ruby on Rails からメールを送信できます。

実際にMailer利用の流れを記述しておきます。

Mailerの作成

$ rails g mailer メーラー名

サーバー設定

メール送信にはサーバーが必要です。
config/environments/development.rbにサーバー設定を記述します。

config_environments/development.rb
  config.action_mailer.raise_delivery_errors = true
  config.action_mailer.delivery_method = :smtp
  config.action_mailer.smtp_settings = {
    port:                 587,
    address:              'smtp.gmail.com',
    domain:               'gmail.com',
    user_name:            '<YOUR EMAIL ADDRESS>', #送信元のメールアドレスになる
    password:             '<YOUR EMAIL PASSWORD>', 
    authentication:       'plain',
    enable_starttls_auto: true
  }

上記の例では、自身のgmailアドレスをサーバーにしています。

メーラーの編集

app/mailer/メーラー名.rb

def send_when_admin_reply(user, contact)
  @user = user
  @answer = contact.reply_text
  mail to: user.email, subject: 'お問い合わせありがとうございます'
end

上記のようなメソッドを mailメソッドと呼びます。
mailメソッドが予備ださえっると、メール本文が記載されているビューが読み込まれます。

メール本文(メーラービュー)の作成

<h2><%= @user.name %>様</h2>
<p>この度はお問い合わせありがとうございます。</p>

<p>[ご回答]</p>
<p><%= @answer %></p>

メールの送信処理

以上でメールの設定が完了しました!
実際にメールの送信処理を行うには、各コントローラのアクションからメーラーを呼び出す必要があります。

controllers/メーラー名.rb

def update
  contact = Contact.find(params[:id])
  contact.update(contact_params)
  user = contact.user
  メーラー名.send_when_admin_reply(user, contact).deliver
end

https://qiita.com/annaaida/items/81d8a3f1b7ae3b52dc2b#action-mailerとは

メーラーの作成

rails g mailer ContactMailer

サーバー設定

config/environments/development.rb にサーバー設定を記述。

config/environments/development.rb

config.action_mailer.raise_delivery_errors = true

config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
 address:              'smtp.gmail.com',
 port:                 587,
 domain:               'gmail.com',
 user_name:            ENV['MAILER_ADDRESS'],
 password:             ENV['MAILER_PASSWORD'],
 authentication:       'plain',
 enable_starttls_auto:  true
}

config.action_mailer.raise_delivery_errors = true
この部分は初期設定で false になっているので、 true に変更します。

それ以下の部分は初期設定で書かれていないので、ファイル下部(endの直前)に記述します。

config.action_mailer.delivery_method = :smtp
メールの送信方法を設定しています。ここでは smtpとしています。

Simple Mail Transfer Protocolの略。インターネットなどのTCP / IPネットワークで標準的に用いられる、メールを送信するための通信プロトコルの一つ。

手紙を例にすると、ポストに投函(とうかん)され、郵便局で宛先別に振り分けられ、相手の最寄りの郵便局へ届けられる。ここまでの過程がメールにおけるSMTPの役割になる。つまり、SMTPはメールを相手のメールサーバーまで届ける仕組みといえる。

SMTPはメールを送信するための通信プロトコルであるのに対し、メールを受信するための通信プロトコルは「POP」と呼ばれる。これはPost Office Protocolの略である。ちなみに送信用サーバーは「SMTPサーバー」、受信用サーバーは「POPサーバー」と呼ばれる。

https://mypage.otsuka-shokai.co.jp/contents/business-oyakudachi/words/smtp.html

config.action_mailer.smtp_settings
この部分で、詳細を設定しています。

address:
リモートメールサーバーの利用を許可する。

port:
メールサーバーが万一ポート25番で動作していない場合はここで変更する。

domain:
HELOドメインを指定する必要がある場合はここで行なう。

user_name:
メールサーバーで認証が必要な場合はここでユーザー名を指定する。

password:
メールサーバーで認証が必要な場合はここでパスワードを指定する。

:authentication:
メールサーバーで認証が必要な場合はここで認証の種類を指定する。:plain(パスワードを平文で送信)、:login(パスワードをBase64でエンコードする)、:cram_md5(チャレンジ/レスポンスによる情報交換と、MD5アルゴリズムによる重要情報のハッシュ化の組み合わせ)のいずれかのシンボルを指定する。

enable_starttls_auto:
SMTPサーバーでSTARTTLSが有効かどうかを検出して有効にする。デフォルトはtrue。

その他の設定については、Railsガイドに詳しく書かれています。
https://railsguides.jp/action_mailer_basics.html#action-mailerを設定する

自分の gmailアドレスを送信元に設定する場合、
・アプリパスワードの取得が必要
・メールアドレスとアプリパスワードを環境変数に代入する
・環境変数をGitにpushしないようにする

必要があります。

アプリパスワードの取得

Googleアカウント → セキュリティ → ログインの2段階認証をON → アプリパスワードの設定
より、アプリパスワードを取得します。

メールアドレスとアプリパスワードを環境変数に代入する

まず、dotenv-railsというGemをインストールします。

Gemfile
gem 'dotenv-rails'
$ bundle install

次に、アプリ直下に .env というファイルを作成します。

$ touch .env

次に、.env ファイルに以下のように記述します。

.env
MAILER_ADDRESS=<自分のgmailアドレス>
MAILER_PASSWORD=<自分のgmailアドレスのアプリパスワード>

次に、.gitignore に .envを追加し、Gitに push しないようにします。

.gitignore
/.env

最後に、config/environments/development.rb を編集します。

config/environments/development.rb
 user_name:            ENV['MAILER_ADDRESS'],
 password:             ENV['MAILER_PASSWORD'],

これでセキュリティ設定は完了です。
正しく代入できているかどうか、rails cで確認しましょう。

$ rails c 

コンソール上で
ENV['MAILER_ADDRESS'] と入力して、 自身のメールアドレスが表示されればokです!

https://qiita.com/ki_87/items/82b28f89a8552506a169

Gemのインストール

Gemfileに

gem 'net-smtp'

を追記して、

$ bundle install

を実行します。

config/initializers/devise.rb の編集

config/initializers/devise.rb
  config.mailer_sender = '自身のメールアドレス'

初期設定ではサンプルのメールアドレスが記述されているので、自分のメールアドレスに書き換えます。

メーラーの編集

今回、application_mailer.html.rb は変更しません。
contact_mailer を以下のように記述します。

app/mailer/contact_mailer.rb
class ContactMailer < ApplicationMailer

  def send_mail(mail_title, mail_content, group_users)
    @mail_title = mail_title
    @mail_content = mail_content
    mail bcc: group_users.pluck(:email), subject: mail_title
  end
  
end

pluck
テーブルの中の、特定のカラムの値を全て取得して、配列に格納するメソッドです。
https://pikawaka.com/rails/pluck
上記では、group_users の 全emailアドレスを取得しています。

@mail_title@mail_content は、
後でビューに渡せるように、インスタンス変数に格納しています。

コントローラの記述

groups_controller.rb
  def new_mail
    @group = Group.find(params[:group_id])
  end

  def send_mail
    @group = Group.find(params[:group_id])
    group_users = @group.users
    @mail_title = params[:mail_title]
    @mail_content = params[:mail_content]
    ContactMailer.send_mail(@mail_title, @mail_content, group_users).deliver
  end

new_mail アクションでは、新しいメールを作成する画面を表示します。

send_mail アクションでは、メール送信ボタンを押した後、実際にメールを送信します。

params[:mail_title]
params[:mail_content]
この部分で、new_mailビューで入力した値を取得しています。

ContactMailer.send_mail(@mail_title, @mail_content, group_users).deliver
この部分では、Mailerで設定した send_mailメーラーメソッドを利用しています。
deliverメソッドでメールを送信します。

Notice an Event ボタンの作成

グループオーナーのみに表示される、Notice an Event ボタンの部分を作成します。

groups/show.html.erb
<td><%= link_to "Notice an Event", group_new_mail_path(@group), class: "btn btn-info" %></td>

groups/new_mail ビューの作成

groups/new_mail.html.erb
<div class="container">
  <div class="row">
    <div class="col-sm-12 col-md-8 col-lg-5 px-5 px-sm-0 mx-auto">
      <h2>Event Mail</h2>
      <%= form_with url:group_send_mail_path(@group), method: :get, local: true do |f| %>

        <div class="form-group">
          <%= f.label :title %>
          <%= f.text_field :mail_title, class: "form-control" %>
        </div>

        <div class="form-group">
          <%= f.label :content %>
          <%= f.text_area :mail_content, class: "form-control" %>
        </div>

        <div>
          <%= f.submit "送信", class: "btn btn-success" %>
        </div>

      <% end %>
    </div>
  </div>
</div>

groups/send_mail ビューの作成

groups/send_mail.html.erb
<div class="container d-flex flex-column align-items-center text-left">
  <div>
    <h3 class="mb-3">送信が完了しました。</h3>
    <p class="mb-1">内容は以下の通りです。</p>
    <div>
      [タイトル]<p class="font-weight-bold"><%= @mail_title %></p>
    </div>
    <div>
      [本文]<p class="font-weight-bold"><%= safe_join(@mail_content.split("\n"),tag(:br)) %></p>
    </div>
  </div>
</div>

safe_join
ヘルパーメソッドの1つ。配列に含まれる文字をエスケープして結合して、改行する。
https://techracho.bpsinc.jp/hachi8833/2014_06_19/17964
http://www.code-magagine.com/?p=11783

contact_mailer/send_mail ビューの作成

contact_mailer/send_mail.text.erb
======================================

New event from <%= @mail_title %> !!

======================================

Title:
<%= @mail_title %>

Details:
<%= @mail_content %>

以上で完成です!試しに送ってみたメールがきちんと届きました◎

参照

https://zenn.dev/goldsaya/articles/0e4187f0cbf326#gmailの設定を変更

https://qiita.com/ki_87/items/67f8965e8de17e95ac1c#メイラーを作成

追記

メーラー部分がわかりにくかったので、修正しました。こちらが最新版です。
https://zenn.dev/airiin/articles/18ee443fde6d8c

Discussion