mastodonの登録メールアドレスをapp.usercheck.comを使って使い捨てかどうか調べる

Last Update: 2026/08/27

最近、使い捨てドメインをどんどん出しながら登録してくるスパムアカウントが増えてきました。 app.usercheck.comを使うと、使い捨てドメインかどうかを調べることができるので、これを使って、使い捨てドメインの登録をブロックすることができます。

app.usercheck.comに登録してAPIキーをもらう

https://app.usercheck.com/ でアカウントを作って、APIキーをもらいます。

mastodonにpatchを当てて、新規登録に対してメールアドレスのチェックを走らせる

以下のバッチを当てて、app/validators/usercheck_email_validator.rbを新規作成します。 app/models/user.rbに、新規追加したカスタムのアドレスチェックを追記します。

usercheck_email_validator.patch

diff --git a/app/models/user.rb b/app/models/user.rb
index 1bddd36dc5..dafe38a899 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -90,6 +90,8 @@ class User < ApplicationRecord
   validates :email, presence: true, email_address: true, length: { maximum: 320 }
   validates :email, email_mx: { attempt_ip: :sign_up_ip }, if: :validate_email_dns?
 
+  validates :email, usercheck_email: true, if: :email_changed?
+
   validates_with UserEmailValidator, if: -> { ENV['EMAIL_DOMAIN_LISTS_APPLY_AFTER_CONFIRMATION'] == 'true' || !confirmed? }
   validates :agreement, acceptance: { allow_nil: false, accept: [true, 'true', '1'] }, on: :create
 
diff --git a/app/validators/usercheck_email_validator.rb b/app/validators/usercheck_email_validator.rb
new file mode 100644
index 0000000000..002cfb110a
--- /dev/null
+++ b/app/validators/usercheck_email_validator.rb
@@ -0,0 +1,34 @@
+require 'net/http'
+require 'uri'
+require 'json'
+
+class UsercheckEmailValidator < ActiveModel::EachValidator
+  def validate_each(record, attribute, value)
+    return if value.blank?
+
+    api_key = ENV['USERCHECK_API_KEY']
+    return unless api_key.present?
+
+    uri = URI("https://api.usercheck.com/email/#{URI.encode_www_form_component(value)}")
+    request = Net::HTTP::Get.new(uri)
+    request['Authorization'] = "Bearer #{api_key}"
+
+    begin
+      response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == 'https', read_timeout: 5) do |http|
+        http.request(request)
+      end
+
+      if response.is_a?(Net::HTTPSuccess)
+        data = JSON.parse(response.body)
+
+        if  data['status'] == 200 && data['disposable'] == true
+          record.errors.add(attribute, :usercheck_invalid)
+        end
+      else
+        Rails.logger.warn "[Usercheck] API Error: #{response.code} for email: #{value}"
+      end
+    rescue StandardError => e
+      Rails.logger.error "[Usercheck] Network Exception: #{e.message}"
+    end
+  end
+end
diff --git a/config/locales/de.custom.yml b/config/locales/de.custom.yml
new file mode 100644
index 0000000000..873ea043a9
--- /dev/null
+++ b/config/locales/de.custom.yml
@@ -0,0 +1,8 @@
+de:
+  activerecord:
+    errors:
+      models:
+        user:
+          attributes:
+            email:
+              usercheck_invalid: "Einweg-E-Mail-Adressen sind für die Registrierung nicht erlaubt."
diff --git a/config/locales/en.custom.yml b/config/locales/en.custom.yml
new file mode 100644
index 0000000000..5f316cd363
--- /dev/null
+++ b/config/locales/en.custom.yml
@@ -0,0 +1,8 @@
+en:
+  activerecord:
+    errors:
+      models:
+        user:
+          attributes:
+            email:
+              usercheck_invalid: "Disposable email addresses are not allowed."
diff --git a/config/locales/es.custom.yml b/config/locales/es.custom.yml
new file mode 100644
index 0000000000..ca50f907e0
--- /dev/null
+++ b/config/locales/es.custom.yml
@@ -0,0 +1,8 @@
+es:
+  activerecord:
+    errors:
+      models:
+        user:
+          attributes:
+            email:
+              usercheck_invalid: "No se permiten direcciones de correo electrónico desechables."
diff --git a/config/locales/fr.custom.yml b/config/locales/fr.custom.yml
new file mode 100644
index 0000000000..f039773b45
--- /dev/null
+++ b/config/locales/fr.custom.yml
@@ -0,0 +1,8 @@
+fr:
+  activerecord:
+    errors:
+      models:
+        user:
+          attributes:
+            email:
+              usercheck_invalid: "Les adresses e-mail jetables ne sont pas autorisées."
diff --git a/config/locales/ja.custom.yml b/config/locales/ja.custom.yml
new file mode 100644
index 0000000000..d04b3808e0
--- /dev/null
+++ b/config/locales/ja.custom.yml
@@ -0,0 +1,8 @@
+ja:
+  activerecord:
+    errors:
+      models:
+        user:
+          attributes:
+            email:
+              usercheck_invalid: "使い捨てメールアドレスでは登録できません"
diff --git a/config/locales/ko.custom.yml b/config/locales/ko.custom.yml
new file mode 100644
index 0000000000..7aec4e3379
--- /dev/null
+++ b/config/locales/ko.custom.yml
@@ -0,0 +1,8 @@
+ko:
+  activerecord:
+    errors:
+      models:
+        user:
+          attributes:
+            email:
+              usercheck_invalid: "일회용 이메일 주소로는 가입할 수 없습니다."
diff --git a/config/locales/pt-BR.custom.yml b/config/locales/pt-BR.custom.yml
new file mode 100644
index 0000000000..eedc056ab6
--- /dev/null
+++ b/config/locales/pt-BR.custom.yml
@@ -0,0 +1,8 @@
+pt-BR:
+  activerecord:
+    errors:
+      models:
+        user:
+          attributes:
+            email:
+              usercheck_invalid: "Endereços de e-mail descartáveis não são permitidos."
diff --git a/config/locales/ru.custom.yml b/config/locales/ru.custom.yml
new file mode 100644
index 0000000000..5e23c2ee6d
--- /dev/null
+++ b/config/locales/ru.custom.yml
@@ -0,0 +1,8 @@
+ru:
+  activerecord:
+    errors:
+      models:
+        user:
+          attributes:
+            email:
+              usercheck_invalid: "Регистрация с использованием одноразовой электронной почты запрещена."
diff --git a/config/locales/zh-CN.custom.yml b/config/locales/zh-CN.custom.yml
new file mode 100644
index 0000000000..aaf441a3e9
--- /dev/null
+++ b/config/locales/zh-CN.custom.yml
@@ -0,0 +1,8 @@
+zh-CN:
+  activerecord:
+    errors:
+      models:
+        user:
+          attributes:
+            email:
+              usercheck_invalid: "不能使用一次性电子邮件地址注册"
diff --git a/config/locales/zh-TW.custom.yml b/config/locales/zh-TW.custom.yml
new file mode 100644
index 0000000000..10d6949c43
--- /dev/null
+++ b/config/locales/zh-TW.custom.yml
@@ -0,0 +1,8 @@
+zh-TW:
+  activerecord:
+    errors:
+      models:
+        user:
+          attributes:
+            email:
+              usercheck_invalid: "無法使用拋棄式電子郵件地址註冊"

mastodonを再起動します

patchをあてたら、mastodonを再起動して反映させます。