6
2

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 3 years have passed since last update.

ActionMailer、Rakeタスク、wheneverで作るメール自動配信機能

6
Posted at

目標

管理者ユーザーに毎朝8時に総記事数、昨日投稿された記事情報を送る機能を実装します。

実装

実装の手順は

  1. Mailerの作成
  2. メールを送信できるか確認
  3. RakeタスクにMailerの処理を登録
  4. wheneverで定期実行
    それでは行こう!

1. Mailerの作成

まずMailerを作成します。
コマンドで実行してもいいですが今回は手動でファイルを追加していきます。
app/mailers/にファイルを作成します。

ターミナル
$ touch app/mailers/admin.mailer.rb #命名は自由

作ったファイルはApplicationMailerを継承させメソッドを定義します。
このメソッドはMVCのControlerとViewの考え方と同じように一つ一つに送るメール内容であるViewが存在します。
今回は全体の記事数と昨日の記事情報の変数を定義しています。

app/mailers/admin.mailer.rb
class AdminMailer < ApplicationMailer
  
  def report
    @article_count = Article.count
    @article_published_yesterday = Article.where(created_at: 1.day.ago.all_day)
    mail(to:'admin@example.com', subject: '[定期連絡] 昨日の記事の集計結果')
  end
end
 mail(to:'admin@example.com', subject: '公開済記事の集計結果')

ここの部分はメールを送る相手のメールアドレスとメールの件名部分になります。

続いてメール本文部分のViewを作ります。

ターミナル
$ mkdir app/views/admin_mailer
$ touch app/views/admin_mailer/report.html.erb

作成したファイルにメール本文を入力します。

app/views/admin_mailer/report.html.erb
<p>総記事数: <%= @article_count %></p>
<% if @article_published_yesterday.present? %>
  <% @article_published_yesterday.each do |article| %>
    <p>タイトル: <%= article.title %></p>
    <p>投稿者: <%= article.user.name %></p>
  <% end %>
<% end %>

これでmailer部分は完成です。

2. メールを送信できるか確認

mailerができたので実際にメールを送れるのかを確認します。
確認方法はletter openerというgemを使っていきます。
Gemfileに以下を追記してbundle install

Gemfile
group :development do
  gem 'letter_opener'
  gem 'letter_opener_web', '~> 1.0'
end
ターミナル
$ bundle install

インストールできたら設定をしていきます。
以下を追加してください。
設定に関しては公式通りなので説明は特にしません。

config/environments/development.rb
config.action_mailer.delivery_method = :letter_opener_web
config.action_mailer.perform_deliveries = true
config/routes.rb
 mount LetterOpenerWeb::Engine, at: '/letter_opener' if Rails.env.development?

ここまでできたらサーバーをたちあげてhttp://localhost:3000/letter_openerにアクセスしてください
以下のような画面がでできたらOKです。
スクリーンショット 2021-07-01 11.01.22.png

ここで送られてきたメールの内容を見ることができます。

それではメールを送っていきましょう。
コンソールを立ち上げます。

ターミナル
$ rails c

deliver_nowというメソッドを使うことでメールを今すぐに送信してくれます。

ターミナル
irb(main):001:0> AdminMailer.report.deliver_now

ここでまたletter_openerを確認してメールが送られてきてたらOKです!

3. RakeタスクにMailerの処理を登録

メールが送れることを確認できたらメール送信の処理をRake タスクに登録していきます。
ターミナルでタスクを作成します。

ターミナル
$ rails g task article_report

作成されたタスクファイルにメール送信処理を登録します。

lib/task/article_report.rake
namespace :article_report do
  desc '管理者に総記事数、昨日投稿された記事のタイトルと投稿者をメール送信' #解説
  task mail_article_report: :environment do  #タスク名
    AdminMailer.report.deliver_now #実行したい処理
  end
end

Rakeタスクからメールが送れるかを確認していきましょう。

ターミナル
$ rake -T

表示されているかを確認して表示されていれば実行していきます。

ターミナル
$ rake article_report:mail_article_report

ここでまたletter openerを確認して送信されていればOKです。

4. wheneverで定期実行

最後にwheneverを使ってメール送信の処理を定期実行できるようにしていきましょう!

gemをインストール。

Gemfile
gem 'whenever', require: false
ターミナル
$ bundle install

インストールできたら設定ファイルをインストールしていきます。

ターミナル
$ bundle exec wheneverize .

[add] writing `./config/schedule.rb'
[done] wheneverized!

ここでschedule.rbというファイルが作成されるのでそこに設定を書いていきます。

config/schedule.rb
require File.expand_path(File.dirname(__FILE__) + '/environment')
# cronを実行する環境変数
rails_env = ENV['RAILS_ENV'] || :development
# cronを実行する環境変数をセット
set :environment, rails_env
# cronのログの吐き出し場所
set :output, "#{Rails.root}/log/cron.log"

# 時間指定
every 1.minutes do
  rake 'article_report:mail_article_report'
end
every 1.minutes do
  rake 'article_report:mail_article_report'
end

この部分にrakeタスクで登録した処理を書きます。
最初は実際に動いているかを確認するために1分毎にメールを送信することにします。

ターミナルでコマンドを入力することで反映されます。

まずエラーがないかを確認するので以下を入力
登録したRakeタスク名が入っていればOKです。

ターミナル
$ bundle exec whenever 

次に現在設定されているcronを確認するために以下を入力
最初なので何も表示されないはずなのでそれでOK

ターミナル
$ crontab -l

そしたら設定を反映していきます。
以下を入力することで設定が反映されます

ターミナル
$ bundle exec whenever --update-crontab 

反映されているかを確認するためにもう一度以下を入力
以下のような表示があれば設定が反映されています。

ターミナル
$ crontab -l

# Begin Whenever generated tasks for:...
# End Whenever generated tasks for:...

設定が反映されているのを確認できたら
実行状況を確認していきます。
ログファイルを開いて

log/cron.log
/usr/bin/open file:////Users/asahi/Desktop/review/tmp/letter_opener/1625029929_4833531_b61109f/rich.html

のような記述があればOKです。
実際にletter openerでも確認しましょう。

確認ができたらこのまま1分毎にメール送信されるのは邪魔なので設定を変更していきます。
以下のコマンドでcronからデータを削除します。

ターミナル
$ bundle exec whenever --clear-crontab

実際に削除されているかを確認するために

ターミナル
$ crontab -l

を実行して何も表示がされなかったらOKです。

それではschedule.rbに毎朝8時にメールが届くように設定を書き換えていきます。

config/schedule.rb
# Rails.rootを使用するために必要
require File.expand_path(File.dirname(__FILE__) + '/environment')
# cronを実行する環境変数
rails_env = ENV['RAILS_ENV'] || :development
# cronを実行する環境変数をセット
set :environment, rails_env
# cronのログの吐き出し場所
set :output, "#{Rails.root}/log/cron.log"

# 時間指定
every 1.day, at: '8am' do #変更場所
  rake 'article_report:mail_article_report'
end
ターミナル
$ bundle exec whenever --update-crontab 

ターミナルで反映したら完成です!

エラー対応

log/cron.logでOperation not permittedというエラーが出た方は(自分は出た)以下の記事が役立ったので参考にしてください。

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?