Rails|グループ作成③(通知メールの送付)
こちらが最新版です。
要件
グループオーナーのみグループ詳細ページに「Notice an Event」リンクを表示させる
「Notice an Event」をクリックすると、メール作成画面に移動
タイトル・本文を入力できるフォームの作成
タイトル・本文を入力後
送信ボタンをクリックすると、グループメンバーにメールが送信される
その後、「送信が完了しました」と表示しその下に内容を記述
開発環境
ruby 3.1.2p20
Rails 6.1.7.4
Cloud9
前提
前回の記事の続きです。
ActionMailer とは
Ruby on Rails に組み込まれているメール送信機能のこと。
Action Mailer を使うと、Ruby on Rails からメールを送信できます。
実際にMailer利用の流れを記述しておきます。
Mailerの作成
$ rails g mailer メーラー名
サーバー設定
メール送信にはサーバーが必要です。
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アドレスをサーバーにしています。
メーラーの編集
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>
メールの送信処理
以上でメールの設定が完了しました!
実際にメールの送信処理を行うには、各コントローラのアクションからメーラーを呼び出す必要があります。
def update
contact = Contact.find(params[:id])
contact.update(contact_params)
user = contact.user
メーラー名.send_when_admin_reply(user, contact).deliver
end
メーラーの作成
rails g mailer ContactMailer
サーバー設定
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サーバー」と呼ばれる。
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ガイドに詳しく書かれています。
自分の gmailアドレスを送信元に設定する場合、
・アプリパスワードの取得が必要
・メールアドレスとアプリパスワードを環境変数に代入する
・環境変数をGitにpushしないようにする
必要があります。
アプリパスワードの取得
Googleアカウント → セキュリティ → ログインの2段階認証をON → アプリパスワードの設定
より、アプリパスワードを取得します。
メールアドレスとアプリパスワードを環境変数に代入する
まず、dotenv-rails
というGemをインストールします。
gem 'dotenv-rails'
$ bundle install
次に、アプリ直下に .env というファイルを作成します。
$ touch .env
次に、.env ファイルに以下のように記述します。
MAILER_ADDRESS=<自分のgmailアドレス>
MAILER_PASSWORD=<自分のgmailアドレスのアプリパスワード>
次に、.gitignore に .envを追加し、Gitに push しないようにします。
/.env
最後に、config/environments/development.rb を編集します。
user_name: ENV['MAILER_ADDRESS'],
password: ENV['MAILER_PASSWORD'],
これでセキュリティ設定は完了です。
正しく代入できているかどうか、rails cで確認しましょう。
$ rails c
コンソール上で
ENV['MAILER_ADDRESS'] と入力して、 自身のメールアドレスが表示されればokです!
Gemのインストール
Gemfileに
gem 'net-smtp'
を追記して、
$ bundle install
を実行します。
config/initializers/devise.rb の編集
config.mailer_sender = '自身のメールアドレス'
初期設定ではサンプルのメールアドレスが記述されているので、自分のメールアドレスに書き換えます。
メーラーの編集
今回、application_mailer.html.rb は変更しません。
contact_mailer を以下のように記述します。
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
テーブルの中の、特定のカラムの値を全て取得して、配列に格納するメソッドです。
上記では、group_users の 全emailアドレスを取得しています。
@mail_title
や @mail_content
は、
後でビューに渡せるように、インスタンス変数に格納しています。
コントローラの記述
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 ボタンの部分を作成します。
<td><%= link_to "Notice an Event", group_new_mail_path(@group), class: "btn btn-info" %></td>
groups/new_mail ビューの作成
<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 ビューの作成
<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つ。配列に含まれる文字をエスケープして結合して、改行する。
contact_mailer/send_mail ビューの作成
======================================
New event from <%= @mail_title %> !!
======================================
Title:
<%= @mail_title %>
Details:
<%= @mail_content %>
以上で完成です!試しに送ってみたメールがきちんと届きました◎
参照
追記
メーラー部分がわかりにくかったので、修正しました。こちらが最新版です。
Discussion