Edited at

Action Mailerのdelivery_methodに独自の配信方法を追加する

More than 1 year has passed since last update.

Action Mailerのdelivery_methodに独自の配信方法を追加してみます。

Action Mailerは内部で mail gem を使っていますが、このgemは配信方法がpluggableになっており、

配信方法にsmtp、sendmail、file(メールをファイルとして保存する)、testが選べます1

で、自社でメール送信APIというものを作った2のでAction MailerからそのAPIにリクエストを投げるようにしたい。

Railsはとてもカスタマイズ性が優れており、実は独自の配信方法を簡単追加できるようになっている。

まず普通にAction Mailerのクラスを作る。

# app/mailers/user_mailer.rb

class UserMailer < ActionMailer::Base
def welcome_email
mail(from: 'from@example.com',
to: 'to@example.com',
subject: 'my subject')
end
end

app/views/user_mailer/welcome_email.html.erbapp/views/user_mailer/welcome_email.text.erbも適当に作る。

次に独自の配信方法を行うクラスを作る。

引数を1つ持ったinitializeメソッドと引数を1つ持ったdeliver!メソッドを作る。

initializeメソッドの引数には、後述する設定ファイルで設定した値が渡ってくる。

deliver!メソッドには、UserMailerクラスのmailメソッドに渡した値が渡ってくる。

詳しくはmail gemのこの辺のソースを読むとよいです。

# app/mailers/my_mail_api_delivery.rb

class MyMailApiDelivery

def initialize(settings)
@settings = settings
end

def deliver!(mail)
# ここでAPI送信処理を呼び出す
MailApi.deliver({from: mail.from.first,
to: mail.to.first,
subject: mail.subject,
text_body: mail.text_part.body.raw_source,
html_body: mail.html_part.body.raw_source,
reply_to: @settings[:reply_to],
return_path: @settings[:return_path]
})
end
end

次に設定ファイルに独自の配信方法を設定する。

add_delivery_methodメソッドを呼ぶと、xxx_settingsというアクセサメソッドが定義される

要はsmtp_settingsみたいに使える。

# config/application.rb

ActionMailer::Base.add_delivery_method :my_mail_api_delivery, MyMailApiDelivery
config.action_mailer.delivery_method = :my_mail_api_delivery
config.action_mailer.my_mail_api_delivery_settings = {
reply_to: 'reply_to@example.com',
return_path: 'return_path@example.com'
}

あとはいつものようにUserMailer.welcome_email.deliver_nowのようにメール送信すれば、API経由でメール送信がされる。





  1. ActionMailerではその4つだが、mail gemでは配信方法にSMTP、Sendmail、Exim、FileDelivery、SMTPConnection、Testが選べる。 



  2. メール配信停止ユーザには送らないようにする処理とか、メールの種類によってメール配信ソフトウェア独自のヘッダーを付与したりする処理とか、メール開封ログをとるための処理とかを共通化するために各システムから利用可能なAPIを作った次第