こんにちは!kossyです!
さて、今回はRailsでsendgridをメール配信サービスとして使用していた時に、
message_idを取得する方法についてブログに残してみたいと思います。
環境
Ruby 2.5.1
Rails 5.2.3
MacOS Mojave
なお、sendgridの設定周りについての説明は割愛します。
configは下記の記事が参考になるかと思います。
https://sendgrid.kke.co.jp/docs/Integrate/Frameworks/rubyonrails.html
ActionMailer::DeliveryJobではなくNet::SMTP::Responseを返り値にする
通常、RailsでActionMailerを使ってメールを送信するときは、
deliver_nowかdeliver_laterを使うと思いますが、
https://edgeapi.rubyonrails.org/classes/ActionMailer/MessageDelivery.html
上記2つのメソッドでメールを送信した場合、返り値がActionMailer::DeliveryJobになります。
これだと、sendgridのmessage_idを受け取ることができないので、
smtp_configと実行するメソッドを変更する必要があります。
まずは config/environment/各環境のenvファイル のsmtpのセッティングを変更します。
config.action_mailer.smtp_settings = { user_name: ENV['sendgrid_user_name'], password: ENV['sendgrid_password'], domain: 'hogehoge.com', address: 'smtp.sendgrid.net', port: 587, authentication: :plain, enable_starttls_auto: true, return_response: true # 追加 }
return_responseをtrueにすると、サーバーからのresponseをそのまま返すようになります。
参考: http://aligach.net/diary/20180725.html
mail gem内でreturn_responseの値を見て分岐しているようでした。
そして、deliver_later(またはdeliver_now)ではなく、deliver_now!を使うようにします。
すると、
response = UserMailer.notify_private_announcement(user).deliver_now! response.class => Net::SMTP::Response
ActionMailer::DeliveryJobではなくNet::SMTP::Responseを返り値にすることができます。
Net::SMTP::Responseインスタンスはattrとして、
response
=> #<Net::SMTP::Response:0x005652f6301890 @status="250", @string="250 Ok: queued as 1dMBeSp6Rj-Uh5TdzJKgmq\n">
statusとstringを持っています。
内、sendgridのmessage_idは、1dMBeSp6Rj-Uh5TdzJKgmq の部分になります。
この文字列を取得するには、
# この書き方なんとかしたい、、、 response.string[18..39] => "1dMBeSp6Rj-Uh5TdzJKgmq"
とすることで取得できます。
このmessage_idを取得し、sendgridのEventWebhookのsg_message_idと前方一致させることで、
メールの開封状況を取得することもできるようになります。
EventWebhookについては、
https://sendgrid.kke.co.jp/docs/API_Reference/Webhooks/event.html
https://sendgrid.kke.co.jp/docs/Tutorials/C_Manage_Events/using_event_webhook.html
が参考になるかと思います。