Action Mailerのインターセプタを使ってバウンスメールのチェックを行う

公開日時

Action Mailerにはメールの配信前に実行されるフックが用意されている。

AWS SESを使っている場合はバウンス対応をやっておかないとサービス停止になってしまうため、インターセプタを使ってバウンス登録されたメールアドレスにはメールを送らないようにする。

バウンスメールはBouncedEmailsテーブルに保存されている前提で、initializersに↓を追加する。

# config/initializers/mailer_interceptor.rb

# frozen_string_literal: true

module MailerInterceptors
  class BounceInterceptor
    class << self
      def delivering_email(message)
        if message.to
          message.to = message.to.select { |to| !bounced?(to) }
        end

        if message.cc
          message.cc = message.cc.select { |cc| !bounced?(cc) }
        end

        if message.bcc
          message.bcc = message.bcc.select { |bcc| !bounced?(bcc) }
        end

        if message.to.blank? && message.cc.blank? && message.bcc.blank?
          message.perform_deliveries = false
        end
      end

      private

      def bounced?(email)
        BouncedEmail.where(email: email).exists?
      end
    end
  end
end

ActionMailer::Base.register_interceptor(MailerInterceptors::BounceInterceptor)

今回、1ユーザに対してメールを送るのが基本であるためbounced?メソッドで1件ずつチェックを行っているが、一括メール送信をする場合は処理を見直したほうが良さそう。

参考


Related #ruby

VSCode + PrettierでRubyのコードを自動フォーマットする

@prettier/plugin-rubyを利用

VSCodeでRails環境を整える

ショートカット大事

VSCodeでRubyのコード補完と関数ジャンプができるようにする

ruby拡張とsolargraph拡張を入れる

open-uriでhttpリクエストを送信する際のtimeout設定

モンキーパッチを当てた

docker-composeでRails6環境をrails newしたら途中で止まってしまった

--skip-gitオプションを追加する必要があった

activerecord-importのクエリログを無効化する

一時的にログを無効化して処理が終わったあとに戻すようにした