[Rails]イベント通知機能①(Action Mailer)
Action Mailer
Action Mailerは、Railsに標準で組み込まれてるメール送信機能。
システム障害・メールマガジン機能などで使える一括送信ができる。
使用方法
メーラーを作成する
bin/rails generate mailer メーラー名
今回は bin/rails generate mailer event
で作成。
Winodwsだと、上記コマンドではbin/rails
が開いてしまい、ファイルが作成されなかったので下記コマンドのようにruby経由で明示的に実行しました。
ruby bin/rails generate mailer event
下記で作成も可能。
rails g mailer EventMailer
app/mailers/event_mailer.rb
が作成される。
class EventMailer < ApplicationMailer
end
app/mailers/application_mailer.rb
は、すべてのメール送信クラス(Mailer)の親クラス。
下記がデフォルトで設定されているので、こちらの修正は不要。
class ApplicationMailer < ActionMailer::Base
default from: 'no-reply@example.com'
layout 'mailer'
end
app/mailers/event_mailer.rb
event_mailer.rb の修正
ここで「通知メールの内容」や「送り方」を定義する。
app/mailers/event_mailer.rb
class EventMailer < ApplicationMailer
# (1)
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: "#{@group.name} の新しいイベント通知"
)
end
# (2)
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
(1)に関して
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: "#{@group.name} の新しいイベント通知"
)
end
通知用のインスタンスメソッド
def send_notification(member, event)
⇒ ユーザー(member)1人と、イベント情報(event)を受け取って、その人に1通メールを送るための関数。送るメールを定義している。
メールの本文で使う変数をセット
@group = event[:group]
@title = event[:title]
@body = event[:body]
@group, @title, @body は、ビュー(send_notification.html.erb など)で使われる変数。
イベントハッシュから必要な情報を取り出して代入している。
@mail = EventMailer.new()
新しいイベントを作成して、@mail
に代入。
メールの設定
mail(
from: ENV['MAIL_ADDRESS'],
to: member.email,
subject: "#{@group.name} の新しいイベント通知"
)
-
mail(...)
は、メールの送信先・件名・差出人を設定する。 -
from:
は差出人のアドレスで.env
に設定された環境変数を使用する。 - 件名は、
"#{@group.name} の新しいイベント通知"
にして、グループ名が入るようにして何のメールかわかりやすくしました。 - メール本文のは
app/views/event_mailer/send_notification.html.erb
で定義する。
(2)に関して
def self.send_notifications_to_group(event)
group = event[:group]
group.users.each do |member|
EventMailer.send_notification(member, event).deliver_now
end
end
グループ全体に通知するクラスメソッド。
グループ全体に一斉送信する関数。
def self.send_notifications_to_group(event)
グループのメンバーにメールを送る
group = event[:group]
group.users.each do |member|
EventMailer.send_notification(member, event).deliver_now
end
(1)のsend_notification(member, event)
が出てきた!
-
group.users.each
:グループに属する全ユーザーに対して1人ずつ処理。 -
EventMailer.send_notification(...)
:EventMailerクラスを使用して、送るユーザーごとにそれぞれのメールを生成。 -
.deliver_now
:即時送信(非同期じゃなくその場で送る)
コントローラ
event_notices_controller.rb
- 投稿機能などと同じように、new・createアクションを作成。
- メールを作成した後、送った後はどこにリダイレクトするかを設定。
class Public::EventNoticesController < ApplicationController
def new
@group = Group.find(params[:group_id])
end
def create
@group = Group.find(params[:group_id])
@title = params[:title]
@date = params[:date]
@body = params[:body]
event = {
:group => @group,
:title => @title,
:date => @date,
:body => @body
}
EventMailer.send_notifications_to_group(event)
render :sent
end
def sent
redirect_to group_path(params[:group_id])
end
end
ビューファイル
app/views/event_mailer/send_notification.html.erb
実際に送るメールの本文を設定する。
=========================================
<%= @group.name %>からの新しいイベントです。
===========================================
イベント名:
<%= @title %>
開催日時:
<%= @date %>
イベント内容:
<%= @body %>
app/views/public/event_notices/new.html.erb
入力フォームの作成。
<div class="main-title">
<h4><i class="fa-solid fa-envelope"></i>メール送信画面</h4>
</div>
<div class="detail-results">
<div class="detail-card">
<div class="detail-row">
<p>イベント告知など、メンバーに送信したいメールを入力してください。</p>
<%= form_with url: group_event_notices_path(@group), method: :post, local:true do |f| %>
<div class="form-field">
<b><i class="fa-solid fa-champagne-glasses"></i> イベント名</b>
<%= f.text_field :title, class: 'form-input' %>
</div>
<div class="form-field">
<b><i class="fa-solid fa-calendar-days"></i> 開催日時</b>
<%= f.text_field :date, class: 'form-input' %>
</div>
<div class="form-field">
<b><i class="fa-solid fa-question"></i> イベント内容</b>
<%= f.text_area :body, class: 'form-input' %>
</div>
<div class="form-field d-flex justify-content-end">
<%= button_tag(type: 'submit', class: 'submit-btn') do %>
<i class="fa-solid fa-paper-plane"></i>
<% end %>
</div>
<% end %>
</div>
</div>
</div>
app/views/public/event_notices/sent.html.erb
送信後、リダイレクト先、送信結果画面。
<div class="main-title">
<h4><i class="fa-solid fa-envelope"></i>送信結果画面</h4>
</div>
<div class="detail-results">
<div class="detail-card">
<div class="detail-row">
<h4>送信が完了しました。</h4>
<p>内容は以下の通りです。</p>
<hr>
<b><i class="fa-solid fa-champagne-glasses"></i> イベント名</b>
<p><%= @title %></p>
<b><i class="fa-solid fa-calendar-days"></i> 開催日時</b>
<p><%= @date %></p>
<b><i class="fa-solid fa-question"></i> イベント内容</b>
<p><%= @body %></p>
</div>
</div>
</div>
gmailに届かない問題が発生しているが、本日はここまで。
明日まとめたいこと
- gmailでは届かない問題解決方法
- .envとは
- SMTPとは
参考文献
Discussion