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

Sidekiqで指定時間待ってから実行する

perform_inを使う

Active Jobで指定時間後にジョブを実行する

setメソッドの引数にwaitを指定する

bot tweetするrubyスクリプト

8時間ほどで申請が通っていた

RailsのログをLogrageに変更する

ログを1行にまとめてくれるので便利

request specでリダイレクトのテストをする

redirect_toが使えた

Extension fieldsを使ってdocker-composeのコンテナ設定を共通化する

Railsコンテナ設定を共通化して、commandだけそれぞれで変えるようにした