Ruby 2.1.1 Rails 4.1.0rc1にて動作確認。
Rails内からSES経由でのメール送信をキューを利用した非同期配信したかったので、設定してみました。
初期設定
ResqueでRedisを使用するため、事前にインストールしておきます。
- Gemfile
gem 'aws-ses', '~> 0.5.0', :require => 'aws/ses'
gem 'resque', :require => 'resque/server'
gem 'resque_mailer'
gem 'daemon-spawn', :require => 'daemon_spawn'
SESの設定
事前にAmazon SESのメール認可設定やアクセスキーの取得が必要になります。
こちらなどが参考になります。
RailsのActionMailerからAmazon SESのSMTPでメールを送信する
まずはRailsのAction MailerからSES経由でメール送信できるようにします。
/app/config/initializers/aws_ses.rb
require 'aws/ses'
ActionMailer::Base.add_delivery_method :ses, AWS::SES::Base,
:access_key_id => 'アクセスキーID',
:secret_access_key => 'シークレットアクセスキー'
/app/config/environments/production.rb
# 〜〜〜省略
config.action_mailer.default_url_options = { :host => 'hogehoge.com' } #SES上でverify登録した送信用メールアドレスのドメイン
config.action_mailer.raise_delivery_errors = true
config.action_mailer.delivery_method = :ses
メーラーの作成
SampleMailerクラスを生成します。
$ rails g mailer SampleMailer send_mail
class SampleMailer < ActionMailer::Base
default from: "sample@hogehoge.com" # SESのコンソール上で認可済のアドレス
def send_mail
@greeting = "Hi"
mail to: "user@sample.com", subject: "ActionMailer test"
end
end
メールテンプレートの修正が必要な場合は、send_mailアクションに対応したhtmlとtxtテンプレートが生成されているので、そちらを修正します。
Resqueの設定
/app/config/initializers/resque.rb
Resque.redis = 'localhost:6379'
Resque.redis.namespace = "resque:ignition:#{Rails.env}"
/app/config/routes.rb
# resqueの管理画面を使用する場合のみ追記 Productionでは弾くこと
mount Resque::Server, :at => "/resque"
Resque用のrake taskを作成します。
/app/lib/tasks/resque.task
require 'resque/tasks'
task "resque:setup" => :environment
動作確認
- worker立ち上げ
QUEUE=mailer rake resque:work
- コンソール上で実行
SampleMailer.send_mail.deliver
workerをバックグラウンドで動かす
/app/bin配下に任意の名前で実行ファイルを作って、chmod +xします。
ここではresque_mailerという名前で作成します。
#!/usr/bin/env ruby
require File.expand_path('../../config/application', __FILE__)
Rails.application.require_environment!
class ResqueWorkerDaemon < DaemonSpawn::Base
def start(args)
@worker = Resque::Worker.new('mailer')
@worker.verbose = true
@worker.work
end
def stop
end
end
ResqueWorkerDaemon.spawn!({
:processes => 1,
:working_dir => Rails.root,
:pid_file => File.join(Rails.root, 'tmp', 'pids', 'resque_worker.pid'),
:log_file => File.join(Rails.root, 'log', 'resque_worker.log'),
:sync_log => true,
:singleton => true,
:signal => 'QUIT'
})
設定後、以下のコマンドでバックグラウンドで起動できるようになります。
$ RAILS_ENV=production ./bin/resque_mailer start