0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

メールサーバーのレピュテーションを改善するためのライブラリを作ってみた

Posted at

はじめに

メール送信機能を持つアプリケーションを開発する際、不正なメールアドレスや存在しないドメインへの送信を防ぐことは重要です。
特に、存在しないドメインへの送信を繰り返すと、メールサーバーの評判(レピュテーション)が低下し、正常なメールも迷惑メールフォルダに入る可能性があり、メールの到達率が悪化する可能性があります。

本記事では、メールアドレスの形式検証とドメイン存在確認を一括で行える email_domain_checker gemを作ってみたので紹介します。
このgemを使用することで、アプリケーションでメールアドレスを検証する際に、ドメインの存在を確認し、メールサーバーのレピュテーション向上を目指します。

email_domain_checkerとは

email_domain_checker は、Rubyでメールアドレスの形式検証とドメイン存在確認を統合的に行うライブラリです。主な特徴は以下の通りです:

  • メールアドレス形式の検証email_address gemを使用した堅牢な形式チェック
  • ドメイン存在確認:MXレコードやAレコードの存在確認によるドメインチェック
  • DNSタイムアウト制御:設定可能なタイムアウトでレスポンス性能を確保
  • メールアドレス正規化:大文字小文字の統一やIDN(国際化ドメイン名)の処理
  • ActiveModel/ActiveRecord統合:Railsアプリケーションでの簡単な統合

なぜこのgemが必要か

メールサーバーの評判低下を防ぐ

存在しないドメインへのメール送信を繰り返すと、以下のような問題が発生します:

  1. メールサーバーの評判低下:ISPがメールサーバーを低評価化し、正常なメールも迷惑メールフォルダに入る
  2. リソースの無駄:存在しないドメインへの送信試行がリソースを消費
  3. ユーザー体験の低下:メールが届かないことによるユーザーへの影響

従来の検証方法の課題

一般的なメールアドレス検証では、形式チェックのみが行われることが多いです:

# 形式は正しいが、ドメインが存在しない
"user@nonexistent-domain-12345.com"  # 形式は有効だが、ドメインは存在しない

このようなメールアドレスでも形式検証は通ってしまいますが、実際には送信できません。

email_domain_checker は、形式検証に加えてドメインの存在確認も行うことで、この問題を解決します。

インストール方法

Gemfileへの追加

gem 'email_domain_checker'

インストール

bundle install

または、直接インストールする場合:

gem install email_domain_checker

基本的な使い方

モジュールレベルの便利メソッド

最もシンプルな使い方は、モジュールレベルの便利メソッドを使用することです:

require 'email_domain_checker'

# クイック検証(ドメイン検証なし)
EmailDomainChecker.valid?("user@example.com", validate_domain: false)
# => true

# 形式検証のみ
EmailDomainChecker.format_valid?("user@example.com")
# => true

# ドメイン検証のみ(MXレコードチェック付き)
EmailDomainChecker.domain_valid?("user@example.com", check_mx: true)
# => true/false

# メールアドレスの正規化
EmailDomainChecker.normalize("User@Example.COM")
# => "user@example.com"

# グローバル設定
EmailDomainChecker.configure(timeout: 10, check_mx: true)

Checkerクラスを使用した詳細な検証

より詳細な制御が必要な場合は、Checkerクラスを使用します:

require 'email_domain_checker'

# 基本的な検証
checker = EmailDomainChecker::Checker.new("user@example.com")
if checker.valid?
  puts "有効なメールアドレスで、ドメインも存在します"
end

# 形式検証のみ
checker = EmailDomainChecker::Checker.new("user@example.com", validate_domain: false)
checker.format_valid?  # => true

# MXレコードチェック付きのドメイン検証
checker = EmailDomainChecker::Checker.new("user@example.com", check_mx: true)
checker.domain_valid?  # => MXレコードが存在する場合true

# 正規化されたメールアドレスを取得
checker = EmailDomainChecker::Checker.new("User@Example.COM")
checker.normalized_email  # => "user@example.com"

# 正規化されたメールアドレスを取得(Gmailの+タグなども処理)
checker = EmailDomainChecker::Checker.new("user.name+tag@gmail.com")
checker.canonical_email  # => "username@gmail.com"

# プライバシー保護のための匿名化
checker = EmailDomainChecker::Checker.new("user@example.com")
checker.redacted_email  # => "{hash}@example.com"

ActiveModel/ActiveRecord統合

Railsアプリケーションでは、ActiveModelのバリデーターとして使用できます:

基本的な使用例

class User < ActiveRecord::Base
  validates :email, domain_check: { check_mx: true, timeout: 3 }, normalize: true
end

このバリデーターは以下の機能を提供します:

  • ドメイン検証:MXレコードの存在確認
  • 自動正規化normalize: trueでメールアドレスを自動的に正規化
  • エラーメッセージ:形式エラーとドメインエラーを区別

バリデーションオプション

基本的な使用例

# ドメイン検証付き(MXレコードチェック)
class User < ActiveRecord::Base
  validates :email, domain_check: { check_mx: true, timeout: 3 }
end

形式検証のみ(ドメイン検証をスキップ)

class User < ActiveRecord::Base
  validates :email, domain_check: { validate_domain: false }
end

自動正規化付き

class User < ActiveRecord::Base
  validates :email, domain_check: { check_mx: true }, normalize: true
end

この場合、User@Example.COM は自動的に user@example.com に正規化されます。

カスタムエラーメッセージ

class User < ActiveRecord::Base
  validates :email, 
            domain_check: { check_mx: true }, 
            message: "有効なメールアドレスを入力してください"
end

利用可能なオプション

domain_check オプションで指定できる設定:

  • check_mx: MXレコードをチェックするか(デフォルト: true
  • check_a: Aレコードをチェックするか(デフォルト: false
  • timeout: DNSクエリのタイムアウト(秒)(デフォルト: 5
  • validate_format: メールアドレス形式を検証するか(デフォルト: true
  • validate_domain: ドメインを検証するか(デフォルト: true

その他のオプション:

  • normalize: 検証前にメールアドレスを正規化するか(デフォルト: false
  • message: カスタムエラーメッセージ

詳細な機能

メールアドレス正規化

メールアドレスは大文字小文字を統一し、IDN(国際化ドメイン名)を処理します:

EmailDomainChecker.normalize("User@Example.COM")
# => "user@example.com"

EmailDomainChecker.normalize("  user@example.com  ")
# => "user@example.com"

ドメイン検証

MXレコードまたはAレコードの存在を確認します:

# MXレコードのみチェック(デフォルト)
checker = EmailDomainChecker::Checker.new("user@example.com", check_mx: true)
checker.domain_valid?

# Aレコードもチェック
checker = EmailDomainChecker::Checker.new("user@example.com", check_mx: true, check_a: true)
checker.domain_valid?

DNSタイムアウト制御

DNSクエリのタイムアウトを設定できます:

# タイムアウトを3秒に設定
checker = EmailDomainChecker::Checker.new("user@example.com", timeout: 3)
checker.domain_valid?

グローバル設定

アプリケーション全体のデフォルト設定を変更できます:

EmailDomainChecker.configure(
  timeout: 10,
  check_mx: true,
  check_a: false,
  validate_format: true,
  validate_domain: true
)

実装のポイント

DNS解決の実装

このgemは、Ruby標準ライブラリのResolvを使用してDNSクエリを実行します:

# lib/email_domain_checker/dns_resolver.rb より
def has_mx_record?(domain)
  check_dns_record(domain, Resolv::DNS::Resource::IN::MX)
end

def has_a_record?(domain)
  check_dns_record(domain, Resolv::DNS::Resource::IN::A)
end

タイムアウトも設定可能で、デフォルトは5秒です。

メールアドレス形式検証

email_address gemを使用して、RFC準拠のメールアドレス形式検証を行います。

ActiveModel統合

ActiveModelが利用可能な場合、DomainCheckValidatorが自動的に読み込まれます。Ruby 3.4+での互換性も考慮されています。

まとめ

email_domain_checker gemは、メールアドレスの形式検証とドメイン存在確認を統合的に行うライブラリです。主な利点は以下の通りです:

  1. メールサーバーの評判保護:存在しないドメインへの送信を防ぐ
  2. 簡単な統合:Railsアプリケーションでの簡単な統合
  3. 柔軟な設定:用途に応じて検証レベルを調整可能
  4. パフォーマンス:DNSタイムアウト制御によるレスポンス性能の確保

メール送信機能を持つアプリケーションを開発する際は、このgemを活用して、メールサーバーの評判を守り、ユーザー体験を向上させましょう。

参考リンク

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?