今回やりたいこと
rakeとwheneverについては、以下の記事で説明しています。
また、actionmailerについても、以下の記事で説明しています。
今回はこれらを組み合わせてメールの定期配信を実現したいと思います。
具体的には朝の9時にユーザーに対して「hello」とメールが送られるようにしたいと思います。
では、いきましょう!
mailerを準備
まずは、mailerの準備からやっていきましょう。
mailerの名前は何でもいいですが、わかりやすくGoodMorningとしておきましょうか。
rails g mailer GoodMorning
create app/mailers/good_morning_mailer.rb
invoke haml
create app/views/good_morning_mailer
create app/views/layouts/mailer.text.haml
create app/views/layouts/mailer.html.haml
invoke test_unit
create test/mailers/good_morning_mailer_test.rb
create test/mailers/previews/good_morning_mailer_preview.rb
クラスにメソッドを定義
では、以下のように簡単に宛先を記述しましょう。今回は、userを引数で渡す形にしたいと思います。
class GoodMorningMailer < ApplicationMailer
def good_morning(user)
mail to: user.email, subject: 'good morning!!'
end
end
メール内容を編集
では、次に送るメールの内容を編集していきましょう。
以下のディレクトリとファイルを作成して、
!!!
%html
%head
%meta{ 'http-equiv': 'Content-Type', content: 'text/html; charset=utf-8' }
%style{ type: 'text/css' }
/* Email styles need to be inline */
%body
= hello
必要に応じて'good_morning.text.haml'も編集してください。
ここまでできたら、railsコンソールを立ち上げて、メールが送れるか確認してみましょう。
前提条件として、ユーザーは既に作成しています。最初に紹介したactionmailerの記事を見てください。メール設定などもこちらに書いているので、確認をお願いします。
user = User.first
GoodMorningMailer.good_morning(user).deliver_now
無事メールは送れたので、次はこれを自動化できるようにしていきます。
余談ですが、
deliver_nowは同期的な送信方法で、delver_laterは非同期の送信方法です。
rails4.2まではdeliverメソッドがありましたが、4.2からは非推奨、rails5以降は使用できないので注意しましょう。
rakeタスク
rakeタスクとは
Rubyプログラムを自動化するためのフレームワークであるrakeを使って定義された、Railsアプリケーションで利用できるコマンドラインのタスクのことを指します。rakeタスクを作成することで、例えばデータベースの初期化や定期的なバッチ処理、ファイルの生成や削除などの定型的な作業を簡単に自動化することができます。
要は、このタスクを作成して、作業を自動化できるようになるわけですね。
したがって、メール送信のためのタスクを今回は作成していきます。
task作成
以下のように実行するとタスクを作成できます。
rails generate task good_morning
すると、lib配下のtasksディレクトリにgood_morningタスクが作成されます。
ちなみにtasks配下にディレクトリを作成してその中に作成することもできるので、状況に合わせて作成してください。
lib/tasks/good_morning.rake
このファイルを開いてみると、以下のようになっています。
namespace :good_morning do
end
tasks直下の場合はnamespace
はなくても構いませんが、今後さらに増えるのであればnamespaceをつけておく方が衝突を避けられるので無難だと思います。
namespaceを作成すると、その名前空間内でタスクをまとめることができ、rake namespace_name:task_name
のように呼び出すことができます。
一方で、namespaceを作成しない場合は、rake task_name
で直接タスクを呼び出すことができます。
rakeファイルの編集
話がそれましたが、作成したrakeファイルを編集していきましょう。
とは言っても今回の場合は簡単で、以下のように書きます。
テストなのでuser = User.first
にしておきます。
namespace :good_morning do
desc '朝の9時になったらユーザーにおはようメールを送信'
task good_morning_task: :environment do
user = User.first
GoodMorningMailer.good_morning(user).deliver_now
end
end
では、これをコンソールで呼び出してみます。
namespaceを使用しているのでrake good_morning:good_morning_task
で呼び出せるはずです。
ちなみに、rake -T
でrakeタスクの一覧も見れます。
wheneverで定期実行
最後にこのrakeタスクをwheneverで定期実行していきましょう。
wheneverは、時間に応じてタスクやコマンドを実行できるようにするgemの1つです。
例えば、朝の9時に実行するとか1週間ごとに実行するとかを設定できます。
こちらも冒頭の記事で説明していますが、要点だけ。
以下のgemをインストールして、wheneverize .
を実行すると、config/schedule.rb
が作成されます。
gem 'whenever', require: false
最初は全てコメントアウトされていますが、具体例が書かれているのでそちらを真似して書いていくこともできます。
今回は朝の9時に定期実行したいので、先ほどコンソールで送れることを確認したrakeタスクを記述します。
以下のように書くと、毎朝9時にrakeタスクを実行することができます。
余談ですが、タスク名をクオーテーションで囲まないとエラーが出ます。
every 1.day, at: '9am' do
rake 'good_morning:good_morning_task'
end
これが終わったら以下のコマンドを実行しましょう。
# wheneverの設定更新
bundle exec whenever --update-crontab
# 設定内容にエラーが無いか確認
bundle exec whenever
次にきちんと設定できたかは以下のコマンドで確認できます。
# 設定されているcronを確認
crontab -l
設定を削除する場合は以下のコマンドです。
# crontabの設定を削除
bundle exec whenever --clear-crontab
まとめ
以上がメールの定期配信の実現でした。
基本的な使い方は難しくありませんでしたが、複雑なことをしようとすると難しくなりそうですね。
また別の定期実行したいことが出てきたら記事にしたいと思います。