The biggest risk: having too many fake emails in your mailing list
Service providers check your bounce rate. If they find that you are sending too many emails to the wrong addresses, they may blacklist you. This can have even greater implications than spam filtering, as many of your recipients' mail servers could reject every single mail you send. Once your servers are blacklisted, it can be complicated to remove the blacklisting.
You can verify your server's blacklisting status on a service like Debouncer.
How to validate fields in Ruby on Rails
In most cases, the fields of a form are injected into an ActiveRecord model, which performs the validation. The ActiveRecord::Validations API allows to easily define rules to validate various aspects of these fields: format, inclusion, length, uniqueness, and many others.
Let's take as an example a contact form allowing your visitors to send a message to your staff. Such a form would contain Last and First Name, Email Address, and Message fields. Let's write a model and its validation mechanism to check the presence and length of each field and the email address format. Here is the code:
ActiveRecord calls all validation methods defined in the model during the saving process. If they are successful, then the model is saved in the database. But if there is at least one error, the model won't be saved in the database. You can then check the content of its errors field to obtain details about the validation errors.
Here are the details of the methods used in the code above:
- validates_presence_of: check that the fields contain something. Note that if the value for this field is a simple space, the validation will succeed.
- validates_length_of: checks the length of the value. The acceptable length of a field depends on the application's needs and the database's field type.
- validates_format_of: checks that the format of the field value matches the regular expression provided in the parameter
While the first two validation methods are easy to understand, the third requires a little more attention.
How to use the validates_format_of method
The first step of email validation consists of checking the format of the email address. To do this, it is sufficient to use the validates_format_of method mentioned earlier in this document along with an efficient regular expression.
The standard Ruby library provides the URI::MailTo class, which declares the regular expression EMAIL_REGEXP. This is suitable in most cases.
Here is how to use it in our model:
How to validate an email address in Ruby
As a developer, you are looking to implement the best way to validate an email address format. To do so, you first need to understand precisely what format is allowed by Internet Standards. Section 3,2,4 of RFC 2822 specifies that the local string (the part of the email address that comes before the @) can contain the following characters: ! $ & * - = ` ^ | ~ # % ' + / ? _ { } You can also use something like a regular expression (regex) to verify the email structure is correct.
According to this, validation of an email address format requires quite a complex mechanism. Luckily the URI::MailTo class, which is part of the Ruby Standard Library, contains the URI::MailTo::EMAIL_REGEXP constant, which can be used for email format validation, so you don't have to create your own.
However, according to the next section of RFC 2822, an email address can contain any characters as long as quotes escape them. As an example, this is a correct email address:
And the URI::MailTo::EMAIL_REGEXP constant would reject it.
At this point, you could conclude that URI::MailTo::EMAIL_REGEXP is able to validate 99% of all emails submitted to your forms, which may be good enough.
But an address like sefgqpouinqlzoiyhqjhzgf@gmail.com has a correct syntax and would be validated by any regular expression you may implement. Chances are, though, that the mailbox does not exist, and every email sent to this address would bounce back.
Check that an email address exists in Ruby on Rails.
The method for checking the existence of an email address is to extract the server FQDN (the part after the @ sign); to query the corresponding DNS servers to confirm that the server exists; to query the MX records from the DNS entries. A well-made verification method will also match the server name against a list of known disposable email services to determine if the visitor is using a disposable email address.
Setting up such a complex verification method is beyond this document's scope. But fortunately, there is a solution, easy to implement, which we will discuss in the next chapter.
APIs: The real solution to validating email addresses
An efficient email checker would not only verify the address format but also verify if the email is hosted by a free or paid service, if the domain correctly contains an MX record and if it points to a valid SMTP server, if the email domain is linked to a disposable email service, and more.
Abstract is a fast and reliable API provider that offers multiple services, including email validation. Once subscribed, you get free access to the API along with your private API key.
Abstract Email Validation API is accessible through a GET request and takes 2 arguments. Here is its format:
Using Net::HTTP, here is how to make the request and retrieve the response:
The response is in JSON format and contains multiple parameters:
- auto_correct: contains a suggestion of the correct email if a typo error has been detected
- is_valid_format: check the email format and indicates if it is correct
- is_free_email: indicates if the email is hosted by a free service (Gmail, Outlook, ...)
- is_disposable_email: indicates if the email address is provided by a disposable email provider, which is a service allowing people to receive email without any authentication nor identification
- is_role_email: indicates if the email recipient seems to be a team or a department instead of a person
- is_catchall_email: indicates if the email lands in the catchall inbox of the SMTP server
- is_mx_found (only available on paid plans): indicates if the domain provides one or more MX records and if they point to a server
- is_smtp_valid (only available on paid plans): check the SMTP domain and indicate if the verification was successful
- quality_score: a number scaling from 0.01 to 0.99, indicating the level of trust of the email address submitted
Here is an example of a response: