ActionMailerで送信依頼の結果を取得する

ActionMailer→Mail gemには実はサーバのresponseをそのまま返すオプションがある

ドキュメントには全然情報がないんだけど、ここ。

Mail gem

 class SMTPConnection
   # Send the message via SMTP.
   # The from and to attributes are optional. If not set, they are retrieve from the Message.
   def deliver!(mail)
     envelope = Mail::SmtpEnvelope.new(mail)
     response = smtp.sendmail(dot_stuff(envelope.message), envelope.from, envelope.to)
     settings[:return_response] ? response : self
   end

まずdeliver!メソッド、そしてreturn_response: true

deliver を deliver! にすると

  • ログにメールの内容は出力されない

これだけで log に sensitive な情報が残ってしまう問題を避けることができる。

そのうえで

この辺を参考にすると、

  • Configuration で return_reseponse: true にするとサーバの返事を取得できる
  • その際、エラーも生で扱うことになるので raise_delivery_error などの Rails の機能の恩恵には預かれなくなる

例えば送信時のサーバの返事が取得できると何が嬉しいのか

エラーかエラーでないかだけを気にしているのなら返事は wrap されている方がよい。そうでないと status を見てエラーかどうかを見て、エラーでない場合は返事の構造がこうなっているので、ここにある文字列を取得して…という部分を生々しく作っていく必要が出てくる。

今回なぜこれを考えているかというと、

SendGrid の送信したメールの内容とその配信記録、状況の追跡を容易にするため

まず、SendGrid から配信されるメールにおいては以下の二つの message id が存在している。

  • ユーザーのメール上で確認できる伝統的な message-id
  • SendGrid での実際の処理に紐づく sg-message-id

そして、送信時のサーバからの response に、今処理を開始したメールの sg-message-id が入っているので、これをもとに処理の状況を追跡することが可能となる。

ということで、目的によって ActionMailer の return_response:true と deliver! を使うことが大事になってくる。

SendGrid Webhook APIとの突き合わせ

SendGrid の sg-message-id は

  • SMTP API であっても Web API であっても送信時の response に含まれている
  • Event Wehbook API の中にも含まれている

したがって、

  • メール送信時に sg-message-id とともにメールを記録しておく

と、

  • Event Webhook API からの情報をこの記録と突き合わせる

ことが可能になる。

簡単に言うと、「送信したメールが今どうなっているのかを確認できるシステムを作れる」

ということである。

参考

More