LoginSignup
7
6

More than 1 year has passed since last update.

【Rails】バッチ処理(whenever)で、1日1回メールを自動配信してみる

Last updated at Posted at 2021-04-08

ActionMailerとバッチ処理(whenever)を使って、指定頻度でメールを自動送信する方法をまとめています。

大まかな流れ

  1. メール送信用サーバーの設定(他の記事に飛びます)
  2. DailyMailerを生成
  3. ApplicationMailerとDailyMailerを編集
  4. メール本文の作成
  5. wheneverを導入
  6. schedule.rbを生成して、バッチ処理を記述
  7. cronにバッチ処理を反映する
  8. 処理が実行できているかlogファイルから確認

前提

  • Userモデルを作成した、かつusersテーブルにはemailカラムがあることを前提としています
  • STEP1の「メール送信用サーバの設定」ではGmailを使用するので、Googleアカウントを一つ用意してください。練習用の場合は、サブのアカウントや練習用アカウントで試される方が安心かと思います
  • この記事は、以前私が書いた記事と「手順4」まで重複部分があるため、部分的に抜粋・流用しています。ご了承ください。
  • すでにMailerを生成・編集し、メール本文の作成も終わっている場合は、「手順5」に進んでください。

実装手順

ではさくさくいきましょう!

手順1. メール送信用サーバーの設定

こちらについては、わたしが以前書いた記事の「STEP1~STEP2」に記載しているので、割愛します。
STEP2まで終わったら、この記事の「手順2」に進んでください。

手順2. DailyMailerを生成

ターミナルで以下のコマンドを実行し、DailyMailerdaily_notificationメソッドを一緒に生成します。Mailer名とメソッド名は好きなものを指定してOKです。

今回は1日1回の自動配信を例にとっていくので、Mailer名もメソッド名もそうしています。

terminal
$ rails g mailer DailyMailer daily_notification
# rails g mailer  <Mailer名>    <メソッド名>

これにより、以下が生成されます:

  • app/mailers配下に、application_mailer.rbdaily_mailer.rb
  • app/views/daily_mailer配下に、viewファイル( html.erbファイルとtext.erb

※メソッドは、Mailerと一緒に生成しなくても大丈夫ですが、手順4でメール本文を作成する際に自分でviewファイルを作成する工程が発生するので、この段階でメソッドごと生成してしまう方が手間がないかと思います。

手順3. ApplicationMailerとDailyMailerの編集

まず、application_mailer.rbには、すべてのMailerに共通の設定を記述します。これに対し、daily_mailer.rbには、DailyMailerに固有の設定を記述します。

なお、application_mailer.rbはデフォルトの記述のままでも動作するので、単に練習用・勉強用ということであれば、daily_mailer.rbの編集に進んでもOKです

application_mailer.rbを編集

app/mailers/application_mailer.rb
#デフォルトの記述
class ApplicationMailer < ActionMailer::Base
  default from: 'from@example.com'
  layout 'mailer'
end

#編集例
class ApplicationMailer < ActionMailer::Base
  default from:     "〇〇事務局",
          cc:       "hogehoge@gmail.com"
          bcc:      "hoge_hoge@gmail.com"
  layout 'mailer'
end

👆のdefalutメソッドは、共通の設定を記述する際に使用するもので、以下のような項目についてデフォルト値の指定が可能です:

項目 内容
to メインの送信先
cc メインではないが、共有しておきたい送信先
bcc 他の人に見られずに共有しておきたい送信先
subject メールのタイトル
from メールの送信元の名前
reply_to 返信先のメールアドレス ​
date メールの送信日時 ​

daily_mailer.rbを編集
こちらには、メール送信時に呼ばれるdaily_notificationメソッドを定義します。

app/mailers/daily_mailer.rb

def daily_notification
    default to: -> { User.pluck(:email) }
    mail(subject: "Daily Report of Your Record")
end

詳しく見ていきましょう:

  • default toで宛先を指定。宛先は、登録しているユーザー全員に自動配信する場合、User.pluck(:email)とし、Userのemailすべてを取得できる
  • subjectには任意の件名を指定できる

手順4. メール本文の作成

メールの内容は好きな内容で記入してください。

HTMLファイルで受け取れない/受け取りたくないuserがいる可能性もあるので、テキストファイルもあわせて用意しておくのが推奨されているようです。

app/views/daily_mailer/daily_notification.html.erb

<h2>Today's Record</h2>

<p>Here is the update on your record today!</p>
<p>Don't forget to check on our website</p>

<p>Sincerely,</p>
<p>Team ABC</p>
app/views/daily_mailer/daily_notification.text.erb
-------------------------------
       Today's Record
-------------------------------

Here is the update on your record today!
Don't forget to check on our website

Sincerely,
Team ABC

手順5. wheneverを導入

さて、いよいよwheneverを入れていきます。
ちなみにwheneverは、バッチ処理を行うためにcronを後で使用しますが、その設定を簡単に書けるgemのことです。

Gemfile

# ---- 前略 ---- #
gem 'whenever', require: false
end
terminal
$ bundle install

手順6. schedule.rbを生成して、バッチ処理を記述

次に、 schedule.rbファイルにバッチ処理の内容を記述していきます。
👇 まず schedule.rbをコマンドで生成しましょう

terminal
$ wheneverize .

👇 schedule.rbを開いて、バッチ処理を記述していきます

config/schedule.rb
# Use this file to easily define all of your cron jobs.
#
# It's helpful, but not entirely necessary to understand cron before proceeding.
# http://en.wikipedia.org/wiki/Cron

# Example:
#
env :PATH, ENV['PATH']
set :output, "log/cron.log"  #ログファイルの出力先を指定
set :environment, :development
#
# every 12.hours do
#   command "/usr/bin/some_great_command"
#   runner "MyModel.some_method"
#   rake "some:great:rake:task"
# end
#

every 1.days, at: '6:00 pm' do

# DailyMailerのdaily_notificationメソッド実行
  runner "DailyMailer.daily_notification"
end

# Learn more: http://github.com/javan/whenever

👆では、every 1.days, at: '6:00 pm'によって、毎日6:00PMにメールが自動配信されるように設定されています。

もし何時間おき、何分おき、といったように設定したい場合は、every 12.hours doevery 10.minutes doのように記述すればOKです。

手順7. cronにバッチ処理を反映する

さて、wheneverでは、schedule.rbに記述した内容(バッチ処理)がcrontabに反映される仕組みになっているので、早速反映させていきましょう。

terminal
$ bundle exec whenever --update-crontab
  [write] crontab file updated  #このように表示されていれば成功

次に、crontabに反映されているか確認します

terminal
$ crontab -l
#DailyMailer.daily_notificationの記述があればOK

手順8. 処理が実行できているかlogファイルから確認

さて、schedule.rbに先ほどset :output, "log/cron.log"を記述したのを覚えているでしょうか。

もし処理が正常に動いていて、メールが指定間隔・時間に自動配信できていれば、このlogファイルが生成されて、以下のような記述が、処理ごとに1行ずつ記述されているはずです。

log/cron.log
Running via Spring preloader in process xxxx
Running via Spring preloader in process yyyy

👇 最後に。
もし勉強用・練習用に作成した場合は、cronからデータを削除してバッチ処理を停止しておきましょう!

terminal
$ bundle exec whenever --clear-crontab

参考資料

-Rails メール自動配信機能をActionMailerとwheneverを使用して実装する
-Railsでwheneverを使ってcronを設定する
-Railsでメール自動配信機能をつくるまでの道程

7
6
0

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
7
6