📧

[Rails][SendGrid][API] SendGrid導入まとめ

2025/01/05に公開

以前とある理由でSendGridを導入することとなったのですが、
運用のことまで考えたときに、意外と情報がまとまっていなかったのでメモとして残します。

SendGridのGemを導入

SendGridを導入するにあたって2つGemがあります。

本番環境で運用することを考えるとsendgrid-rubyを導入するかと思います。
理由としては以下の通りになります。

SendGrid管理画面でApiKey発行

APIを使うにあたって、認証キーが必要なので作成します。
権限を細かく設定できるので、メールバウンス用のAPIキーを作ることも可能でした。
詳しくは以下ドキュメントが参考になります。

https://sendgrid.kke.co.jp/docs/User_Manual_JP/Settings/api_keys.html

RailsアプリからSendGrid経由でのメール送信処理

具体的にはGemの以下メソッドを使ってメール送信をします。
https://github.com/sendgrid/sendgrid-ruby/blob/main/USAGE.md#post-mailsend

具体的にコードで書くとこのような感じになります。
個人的にはSendGrid::Personalizationでもバリデーションがあるので戸惑いました。

personalization = SendGrid::Personalization.new
personalization.add_to(::SendGrid::Email.new(email: 'to_email@example.com'))
sendgrid_personalization.add_cc(::SendGrid::Email.new(email: 'cc_email@example.com'))
sendgrid_personalization.add_bcc(::SendGrid::Email.new(email: 'bcc_email@example.com'))

mail = SendGrid::Mail.new
mail.from = ::SendGrid::Email.new(email: 'to_email@example.com')
mail.subject = 'hoge_subject'
mail.add_content(::SendGrid::Content.new(type: 'text/html', value: 'hoge_body'))
mail.add_personalization(personalization)

mail.to_json
# JSONの出力例
# {
#   "from" => {
#     "email" => "from_email@example.com"
#   },
#   "subject" => "hoge_subject",
#   "personalizations" => [
#     {
#       "to" => [
#         { "email" => "to_email@example.com" }
#       ],
#       "cc" => [
#         { "email" => "to_cc@example.com" }
#       ],
#       "bcc" => [
#         { "email" => "to_bcc@example.com" }
#       ] 
#     }
#   ],
#   "content" => [
#     { "type" => "text/html", "value" => "hoge_body" }
#   ] 
# }

client = SendGrid::API.new(api_key: 'sendgrid_api_key').client
client.mail._('send').post(request_body: mail.to_json)

SendGridのx-message-idについて

運用することを考えると、メールがバウンスされたのかを確認する必要があるかと思います。
SendGridではメール送信後に、ユニークidとしてx-message-idが割り振られます。
詳細は以下の通りになります。
https://support.sendgrid.kke.co.jp/hc/ja/articles/360000222542-送信リクエストの内容とイベントを紐付ける方法を教えてください

SendGridからAPI経由でメール一覧を取得

送信されたメール一覧を取得したり、検索することも可能です。
具体的には以下のメソッドを使って、メール一覧を取得します。

https://github.com/sendgrid/sendgrid-ruby/blob/main/USAGE.md#get-messages

具体的にコードで書くとこのようになります。

client = SendGrid::API.new(api_key: 'sendgrid_api_key').client
query_params_to_filter_from_email = "from_email = 'send_from_email@example.com'"
query_params_to_filter_x-message-id = "x_msg_id LIKE 'hoge-x-message-id%'"

# 送信メールアドレスで絞り込み
client.messages.get(query_params: query_params_to_filter_from_email)

# x-message-idで絞り込み
client.messages.get(query_params: query_params_to_filter_x-message-id)

# レスポンス例
# {
#   :messages => [
#     {
#       :from_email => "",
#       :msg_id => "",
#       :subject => "",
#       :to_email => "",
#       :status => "delivered",
#       ...
#     },
#     ...
#   ]
# }

SendGridからAPI経由でメール詳細を取得

ユニークキーから送信されたメール詳細も確認することが可能になります。
こちらはより詳細なレスポンスになるので、メールが送信されたか調査している場合はこちらを使用するかと思います。
具体的には以下メソッドを使用します。
https://github.com/sendgrid/sendgrid-ruby/blob/main/USAGE.md#get-messagesmsg_id

具体的にコードで書くとこのようになります。

client = SendGrid::API.new(api_key: 'sendgrid_api_key').client
client.messages._("******x-message-id******").get

# レスポンス例
# {
#   :from_email => "",
#   :msg_id => "",
#   :subject => "",
#   :to_email => "",
#   :status => "delivered",
#   ...
# }

RailsのAction::MailerにSendGridを組込方法

以下のようにActiveSupportのモジュールに、delivery_methodを追加します。

# Something initializer
ActiveSupport.on_load :action_mailer do
  ActionMailer::Base.add_delivery_method :sendgrid, DeliverySendgrid
end

delivery_methodへ追加元となるクラスを実装します。

# something extend class
class DeliverySendgrid
  attr_reader :settings

  def initialize(settings)
    @settings = settings
  end

  def deliver!(message_delivery = ActionMailer::MessageDelivery.new)
    # SendGridからAPI経由でメール送信
    # example: client.mail._('send').post(request_body: mail.to_json)
  end
end

SendGrid経由でメール送信するために、Baseクラスを実装します。
(主にはこちらでエラーハンドル用のメソッドを追加で実装するため)

# Base class for SendGrid
class SendgridExampleMailer < ApplicationMailer
  default delivery_mehtod: -> { :sendgrid }
end

Baseクラスを継承して、各実装箇所によって専用のメーラーを実装します。

# Child class for sending email via SendGrid
class HogeMailer < SendgridExampleMailer
  def deliver!
    mail(
      # パラメータ
    )
  end
end

まとめ

基本はAPIでの運用についてまとめていますが、SendGridの管理画面からもメールのバウンス状態を確認できます。
そのため管理画面で事足りる場合は、わざわざバウンス確認の実装する必要はないかと思います。

Discussion