0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Rails グループメンバーにメールを送信する「Action Mailer」

Last updated at Posted at 2023-06-15

Rails Action Mailrを利用してグループメンバーにメールを送信する機能の実装方法

こんにちは!
Rails初学者の私ですが、先日グループ機能を応用してのAction Mailerを利用した
グループメール送信機能を実装しましたので
その実装方法を記事にしてみました。

今回やること

グループメンバーの一人からグループメンバー全員にメールを送れる。
メール送信後は送信完了画面を表示する。

前提

完成系のイメージ

スクリーンショット 2023-06-15 14.03.12.png

送信ボタンを押すとグループメンバー全員にメールが送られて、
送信完了画面に遷移します。
スクリーンショット 2023-06-15 14.03.58.png

メイラーを作成する

$ rails generate mailer EventMailer

このようにapp/mailers内にevevt_mailer.rbが作成されておりますでしょうか。
application_mailer.rbは元々あるものです。

スクリーンショット 2023-06-15 14.11.36.png

メールサーバーの設定

Gmailを使って送信できるように設定をしていきます。

config/environments/development.rb
config.file_watcher = ActiveSupport::EventedFileUpdateChecker
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:            'Gamilのアドレス',
  password:             'アプリパスワード',
  authentication:       'login',
  enable_starttls_auto: true
}

development.rbファイルにこの記述を追加します。

それぞれがどういう意味なのかは以下の記事がとても参考になります。
https://qiita.com/annaaida/items/81d8a3f1b7ae3b52dc2b

※アプリパスワードとはGamilの16桁のパスワードになります。
以下のやり方でやっていただければ上手くいくと思います。
簡単にいうと、
①Googleアカウト→セキュリティのGoogleでのログインで2段階プロセスをONにします。
②その後、アプリパスワードというものを設定できるようになるので、そこでアプリパスワードを設定します。
最初、アプリパスワード設定の画面が見つからず、違うやり方を試みたのですが、できませんでした。
2段階プロセスをONした後に、Googleアカウト→セキュリティのGoogleでのログインを見れば、アプリパスワードの設定ができるかと思います。

:bangbang:ちなみに、メールアドレスとパスワードをgithubにプッシュしないようにして下さい。
メールアドレスとパスワードは環境変数を使って、情報漏洩を防ぎます。
環境変数の設定方法の記事も作成しましたので、参考にしてみて下さい。
https://qiita.com/fumiya1800/items/6795e5e1046ec6f60aed

メーラーを編集する

application_mailer.rbには、どのメーラーにも共通することを記述していきます。

app/mailers/application_mailer.rb
class ApplicationMailer < ActionMailer::Base
  default from: '管理人<from@example.com>'
  layout 'mailer'
end

app/mailers/event_mailer.rb
class EventMailer < ApplicationMailer

  # 下のクラスメソッド内で使用するメソッド
  # このメソッド(アクション)が発動するとviews/event_mailer/send_notification.text.erbを呼出して、
  # メールを引数のデータに従ってメールを作成する。
  def send_notification(member, event)
    @group = event[:group]
    @title = event[:title]
    @body = event[:body]

    #メールを新規作成
     #from→送り主、to→送り先、subject→メールタイトルを入力
    @mail = EventMailer.new()
    
    mail(
      from: 'Gmailアドレス',
      to:   member.email,
      subject: '新規お知らせ'
    )
  end

  # このクラスメソッドが呼出されるとメールをグループメンバにメールを送信する
  # フォームでメールを送信を押したタイミングで発動(event_noticesコントローラの#create呼出時)
  def self.send_notifications_to_group(event) #引数のeventはevent_noticesコントローラでハッシュでデータを入れている
    group = event[:group] #group_idを呼出
    group.users.each do |member| #group_idに紐づくuserを順番に取り出す
      # 上のメソッドを発動すると各メンバー毎にメールが作られて、.deliver_nowで送信をしている
      EventMailer.send_notification(member, event).deliver_now
    end
  end
end

event_mailer.rbで記述したメソッドは次に作成するコントローラーで使用していきます。
後に紐づきが理解できるかと思いますので安心して下さい。

event_noticesコントローラーを作成

$ rails g controller public/event_notices

コントローラーを編集する

app/controllers/public/event_notices_controller.rb
class Public::EventNoticesController < ApplicationController
  before_action :authenticate_user!

  def new
    # view/event_notices/new.html.erbのフォームでグループIDが必要な為
    @group = Group.find(params[:group_id])
  end

  def create
    @group = Group.find(params[:group_id]) #newアクションと同じグループIDが入っている
    @title = params[:title] #フォームで入力された内容が入っている
    @body = params[:body] #フォームで入力された内容が入っている

    # 上記でインスタンス変数のデータを変数eventのハッシュとして登録
    event = {
      #キー =>  データ
      :group => @group,
      :title => @title,
      :body => @body,
      # enent[:group]のように呼び出すと@groupを呼び出せるようになる(event_mailerで使う)
    }
    
    #app/mailers/event_mailer.rbのメソッドを使用している
    EventMailer.send_notifications_to_group(event)
    # @group,@title,@bodyのデータを持ったまま、view/event_notices/sent.html.erbを表示する
    render :sent
  
  end

  def sent
    redirect_to group_path(params[:group_id])
  end

end

解説します。
newアクションではどのgroupのメールなのかを判断する為に
@group = Group.find(params[:group_id])を定義しています。

createアクションではview上のフォームに入力された内容を
変数名eventにハッシュとして格納しています。
これによって、enent[:group]のように呼び出すと
フォームに入力された@groupの内容を呼び出すことが可能となります。

そしてevent_mailer.rbに記述した
self.send_notifications_to_group(event)メソッドを
EventMailer.send_notifications_to_group(event)として使用しています。
このeventにはフォームに入力された内容がハッシュとして入っています。

コントローラー側の処理は以上で
最後にsent.html.erbページをrenderで表示しています。

EventMailer.send_notifications_to_group(event)を呼出し後は
event_mailer.rb内で処理が進んでいきます。
event_maile.rb内の処理の説明は上記の該当箇所で細かくコメントを残していますので
確認してみて下さい。

 ルーティングの編集

config/routes.rb
scope module: :public do
   resources :groups, except: [:new] do
     resource :permits, only: [:create, :destroy]
     resource :group_users, only: [:create, :destroy]
     resources :event_notices, only: [:new, :create] #追加
     get "event_notices" => "event_notices#sent" #追加
   end
   get "groups/:id/permits" => "groups#permits", as: :permits
end

viewページを作成

メール作成ページになります。

app/views/public/event_notices/new.html.erb
<div class="container">
  <h2 class="text-center">メール作成</h2>

  <div class="row mt-5">
    <div class="col-10 col-md-7 mx-auto">
      <%= 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, rows: 10, class: 'form-control' %>
        </div>
        <div class="form-group d-flex justify-content-end">
          <%= f.submit "送信", class: 'btn btn-success' %>
        </div>
      <% end %>
    </div>
  </div>

  <div class="row mt-5">
    <div class="col-md-9 mx-auto">
    <p class="text-center"><%= link_to "戻る", group_path(@group.id), class: 'text-dark' %></p>
    </div>
  </div>

</div>

次にメール送信完了ページです。

app/views/public/event_notices/sent.html.erb
<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>
</div>

グループ詳細ページにメール作成ページへ遷移するリンクを追加します。

app/views/public/groups/show.html.erb
<%= link_to 'グループメール', new_group_event_notice_path(@group), class: "btn btn-outline-info btn-sm" %>

メールの本文ページを作成する

このページ内容でGmailは作成されることになります。
ファイル名はevent_mailer.rb内のメソッド名と同じにします。

app/views/event_mailer/send_notification.html.erb
<!DOCTYPE html>
<html>
  <head>
    <meta content='text/html; charset=UTF-8' http-equiv='Content-Type' />
  </head>
  <body>
    <h2>お知らせ from <%= @group.name %></h2>
    <p>
      <タイトル><br>
      <%= @title %>
    </p>
    <p>
      <内容><br>
      <%= @body %>
    </p>
  </body>
</html>

以上でメール機能は完成となります。!!
ちなみにメールはテキスト形式での作成可能です。
今回はHTML形式で作成しています。

実装は以上になります。

最後に

最後までご覧いただきありがとうございます。
初学者なので、間違っていることや、分かりづらい箇所もあるかと思います。
何かお気づきがあれば遠慮なくご指摘頂けると幸いです。

ここまで長くなりましたが
最後までお付き合いいただきましてありがとうございました!!

0
0
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?