Rails グループメンバーへメール送信
この続きです🏋🏻
⇩
グループのオーナーから、グループメンバーにメールを送信できるようにします!
要件
- グループオーナーのみグループ詳細ページに「Notice an Event」リンクを表示させる
- 「Notice an Event」をクリックすると、メール作成画面に移動
- タイトル・本文を入力できるフォームの作成
- タイトル・本文を入力後、送信ボタンをクリックすると、グループメンバーにメールが送信される
- その後、「送信が完了しました」と表示しその下に内容を記述
完成
groups/show.html.erb
⇩
new_mail.html.erb
⇩
send_mail.html.erb
Action Mailer
Ruby on Railsには標準でAction Mailerというメールの送信機能が組み込まれている!
例えば、
メールフォームの入力内容を業務担当者に自動送信
メールマガジンを一括メール送信
システム障害を検知してシステム担当者メール通知
など、色々な場面で活用することができる!
🌱わかりやすい記事 https://www.sejuku.net/blog/48739
メイラーを作成
rails g mailer ContactMailer
bin/rails generate mailer 任意のメイラー名 でOK!
こんな感じでMailerが作成される!
ターミナル結果
作成されたファイルのうち、「app/mailers/contact_mailer.rb」が、メール送信機能を実装するための空のクラスとなる。
サーバーを設定
(Gmailで送信するための設定)
メールサーバの設定をするには「config/environments/環境毎に設定.rb」に追記します。
Rails.application.configure do
# ----- 中略 ----- #
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: '送信元となるGmailアドレスを記入',
password: 'アプリパスワードを記入',
authentication: 'login',
enable_starttls_auto: true
}
end
すでに記述のあるconfig.action_mailer.raise_delivery_errors
がfalseになっていれば、trueに変更する!
port:は上記の数のままで問題ございません!
上から、config.action_mailer
というパラメーターに色んなオプションを指定しています。
1行目delivery_method
メールの送信方法を設定するためのメソッド
デフォルトで :smtpになっているらしい
ちなみにSMTPとは
メールを相手のメールサーバーまで届ける仕組みが「SMTP」だ。
「SMTP」とは「Simple Mail Transfer Protocol(シンプル・メール・トランスファー・プロトコル)」の略で、あえて訳せば「簡単なメールの送信の手順」というところだろうか。お約束ごとと考えてもいい。
「メールを送るよ〜」「ええで!」「宛先は〇●だよ」「りょ」「本文はかくかくしかじかだよ」「受け取ったで!」――とまぁそんな具合。
参照:https://time-space.kddi.com/ict-keywords/kaisetsu/20170824/2081
2行目 smtp_settings
SMTP サーバーを使用してメールを送信する場合に設定するための Action Mailer のオプションの一つ
- address: SMTP サーバーのアドレス。
- port: SMTP サーバーのポート番号。
- domain: アプリケーションのドメイン名。
- user_name: SMTPサーバーに接続するためのユーザー名。
- password: SMTPサーバーに接続するためのパスワード。
- authentication: 認証方式。通常、:login または :plain を使用。
- enable_starttls_auto: STARTTLS に対応している場合に、セキュアな接続を確立するために必要なオプション。
Gmailの設定を変更
Net::SMTPAuthenticationErrorにならないために、、
GmailのGoogleアカウントページから、アプリパスワードを取得!
Googleアカウント→セキュリティのGoogleでのログインで2段階プロセスをON、
その後、アプリパスワードというものを設定できるようになるので、そこでアプリパスワードを設定。
🌱こちらの記事のSTEP2アプリパスワードの取得部分がとてもわかりやすいです!
メールアドレスとパスワードをgithubにプッシュしないように気をつけること!
メーラーを編集
生成直後は、以下のような application_mailer.rb と
class ApplicationMailer < ActionMailer::Base
default from: 'from@example.com'
layout 'mailer'
end
空のメーラー
class ContactMailer < ApplicationMailer
end
が作られている。
application_mailerには全メーラー共通の設定を、
sample_mailerにはメーラー個別の設定を記述する!!
application_mailerはそのままでOK、
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
このsend_mailメソッドは、引数で渡されたタイトル、内容、グループメンバーのEmailアドレスを使って、グループメンバー全員にメールを送信するメソッド。
mailメソッドを使用して、BCCフィールドをグループメンバーのメールアドレスの配列で指定し、タイトルを設定している。
ちなみに、BCCは「Blind Carbon Copy」の略で、メールの本文の受信者に対して、他に誰がBCCに入っているかを見えないようにするためのフィールドです。
コントローラー記述
Group詳細ページのmailボタン
⇩
メール作成画面
⇩
メール送信完了画面
の流れです🌱
#該当部分のみ
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
〜解説〜
def send_mailでは、グループのメンバー全員にメールを送信するためのアクション
で、'viwes/groups/new_mail.html`のform_withで入力された値を受け取っている。
@group変数には、グループをidで検索して代入し、
group_users変数には、グループに所属する全ユーザーが代入されている。
@mail_titleと@mail_contentには、それぞれ送信するメールのタイトルと内容が代入され、
最後に、ContactMailer.send_mailメソッドを呼び出して、メールを送信します。
send_mailメソッドは、mailers/contact_mailer.rbファイルに記述されていて、deliverメソッドは、メール送信を実行します。
Viewページ
<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-sm btn-success" %>
</div>
<% end %>
</div>
</div>
</div>
<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とは
渡された複数の文字列を連結し、エスケープ処理を施した上で一つの文字列に変換するRailsのヘルパーメソッド。
エスケープ処理とは
HTMLやJavaScriptなどのテキストベースのファイルで特別な意味を持つ文字(例:<、>、&)をそのまま表示したり実行したりすると、意図しない結果を生む可能性があるため、その文字を無効化するための処理。
safe join無しの記述だと、コンテント内で入れていた改行がなくなってしまったりするらしい。
<%= link_to 'Notice an Event',group_new_mail_path(@group), class: "btn btn-sm btn-info" %>
ルーティングの記述
#該当部分のみ
resources :groups, only: [:new, :index, :show, :create, :edit, :update] do
resource :group_users, only: [:create, :destroy]
get "new/mail" => "groups#new_mail"
get "send/mail" => "groups#send_mail"
end
メールのview記述
=========================================
New event from <%= @group.name %>!!
=========================================
Title:
<%= @mail_title %>
Details:
<%= @mail_content %>
確認
この流れで問題なく送信できているような気になっていましたが、
肝心のメールが自分宛に届かず。。
なぜか調べたところ
devise.rbのconfig.mailer_senderに、
送信元となるGmailアドレス(development.rbのuserに記述したのと同じアドレス)を記入
しなければならないそう!
config.mailer_sender = '送信元となるGmailアドレスを記入'
🌱こちらの記事がとてもわかりやすかったです!!
また、development.rbに載っているメールアドレスと、アプリパスワードをgithubにそのままプッシュしないように注意です!
🌱参考にさせていただいた記事
上記とは違う書き方のメモ
メーラーの編集
class EventMailer < ApplicationMailer
def send_notification(member, event)
@group = event[:group]
@title = event[:title]
@body = event[:body]
@mail = EventMailer.new()
mail(
from: ENV['MAIL_ADDRESS'],
to: member.email,
subject: 'New Event Notice!!'
)
end
def self.send_notifications_to_group(event)
group = event[:group]
group.users.each do |member|
EventMailer.send_notification(member, event).deliver_now
end
end
end
サーバーを設定
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
address: 'smtp.gmail.com',
port: 587,
domain: 'gmail.com',
user_name: ENV['MAIL_ADDRESS'],
password: ENV['MAIL_PASSWORD'],
authentication: 'plain',
enable_starttls_auto: true
}
ルーティング
resources :groups, only: [:new, :index, :show, :create, :edit, :update] do
resource :group_users, only: [:create, :destroy]
resources :event_notices, only: [:new, :create]
get "event_notices" => "event_notices#sent"
end
コントローラー
class EventNoticesController < ApplicationController
def new
@group = Group.find(params[:group_id])
end
def create
@group = Group.find(params[:group_id])
@title = params[:title]
@body = params[:body]
event = {
:group => @group,
:title => @title,
:body => @body
}
EventMailer.send_notifications_to_group(event)
render :sent
end
def sent
redirect_to group_path(params[:group_id])
end
end
ビュー
<div class="container">
<div class="row justify-content-center">
<div class="col-6">
<h1>Event Mail</h1>
<%= form_with url: group_event_notices_path(@group), method: :post, local:true do |f| %>
<div class="form-group">
<%= f.label :title %>
<%= f.text_field :title, class: 'form-control' %>
</div>
<div class="form-group">
<%= f.label :body %>
<%= f.text_area :body, class: 'form-control' %>
</div>
<div class="form-group d-flex justify-content-end">
<%= f.submit "Send", class: 'btn btn-success' %>
</div>
<% end %>
</div>
</div>
</div>
<div class="container">
<div class="row justify-content-center">
<div class="col-6">
<h1>送信が完了しました</h1>
<p>内容は以下の通りです。</p>
<h2>[タイトル]</h2>
<p><%= @title %></p>
<h2>[本文]</h2>
<p><%= @body %></p>
</div>
</div>
=========================================
New event from <%= @group.name %>!!
===========================================
Title:
<%= @title %>
Details:
<%= @body %>
こんな書き方もある💡
Discussion