Email verification is no secret. All it requires is a little knowledge of the SMTP protocol and your programming language of choice. To prove just how easy it is, I'm going to walk you through the basics using a simple python script.
Warnings and Disclaimers
While this process will get you up and running, you need to be aware of the following risks:
- Do this too much and you will get put on a naughty list (e.g. Spamhaus), especially if you are using a dynamic IP address from your ISP.
- B2C addresses: this does not work very well against the big boys who have their own procedures and spam rules (e.g.hotmail and yahoo).
- Incorrect results: some mail servers will give you incorrect results, for instance catch-all servers, which will accept all incoming email addresses, often forwarding incoming emails to a central mailbox. Yahoo addresses displays this catch-all behavior.
This script on its own is not enterprise grade email verification; you will not be able to process millions of addresses with it.
Email Verification
Syntax
Before we start committing network IO, we should first perform a basic check to see if the email is in fact something that resembles an email address. We can use some simple regex to do this.
import re
addressToVerify ='[email protected]'
match = re.match('^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,4})$', addressToVerify)
if match == None:
print('Bad Syntax')
raise ValueError('Bad Syntax')
DNS
Next we need to get the MX record for the target domain, in order to start the email verification process. Note that you are allowed in the RFCs to have a mail server on your A record, but that's outside of the scope of this article and demo script.
import dns.resolver
records = dns.resolver.query('scottbrady91.com', 'MX')
mxRecord = records[0].exchange
mxRecord = str(mxRecord)
Mailbox
Now that we have all the preflight information we need, we can now find out if the email address exists.
import socket
import smtplib
# Get local server hostname
host = socket.gethostname()
# SMTP lib setup (use debug level for full output)
server = smtplib.SMTP()
server.set_debuglevel(0)
# SMTP Conversation
server.connect(mxRecord)
server.helo(host)
server.mail('[email protected]')
code, message = server.rcpt(str(addressToVerify))
server.quit()
# Assume 250 as Success
if code == 250:
print('Success')
else:
print('Bad')
What we are doing here is the first three commands of an SMTP conversation for sending an email, stopping just before we send any data.
The actual SMTP commands issued are: HELO, MAIL FROM and RCPT TO. It is the response to RCPT TO that we are interested in. If the server sends back a 250, then that means we are good to send an email (the email address exists), otherwise the server will return a different status code (usually a 550), meaning the email address does not exist on that server.
And that's email verification!
GitHub
You can find the full python script on GitHub. This script uses keyboard input for the email address to verify and has a couple of extras in terms of error handling and debugging.
Please note that this script uses Python 3 and the dnspython3 library.
PHP Email Verification Script
There's a similar script available for PHP, which you can also find on GitHub.
You can find more details on the SMTP conversation for verifying email addresses in the article 'Detailed Guide On How To Do Mailbox Pinging'.