RailsにSendGridのX-SMTPAPIを組み込んで、メールの大量送信などを実現する

  • 20
    いいね
  • 0
    コメント

こんにちは。株式会社LITALICOにてエンジニアをしている@yoshi_kskです。

LITALICO Advent Calendar 2016』9日目の記事です。

LITALICOではメール配信システムとしてSendGridを導入しており、メールの一括送信や各種指標の計測に利用しています。
今回はSendGridをRailsで使う上で押さえたい、SendGrid APIの使い方についてまとめてみました。

SendGridの提供API

種類

SendGridは下記の4種類のAPIを提供しています。

  • X-SMTPAPI
  • WebAPI v2
  • WebAPI v3
  • WebHook API

できること

上記のAPIを利用することで、下記の様な動作を実現できます。

  • 1通の送信で1000件~10000件の大量送信
  • 予約配信
  • メールのカテゴリ別で開封率・クリック率を取得できる

導入検討

導入する上での懸念点

現在、Ruby on Railsで自社サービスを開発しています。
そのため、公式のrubyライブラリを確認したのですが、どうもrailsっぽくない。
https://github.com/sendgrid/sendgrid-ruby

require 'sendgrid-ruby'
include SendGrid

from = Email.new(email: 'test@example.com')
subject = 'Hello World from the SendGrid Ruby Library!'
to = Email.new(email: 'test@example.com')
content = Content.new(type: 'text/plain', value: 'Hello, Email!')
mail = Mail.new(from, subject, to, content)

sg = SendGrid::API.new(api_key: ENV['SENDGRID_API_KEY'])
response = sg.client.mail._('send').post(request_body: mail.to_json)
puts response.status_code
puts response.body
puts response.headers

一応、ActionMailerもMailクラスのラッパーなのでやれないことはないのですが、
すでにActionMailerを用いたコードベースがあったので、それらを書き換えるという選択肢は躊躇われました。

結局どうしたか

ActionMailerの機構を維持しつながら自前でコードを書くことにしました。
SendGridのAPIの中でも、X-SMTPAPIはSMTPプロトコルでAPIを利用できます。
ActionMailerを利用する上ではこれが最適だと考え、X-SMTPAPIを利用することにしました。

導入方法

基礎編

SendGridのX-SMTPAPIは、メールのヘッダー部分にJSON形式でパラメーターを与えることで利用することができます。

class UserNotifier < ActionMailer::Base
  default :from => 'any_from_address@example.com'

  def send_signup_email(user)
    # カテゴリをつける場合の例
    xsmtp_api_params = { category: ['category1', 'category2'] }
    header['X-SMTPAPI'] = JSON.pretty_generate(xsmtp_api_params)

    @user = user
    mail( :to => @user.email,
    :subject => 'Thanks for signing up for our amazing app' )
  end
end

参考:
https://sendgrid.kke.co.jp/docs/API_Reference/SMTP_API/using_the_smtp_api.html

ものすごくシンプルですね。

一応の注意点ですが、

RFC 821ではテキスト行の最大長さは1000文字です。この文字列をご自身で生成する場合、上記の制限に収まるよう確認することをお勧めします。

https://sendgrid.kke.co.jp/docs/API_Reference/SMTP_API/using_the_smtp_api.html

とあるので、JSON.pretty_generateでJSONの改行をするようにしています。
https://docs.ruby-lang.org/ja/latest/method/JSON/m/pretty_generate.html

JSON.generateをすると改行がないJSONになってしまい、テキスト行の長さが1000文字を超える可能性があります。

実践編

大量送信をする

xsmtp_api_params = { to: ['メールアドレス1', 'メールアドレス2', ...] }
header['X-SMTPAPI'] = JSON.pretty_generate(xsmtp_api_params)

最大は10000件まで同時送信可能ですが、SendGrid側の処理速度が遅くなってしまうので1000件までにしましょう。

https://sendgrid.kke.co.jp/blog/?p=1300

予約送信をする

時間指定をしてあげることで、メールが届く時間を指定することが出来ます。

time = Time.zone.now + 1.hour
xsmtp_api_params = { send_at: time.to_i }
header['X-SMTPAPI'] = JSON.pretty_generate(xsmtp_api_params)

実際に試した上での注意点なのですが、
送信時刻は実際に送信された時刻のままであり、届く時間のみが変わるようです。
なのでメーラーによっては、送信時刻でソートしているため、過去のメールの中に埋もれてしまうこともあります。

カテゴリをつけてメールを区別する

上の方で書いたやつです。

xsmtp_api_params = { category: ['category1', 'category2'] }
header['X-SMTPAPI'] = JSON.pretty_generate(xsmtp_api_params)

メール種別ごとにカテゴリをつけることで、各メールの種類ごとに開封率・クリック率を計測できます。

メールでPDCAを回すには必須ですね。
ただし、カテゴリは累計100個までが推奨らしいので注意。

現状、トラック可能なカテゴリの数には制限はありません。しかし、ユニークカテゴリ数は100を超えないことを推奨 します。これによりダッシュボード内のStatistics機能の利用性が向上するためです。また、ユニークカテゴリ数が多い場合、メール送信速度に悪い影響を与えます。

https://sendgrid.kke.co.jp/docs/API_Reference/SMTP_API/categories.html

まとめ

上記の方針で、Railsでも簡単にSendGridのAPIを利用することができます。

SendGridには他にもユーザーごとに配信コンテンツを変更する機能があります。応用が効くのでぜひ試してみてください。

ユーザーごとに配信コンテンツを変更する
https://sendgrid.kke.co.jp/docs/API_Reference/SMTP_API/substitution_tags.html

次回は@kamesenninさんがAndroidでよく見る系のメディアを作る際に押さえておくべきライブラリ集について書いてくれます。