Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
5
Help us understand the problem. What is going on with this article?
@kyoooko

【Rails】wheneverでバッチ処理を行う(未読通知が3件以上溜まったらAction Mailerでメール送信)

wheneverで定期的にバッチ処理を行い、「未読通知が3件以上溜まったらAction Mailrでメール送信」する実装方法を記載します。対象者には毎朝午前8時に下記のようなメールが送信されます。

前提

  • 通知機能を実装ずみ

スクリーンショット 2020-08-26 14.01.44.png

私の場合は上記のような通知機能を作成済みです。

大まかな流れ

  1. Action Mailerでメーラー生成
  2. 「未読3件以上のユーザーを見つけてメールを送る」処理をアクションメーラで定義
  3. メール文面作成
  4. wheneverの導入
  5. 2を1日に1回、wheneverで実行(メール送信)

実装方法

1. Action Mailerでメーラー生成

  • Action Mailerの基本については下記の記事に詳しく載っています

【Rails入門説明書】Action Mailerについて解説
【初心者向け】Ruby on Railsアプリでメール送信機能を実装する方法

  • メーラーを生成
rails g mailer ScheduledProcessing

下記のファイルができる

フォルダ・ファイル名     
app/meilers/application_mailer.rb     controllerみたいなイメージ   
app/meilers/scheduled_processing_mailer.rb      controllerみたいなイメージ
app/views/scheduled_processing_mailer (フォルダ) viewみたいなイメージ

2. 「未読3件以上のユーザーを見つけてメールを送る」処理をアクションメーラで定義

  • app/meilers/application_mailer.rb
class ApplicationMailer < ActionMailer::Base
  default from: "ノミジョイ!チーム(ここは送り先。任意の名前を入力) <delivery@nomijoy.com>"
  layout 'mailer'
end
  • app/meilers/scheduled_processing_mailer
class ScheduledProcessingMailer < ApplicationMailer
  def check_notice_mail
    @url = "https://nomi-joy.com/users/sign_in"

    users_with_unckecked_notices = User.all.select do |user|
      user.passive_notifications.where(visited_id: user.id, checked: false).count >= 3
    end

    users_with_unckecked_notices_mails = users_with_unckecked_notices.pluck(:email)

    mail(subject: "未読の通知が3件以上あります", bcc: users_with_unckecked_notices_mails)
  end
end

メソッド名をcheck_notice_mailにしていますが、ここは任意で問題ありません。
@url = "https://nomi-joy.com/users/sign_in"は、送信するメールにアプリケーションのログイン画面へとぶURLを表示したかったので記載しましたが必要なければ記載しなくてOKです。

selectは返り値が真の要素を集めた配列を返すメソッドなので、users_with_unckecked_noticesは未読通知が3件以上のUserたちの配列になっています。
「今いる全Userを一人ずつ調べる。userに紐づく(受信)通知が未読通知が3件以上あるかどうかを。それが真なら該当するUserを配列にする。配列にしたものがusers_with_unckecked_notices。」という感じです。

'user.passive_notifications.where(visited_id: user.id, checked: false)'は通知機能の設計によって変わるかと思いますので適宜ご自身の実装に合わせて変更してください。

pluckは引数に設定したカラム(ここではemail)のデータのみ集めて配列にしてくれるメソッドです。なので、users_with_unckecked_notices_mailsは下記のようになっています。

users_with_unckecked_notices_mails
=> ["test1@test.co.jp","test2@test.co.jp"]

'mail(subject: "未読の通知が3件以上あります", bcc: users_with_unckecked_notices_mails)'でメールを送信します。bccをtoに置き換えてもOKです。

3. メール文面作成

  • app/views/scheduled_processing_mailer (フォルダ) に下記ファイルを新規作成
  • ファイル名     
    check_notice_mail.html.erb     html    
    check_notice_mail.text.erb      text
  • check_notice_mail.html.erb

  • <!doctype html>
    <html lang="ja">
    <head>
    <meta content="text/html; charset=UTF-8" />
    <style>
    /* h2,p{
    color:#215c89;
    } */
    </style>
    </head>
    <body> 
    <hr>
    <h3>未読の通知が3件以上あります</h3>
    <hr>
    <p>通知は【フォローされたとき】、【ダイレクトメッセージが届いたとき】、【新規ノミカイに招待されたとき】、【カンジから何かしらの連絡を受けたとき】に届きます。</p>
    <p>◆詳細は下記よりログインして【Notice(通知)】からご確認いただけます。</p>
    <p>&ensp;ノミジョイ!ログインページ:<br>&ensp;<%= @url %></p>
    <br>
    <p>※このメールは送信専用です。</p>
    <hr>
    <h3>ノミジョイ!チーム</h3>
    <hr>
    </body>
    </html>
    
  • check_notice_mail.text.erb

===============================
 未読の通知が3件以上あります
===============================
通知は【フォローされたとき】、【ダイレクトメッセージが届いたとき】、【新規ノミカイに招待されたとき】、【カンジから何かしらの連絡を受けたとき】に届きます。

◆詳細は下記よりログインして【Notice(通知)】からご確認いただけます。
  ノミジョイ!ログインページ:
  <%= @url %>

※このメールは送信専用です。
===============================
 ノミジョイ!チーム
===============================

4. wheneverの導入

  • こちらの記事を参考に設定する

Rails メール自動配信機能をActionMailerとwheneverを使用して実装する

5. 2を1日に1回、wheneverで実行(メール送信)

  • schedule.rbを下記に変更(下記は開発環境を前提の記述)
# 絶対パスから相対パス指定
env :PATH, ENV['PATH']

# ログファイルの出力先
set :output, 'log/cron.log'

# ジョブの実行環境の指定(実行環境はprodaction環境がデフォルト設定)
set :environment, :development

# 日本時間の午前8:00にメール送信される(JSTは+9:00なので-9:00の時間を記述)
# 未読通知が3件以上たまっているユーザーにメール通知
every 1.days, at: '11:00 pm' do
  runner "ScheduledProcessingMailer.check_notice_mail.deliver_now"
end

今回は日本時間の午前8:00にメール送信される設定にしました。最初はデバックのために下記のようにして確かめてもいいと思います。

every 1.minutes do
   runner "ScheduledProcessingMailer.check_notice_mail.deliver_now"
end
  • schedule.rbの変更をcronに登録
bundle exec whenever --update-crontab
  • 反映されているか確認
crontab  -l 

ScheduledProcessingMailer.check_notice_mailに記載があれば登録されています

  • ログはlog/cron.logにから確認できます

=>これでメール送信されるはずです!!

  • バッチ処理を停止したい場合(cronの中を空にする)
bundle exec whenever --clear-crontab
  • 反映されているか確認
crontab  -l 

空になっていたらOK

5
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
kyoooko
WEBエンジニアを目指し勉強中です。自分の学びのアウトプット、躓いたところの備忘録として記録します。

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
5
Help us understand the problem. What is going on with this article?