DEV Community

Magic.rb
Magic.rb

Posted on

How I stop users with a disposable email from creating an account on appstate.co

Simple Guide: Building an Email Checker in Rails

Let's create a tool that checks if an email is from a disposable email service. This can help keep your user list clean and reduce spam.

What We're Building

We'll make a service that:

  1. Checks an email address
  2. Tells us if it's from a disposable email service

Steps to Build It

Step 1: Set Up Your Files

  1. Make a new folder for our service:
   mkdir -p app/services/utils
Enter fullscreen mode Exit fullscreen mode
  1. Create a new file for our code:
   touch app/services/utils/email_checker_service.rb
Enter fullscreen mode Exit fullscreen mode

Step 2: Write the Basic Code

Open email_checker_service.rb and add this code:

module Utils
  class EmailCheckerService < ApplicationService
    DISPOSABLE_DOMAINS_URL = 'https://raw.githubusercontent.com/disposable/disposable-email-domains/master/domains.json'

    def initialize(email)
      @email = email
    end

    def call
      domain = get_domain(@email)
      disposable_domains = get_disposable_domains
      disposable_domains.include?(domain)
    end

    private

    def get_domain(email)
      email.split('@').last.downcase
    end

    def get_disposable_domains
      Rails.cache.fetch('disposable_email_domains', expires_in: 1.day) do
        response = HTTParty.get(DISPOSABLE_DOMAINS_URL, timeout: 10)
        JSON.parse(response.body) if response.success?
      end
    rescue StandardError => e
      Rails.logger.error "Error getting disposable domains: #{e.message}"
      []
    end
  end
end
Enter fullscreen mode Exit fullscreen mode

Step 3: Understand the Code

Let's break it down:

  • initialize(email): This starts our service with an email to check.
  • call: This is the main method that does the checking.
  • get_domain: This gets the domain part of the email (the part after @).
  • get_disposable_domains: This gets a list of known disposable email domains.

Step 4: Add HTTParty

We use HTTParty to get the list of disposable domains. Add it to your Gemfile:

gem 'httparty'
Enter fullscreen mode Exit fullscreen mode

Then run:

bundle install
Enter fullscreen mode Exit fullscreen mode

Step 5: Create a Base Service Class

Create a new file app/services/application_service.rb:

class ApplicationService
  def self.call(*args)
    new(*args).call
  end
end
Enter fullscreen mode Exit fullscreen mode

This lets us use our service more easily.

Step 6: Use the Service

Here's how to use it in your app:

class SignupsController < ApplicationController
  def create
    email = params[:email]
    if Utils::EmailCheckerService.call(email)
      render json: { error: 'Please use a permanent email address' }, status: :unprocessable_entity
    else
      # Sign up the user
    end
  end
end
Enter fullscreen mode Exit fullscreen mode

Step 7: Test It

Let's add a simple test. Create spec/services/utils/email_checker_service_spec.rb:

require 'rails_helper'

RSpec.describe Utils::EmailCheckerService do
  it 'detects disposable emails' do
    allow_any_instance_of(described_class).to receive(:get_disposable_domains).and_return(['disposable.com'])
    expect(described_class.call('test@disposable.com')).to be true
    expect(described_class.call('test@gmail.com')).to be false
  end
end
Enter fullscreen mode Exit fullscreen mode

Run the test:

rspec spec/services/utils/email_checker_service_spec.rb
Enter fullscreen mode Exit fullscreen mode

What We Built

We made a service that:

  1. Takes an email address
  2. Checks if it's from a list of known disposable email services
  3. Tells us if it's disposable or not

This helps keep your user list clean and can reduce fake signups.

Next Steps

To make it even better, you could:

  1. Update the list of disposable domains regularly
  2. Add more checks, like making sure the email format is correct
  3. Allow some disposable emails if needed

That's it! You now have a simple way to check for disposable emails in your Rails app.

Top comments (0)