Edited at

RailsとHerokuを利用してメールを自動的に定期配信する

Railsで作成したApplicationで、Mailをある条件で自動的に発行したかったので、その時の実装したことのメモです。

(※ 例. 誕生日におめでとうMailを自動的に送信する・・・等)

本番環境は、Herokuを利用してデプロイしました。

仮のサンプルアプリケーションを作成する要領でメモします。


環境


  • Ruby 2.4.1

  • Rails 5.0.6

  • Heroku


    • SendGrid(※ Mailを送信する為に使用したHerokuのadd-on)

    • Heroku Scheduler(※ Herokuでrakeタスクを定期的に実行させる為にadd-on)




仮定

朝10:00にUserモデルに登録されているユーザー1人1人に

「Hello, user name!!]」

とMailを送ってくれるアプリをつくってみます。


1. Railsアプリケーションを作成

$ rails new sample_application


2. Modelをつくる

nameemailというcolumnを持つModelを作成します。

$ rails g model user name:string email:string

db:migrateします。

$ rails db:migrate

こんな感じのschemaファイルになるかと思います。


db/schema.rb

# 省略

create_table "users", force: :cascade do |t|
t.string 'name'
t.string 'email',
end
# 省略


3. サンプルユーザーを作成

(※ 本題とはあまり関係のない内容になります。)

User Modelに登録が1名もいないとイメージが湧かないので3名くらい登録しようと思います。

FakerというGemを利用します。


Gemfile

group :development, :test do

# 省略
# 省略
gem 'faker'
end

をGemfileに追加します。

※ 本番環境ではサンプルは必要無いかと思うのでgroupで制限をしています。

$ bundle install

bundle installしてgemを利用できるようにします。


db/seeds.rb

3.times do

User.create!(name: Faker::Name.name, email: Faker::Internet.email)
end

seeds.rbファイルに上記の感じで3名、ユーザーを作ります。

$ rails db:seed

これで開発環境で3名のサンプルユーザーが登録されたかと思います。


4. Mailerをつくる

定期配信するMailをActionMailerで実装します。今回の名前は、"UserMailer"にして#say_helloというメソッドでメールを送れるようにしようと思います。

rails g mailer UserMailer say_hello

上記、ジェネレーターで生成されたファイルを調整します。


app/mailers/user_mailer.rb

class UserMailer < ApplicationMailer

def say_hello(user)
@user = user

mail to: "#{@user.email}", subject: "Hello, #{@user.name}"
end
end



app/views/user_mailer/say_hello.html.erb

<h1>Hello, <%= @user.name %>!!</h1>



app/views/user_mailer/say_hello.text.erb

Hello, <%= @user.name %>


ジェネレーターで作成されているtest/mailers/previews/user_mailer_preview.rbファイルのコメントアウトされているURLをrails serverを起動し、ブラウザのアドレスバーに貼り付ければ送信するメール本文のプレビューが出来るのでおすすめです。


test/mailers/previews/user_mailer_preview.rb

# Preview all emails at http://localhost:3000/rails/mailers/user_mailer

class UserMailerPreview < ActionMailer::Preview

# Preview this email at http://localhost:3000/rails/mailers/user_mailer/say_hello
def say_hello
UserMailer.say_hello(User.first)
end

end


quita_say_hello.png


5. Rakeタスクをつくる

Mailを送信する為のRakeタスクを作ります。

名前空間は、greetingにします。

$ rails g task greeting

上記、ジェネレーターで自動生成されたファイルにタスクを記述します。


lib/tasks/greeting.rake

namespace :greeting do

desc '挨拶するメールを発行する。'
task say_hello: :environment do
users = User.all

users.each do |user|
UserMailer.say_hello(user).deliver
end
end
end


これで、後は、Herokuへデプロイし、Herokuのアドオンを利用して上記、rake taskを定期的に走らせればメールが自動的に定期配信されます。


6. Herokuへのデプロイ

Herokuへのデプロイする為にとりあえずGitを利用します。

$ git init

$ git add .
$ git commit -m 'sample application'

とりあえず、上記でGitのmasterブランチにコミットします。

Herokuでは、PostgreSQLを使用するので、本番環境にpg gemをインストールします。また、sqlite3 gemが本番環境に導入されないように気をつけます。


Gemfile

# 省略

group :development, :test do
# 省略
gem 'faker'
gem 'sqlite3' # <- ここのgroup内に移動させたかたいです。
end

# 省略

group :production do
gem 'pg'
end
# 省略


上記、Gemfileに追加したら--without productionオプションをつけてbundle installします。

本番用のgemをローカル環境にはインストールしないためです。

$ bundle install --without production

Gitを更新します。

$ git commit -a -m 'update Gemfile for Heroku'

Heroku createコマンドを事項してSample_applicationの実行場所を作成します。

※ HerokuのCLIのインストールは完了しているものとします。

$ heroku create

そして、デプロイします。

$ git push master

本番環境でのdb:migrateを実行します。

$ heroku run rails db:migrate

これで、Herokuへのデプロイ完了です。


7. HerokuのアドオンSendGridを追加

Herokuのアドオンのひとつ"SendGrid"を利用して本番環境でメールの送信をおこなえるようにします。

※SendGridの利用にはクレジットカードの登録が必要になりますが、メール数が一定数までは無料で利用できます。

$ heroku addons:create sendgrid:starter

Railsの本番用のconfigファイルに情報を記入します。


config/environments/production.rb

Rails.application.configure do

# 省略
config.action_mailer.raise_delivery_errors = true
↓↓↓↓↓↓↓ あなたの記事の内容
config.action_mailer.delivery_method = :smtp
───────
config.action_mailer.delicery_method = :smtp
↑↑↑↑↑↑↑ 編集リクエストの内容
config.action_mailer.default_url_options = { host: '<Herokuのアプリ名>.herokuapp.com' }
ActionMailer::Base.smtp_settings = {
address: 'smtp.sendgrid.net',
port: '587',
authentication: :plain,
user_name: ENV['SENDGRID_USERNAME'],
password: ENV['SENDGRID_PASSWORD'],
domain: 'heroku.com',
enable_starttls_auto: true
}
# 省略
end

上記、設定が完了したらgit commitしてHerokuへpushします。

$ git commit -a -m 'Send Grid setting'

$ git push heroku master

以上で、SendGridを利用してメールを送信できるようにしました。


8. HerokuのアドオンHeroku Schedulerを追加してrakeタスクを実行させる

Herokuのアドオン"Heroku Scheduler"を利用すれば、設定した時間にrakeタスクを実行させることができます。

※ Schedulerの利用にもクレジットカードの登録が必要です。一定までは無料で利用できるようですが、Dyonsがworkerである必要があるようです。

HerokuにHeroku Schedulerを追加します。

$ heroku addons:create scheduler:standard

Schedulerに実行するrakeタスクと時間を設定します。

下記コマンドを実行することでブラウザで設定画面が立ち上がります。

$ heroku addons:open scheduler

Screenshot-2017-9-30 Heroku Scheduler.png


  • 実行するコマンド: bundle exec rake greetig:say_hello

  • FREQUENCY: Daily

  • NEXT DUE: 1:00

    ※ Heroku Schedulerは、UTC「世界協定」の時間になります。日は、9時間早く進んでいる為、設定したい時間より9時間引いた時間をセットすることになります。

上記を設定して"Save"実行。

これで、rakeタスクが定期的に実行され毎朝メールを送信することができました。


参照