1
/
5

Ruby on RailsでSendGrid(Web API)メール送信を実装


業務でSendGridのSMTPを用いてメールをユーザー宛に送信していたが、送信されるメール毎にカテゴリーを付与し、コンバージョン率を調査したいとの社内マーケからの要望を受け実装。

そのため、SMTPでカテゴリーを付与しようとしたが、カテゴリー設定がSMTPではできないことが判明し、Web APIにて実装しようと思ったところ、意外と参考文献が少なかったので備忘録も兼ねて記事とします。

ちなむと今回は、Web APIを用いてメール送信するところが難所なのではなく、カテゴリーを付与するところで詰まりました。


また、今回APIの呼び出しに使用したのはsendgrid-rubyというgemになります。

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のAPI取得

APIの取得に関しては公式ドキュメントを参照。

極力権限絞る方が万が一流出した際に影響範囲が少なく済むので、必要最低限でMail Sendのみfull access にすれば取り急ぎ、メール送信は動作します!

APIキーを管理する
SendGridでは、各機能を利用する際の認証情報としてAPIキーを利用します。 APIキーには、次のような特徴があります。 メール送信およびAPIアクセスにのみ利用できる Webポータルのログインには利用できない パーミッションを設定して機能単位でアクセス制限をかけることができる こういった特徴を利用して、アプリケーション別、オペレータ別、サーバ別など、目的別に認証情報を管理することができます。万が一APIキーが漏洩した場合でも、個別に削除することで被害を最小限に抑える、といった柔軟な運用ができます。
https://sendgrid.kke.co.jp/docs/Tutorials/A_Transaction_Mail/manage_api_key.html




コード実装


ここからの実装の流れは以下2つの記事を参照しました。


Action Mailerのdelivery_methodに独自の配信方法を追加する - Qiita
Action Mailerのdelivery_methodに独自の配信方法を追加してみます。Action Mailerは内部で mail gem を使っていますが、このgemは配信方法がplugg...
https://qiita.com/sheepland/items/0bbf5c6f9fba08caf0a6
Rails: SendGrid(Web API)とAction Mailerでメールを送信する|TechRacho by BPS株式会社
こんにちは、yamadaです。入社から1年半ほど経ちますが、初めての記事になります。 今回はRailsとSendGridでメール送信を行った時の手順をまとめようと思います。 Rails 5.2 SendGrid(V3 Mail Send API) sendgrid.comより APIキーの作成 まずはSendGridのAPIキーを作成します。作成方法は公式ドキュメントをご確認ください。 権限は使用目的に合わせて設定しましょう。単純なメール送信だけであれば「Mail Send」を「Full Access」に
https://techracho.bpsinc.jp/yamada/2018_12_22/67222



最終的なコード

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では一緒に働くエンジニアを募集しています!

ファッションに興味があるエンジニアのご応募お待ちしております!

Railsエンジニア
ファッション×採用を加速させる!Railsエンジニア募集!
2016年11月に創業。ファッション業界特化の求人プラットフォーム「READY TO FASHION」を開発・運営するスタートアップです。 弊社は、若者や既存の枠を超える「人」の力によって、旧態依然としたファッション業界の変革を促進し、「業界に従事する人」や「ファッションを楽しむ人」の生活を豊かにすることを目指しています。 そのために、採用におけるコミュニケーションだけでなく、業界のコミュニケーションにおける課題をITの力で解決し続けます。 【主な事業内容】 ・求人メディア事業 ファッション業界特化の求人プラットフォーム「READY TO FASHION」 https://www.readytofashion.jp 弊社のメイン事業。2017年3月にプロダクトをリリースし、現在は900社を超えるファッション企業、50000人以上のユーザーに登録していただいております。アパレル業界だけでなく、広義的にファッションを扱う企業情報を掲載。 ・CtoCマッチング事業 ファッションビジネスマッチングアプリ「fatch」 2019年2月ローンチ:https://www.readytofashion.jp/lp/fatch ・メディア事業 ファッション好きな若者のためのWEBマガジン「READY TO FASHION MAG」 https://www.readytofashion.jp/mag/ ・コミュニティー|学生マーケティング事業 ファッション系学生団体の組織「fashion community 1.0」 https://www.readytofashion.jp/mag/fashioncommunity1_0.html ・イベント事業 株式会社 三越伊勢丹と共催の『DENIM ACT NIGHT(デニムアクトナイト)』 https://www.readytofashion.jp/mag/news/denim_act_night_201803/
READY TO FASHION
フロントエンドエンジニア
ファッション×HRを加速させるフロントエンドエンジニア募集!
2016年11月に創業。ファッション業界特化の求人プラットフォーム「READY TO FASHION」を開発・運営するスタートアップです。 弊社は、若者や既存の枠を超える「人」の力によって、旧態依然としたファッション業界の変革を促進し、「業界に従事する人」や「ファッションを楽しむ人」の生活を豊かにすることを目指しています。 そのために、採用におけるコミュニケーションだけでなく、業界のコミュニケーションにおける課題をITの力で解決し続けます。 【主な事業内容】 ・求人メディア事業 ファッション業界特化の求人プラットフォーム「READY TO FASHION」 https://www.readytofashion.jp 弊社のメイン事業。2017年3月にプロダクトをリリースし、現在は900社を超えるファッション企業、50000人以上のユーザーに登録していただいております。アパレル業界だけでなく、広義的にファッションを扱う企業情報を掲載。 ・CtoCマッチング事業 ファッションビジネスマッチングアプリ「fatch」 2019年2月ローンチ:https://www.readytofashion.jp/lp/fatch ・メディア事業 ファッション好きな若者のためのWEBマガジン「READY TO FASHION MAG」 https://www.readytofashion.jp/mag/ ・コミュニティー|学生マーケティング事業 ファッション系学生団体の組織「fashion community 1.0」 https://www.readytofashion.jp/mag/fashioncommunity1_0.html ・イベント事業 株式会社 三越伊勢丹と共催の『DENIM ACT NIGHT(デニムアクトナイト)』 https://www.readytofashion.jp/mag/news/denim_act_night_201803/
READY TO FASHION
このストーリーが気になったら、遊びに来てみませんか?
ファッション×採用を加速させる!Railsエンジニア募集!
READY TO FASHIONでは一緒に働く仲間を募集しています
2 いいね!
2 いいね!

同じタグの記事

今週のランキング

高草木 大地さんにいいねを伝えよう
高草木 大地さんや会社があなたに興味を持つかも