GitHub - sendgrid/sendgrid-ruby: The Official Twilio SendGrid Led, Community Driven Ruby API Library
The Official Twilio SendGrid Led, Community Driven Ruby API Library - sendgrid/sendgrid-ruby
https://github.com/sendgrid/sendgrid-ruby
業務でSendGridのSMTPを用いてメールをユーザー宛に送信していたが、送信されるメール毎にカテゴリーを付与し、コンバージョン率を調査したいとの社内マーケからの要望を受け実装。
そのため、SMTPでカテゴリーを付与しようとしたが、カテゴリー設定がSMTPではできないことが判明し、Web APIにて実装しようと思ったところ、意外と参考文献が少なかったので備忘録も兼ねて記事とします。
ちなむと今回は、Web APIを用いてメール送信するところが難所なのではなく、カテゴリーを付与するところで詰まりました。
また、今回APIの呼び出しに使用したのはsendgrid-rubyというgemになります。
APIの取得に関しては公式ドキュメントを参照。
極力権限絞る方が万が一流出した際に影響範囲が少なく済むので、必要最低限でMail Send
のみfull access
にすれば取り急ぎ、メール送信は動作します!
ここからの実装の流れは以下2つの記事を参照しました。
Railsは初期値でAction Mailer(smtp)を使用するので、新規でdelivery methodを追加してあげる。
今回実装したファイルは以下。
# config/initializers/sendgrid.rb
ActionMailer::Base.add_delivery_method :sendgrid, Mail::SendGrid,
api_key: Settings.sendgrid_api #settings.local.ymlの中にあるAPIキーを呼び出す。
# app/mailers/application_mailer.rb
class ApplicationMailer < ActionMailer::Base
def set_sendgrid_settings(category)
ActionMailer::Base.delivery_method = :sendgrid
headers['category'] = category
end
end
# lib/mail/send_grid.rb
class Mail::SendGrid
def initialize(settings)
@settings = settings
end
def deliver!(mail)
sg_mail = set_mail_information(mail)
add_content_and_category(sg_mail, mail)
sg = SendGrid::API.new(api_key: @settings[:api_key])
sg.client.mail._('send').post(request_body: sg_mail.to_json)
end
private
def set_mail_information(mail)
from = SendGrid::Email.new(email: mail.from.first)
to = SendGrid::Email.new(email: mail.to.first)
subject = mail.subject
content = SendGrid::Content.new(type: 'text/plain', value: mail.body.parts[0].body.raw_source)
SendGrid::Mail.new(from, subject, to, content)
end
def add_content_and_category(sg_mail, mail)
sg_mail.add_content(SendGrid::Content.new(type: 'text/html', value: mail.body.parts[1].body.raw_source))
sg_mail.add_category(SendGrid::Category.new(name: mail[:category].value))
end
end
app/mailers/application_mailer.rbで定義したメソッドset_sendgrid_settings('カテゴリー名')をmailerファイルの中で呼び出す。
以下test_mailer.rbのアクション内で定義した`set_sendgrid_settings('カテゴリー名')`を呼び出すことで、「test_mailerメソッドのdelivery_methodはsendgridのWeb APIを通して送信しますよ。」と指示する。
※引数でカテゴリー名を渡すことで、sendgridへカテゴリー名も付与することができる。
# app/mailers/test_mailer.rb
class TestMailer < ApplicationMailer
def test_mail
set_sendgrid_settings('This is test category')
mail(from: 'from@example.com', to: 'to@example.com', subject: 'テストメール')
end
end
# app/views/test_mailer/test_mail.text.erb
SendGrid送信テスト
set_sendgrid_settings('カテゴリー名')によって、lib/mail/send_grid.rbで定義したdeliver!メソッドが使用できる。
以下のinitializeによって、config/initializers/sendgrid.rbが呼び出されAPIを使用することができ、@settingsにAPIキーが代入される。
# lib/mail/send_grid.rb
class Mail::SendGrid
def initialize(settings)
@settings = settings
end
~
mailerから渡ってきたmail変数をsendgrid-rubyの所定のフォーマットに則って代入する。
以下のset_mail_information(mail)プライベートメソッドにてgemのフォーマットに則って代入する。
※SendGrid::Email.new()はgem特有のもの。詳しくは公式まで。
# lib/mail/send_grid.rb
class Mail::SendGrid
~
private
def set_mail_information(mail)
from = SendGrid::Email.new(email: mail.from.first)
to = SendGrid::Email.new(email: mail.to.first)
subject = mail.subject
content = SendGrid::Content.new(type: 'text/plain', value: mail.body.parts[0].body.raw_source)
SendGrid::Mail.new(from, subject, to, content)
end
~
以上の流れでメールは送信できる。
そもそも業務でSendGridを使用しているので、text/plain形式だけではなく、html形式のメールも送信するマルチパートメールを採用している。
上記までだと、text/plain形式のメールだけしか送れず、なんならhtml.erbファイルもある場合はエラーが出て送信できない。
あと、カテゴリーに関してもaction mailerのMail::Messageに含まれる引数しか渡せないため、独自に変数を渡すことは不可能だったので、別の方法で実装するしかなかった。
結論、gemの特性なのか知らないが、先にtext/plain形式のメールを指定しなければならないらしい。なので、html形式はadd_categoryというgemのメソッドを使用して追加することに成功した。
カテゴリーは、mailerのactionごとに指定したい場合には、header[:category]として含める必要があることがわかった。
※カテゴリー名はUS-ASCII文字セットのみ対応(日本語不可)ということにも注意。
該当箇所
html形式のメールはmail.body.partsの2番目に含まれているので、mail.body.parts[1]で指定してあげる。(1番目に格納されているのはtext/plain形式。)
# lib/mail/send_grid.rb
class Mail::SendGrid
~
def add_content_and_category(sg_mail, mail)
sg_mail.add_content(SendGrid::Content.new(type: 'text/html', value: mail.body.parts[1].body.raw_source))
sg_mail.add_category(SendGrid::Category.new(name: mail[:category].value))
end
end
以上でmailerのアクション毎にカテゴリー名を付与した上で、Web APIを経由しメール送信することが可能になった。
Sengridのダッシュボード上でもカテゴリー分け毎のコンバージョン率も確認できて、Webマーケからも感謝されました。
READY TO FASHIONでは一緒に働くエンジニアを募集しています!
ファッションに興味があるエンジニアのご応募お待ちしております!