# Grey verifier: Smart SMTP Email Verifier (python)
Grey Verifier makes correct SMTP conversation to verify email address or list of addresses and properly handles 4xx SMTP errors (such as greylisting).
This tool could be slow - it's not working parallel.
verifier prints successfully verified email addresses to stdout, and failed addresses (and reason) to stderr.
## Why yet another mail list verifier?
Because many other verifiers are working incorrectly, e.g. They use incorrect `HELO` host, do not issue `MAIL FROM` command before `RCPT TO` and on some mailserver this makes incorrect result (e.g. RCPT TO fails because of missed MAIL FROM, but not because something wrong with recipient).
SMTP Email verifier:
1. Connects to main MX for domain (with lowest MX priority)
2. Makes correct (configurable) SMTP conversation with `HELO` / `MAIL FROM` / `RCPT TO`
3. For each failed email prints (easy to parse with `cut -f 1 -d:` )
4. Supports Greylisting! If verification returns a temporary error, it will retry every `--retry` seconds for up to `--max-retry` seconds.
5. Supports IPv6 (and IPv4-only, sure). Yes, some recipients in your big maillist has main MX on IPv6 address.
## Install
~~~
pipx install grey-verifier
~~~
## Usage
### Verify one email address
~~~
$ grey-verifier yaroslaff@gmail.com
yaroslaff@gmail.com
$ grey-verifier yaroslaff-NoSuchEmail@gmail.com
yaroslaff-NoSuchEmail@gmail.com: RCPT TO error: 550 b"5.1.1 The email account that you tried to reach does not exist. Please try\n5.1.1 double-checking the recipient's email address for typos or\n5.1.1 unnecessary spaces. For more information, go to\n5.1.1 https://support.google.com/mail/?p=NoSuchUser 38308e7fff4ca-2ef05d163c2si289891fa.270 - gsmtp"
~~~
Optionally provide options `--helo HOSTNAME` and `--from ADDRESS`. Some mail servers will give false negative results if will not like HELO or FROM address.
### Verify list
~~~
# See verification status for each email address
$ grey-verifier -f /tmp/test.txt
aaa@example.com: DNS error for example.com
bbb@example.com: DNS error for example.com
yaroslaff@gmail.com
# Get only verified emails
$ grey-verifier -f /tmp/test.txt 2> /dev/null
yaroslaff@gmail.com
# Or with redirections and custom HELO and MAIL FROM address
$ grey-verifier -f /tmp/test.txt --helo localhost --from noreply@example.com > /tmp/test-ok.txt 2> /tmp/test-fail.txt
# now get all failed addresses:
$cut -f 1 -d: < /tmp/test-fail.txt
~~~
### Greylisting
To pass greylisting protection, use `--max-retry N` option to set retry limit (in seconds). If `--max-retry` is set, verifier will retry every `--retry N` seconds (default: 60), for up to `--max-retry` limit.
> **Note**: Default value for `--max-retry` is 0 (retries disabled). Set it to something like `--max-retry 600` (or even more) to properly handle greylisting.
### Verbose
If you want to see how exactly verification happens for email address, use `-v` / `--verbose` to see internal debug messages and `-s` / `--smtp-verbose` to see SMTP conversation. Example:
~~~
$ grey-verifier -sv yaroslaff@gmail.com
# Verifying yaroslaff@gmail.com
connect: to ('gmail-smtp-in.l.google.com.', 25) None
reply: b'220 mx.google.com ESMTP 2adb3069b0e04-52ed252cfc0si2901698e87.159 - gsmtp\r\n'
reply: retcode (220); Msg: b'mx.google.com ESMTP 2adb3069b0e04-52ed252cfc0si2901698e87.159 - gsmtp'
connect: b'mx.google.com ESMTP 2adb3069b0e04-52ed252cfc0si2901698e87.159 - gsmtp'
send: 'helo mir.localdomain\r\n'
reply: b'250 mx.google.com at your service\r\n'
reply: retcode (250); Msg: b'mx.google.com at your service'
send: 'mail FROM:<noreply@example.com>\r\n'
reply: b'250 2.1.0 OK 2adb3069b0e04-52ed252cfc0si2901698e87.159 - gsmtp\r\n'
reply: retcode (250); Msg: b'2.1.0 OK 2adb3069b0e04-52ed252cfc0si2901698e87.159 - gsmtp'
send: 'rcpt TO:<yaroslaff@gmail.com>\r\n'
reply: b'250 2.1.5 OK 2adb3069b0e04-52ed252cfc0si2901698e87.159 - gsmtp\r\n'
reply: retcode (250); Msg: b'2.1.5 OK 2adb3069b0e04-52ed252cfc0si2901698e87.159 - gsmtp'
send: 'quit\r\n'
reply: b'221 2.0.0 closing connection 2adb3069b0e04-52ed252cfc0si2901698e87.159 - gsmtp\r\n'
reply: retcode (221); Msg: b'2.0.0 closing connection 2adb3069b0e04-52ed252cfc0si2901698e87.159 - gsmtp'
yaroslaff@gmail.com
~~~
### Command-line parameters
~~~
usage: grey-verifier [-h] [--file FILE] [-4] [--dns] [--from EMAIL] [--helo HELO] [--timeout N] [--retry N] [--max-retry N] [--verbose] [--smtp-verbose] [email]
grey-verifier Email address verifier (0.1.6) which knows about SMTP, Greylisting and IPv6
options:
-h, --help show this help message and exit
Main Options:
email Email address to verify
--file FILE, -f FILE email list
Verification options:
-4 Check only IPv4 MXes, ignore IPv6 ones
--dns Simplified DNS-only domain check, without connecting to mailserver and checking recipient address
--from EMAIL email for MAIL FROM
--helo HELO HELO host
--timeout N Timeout for SMTP operations
Options for retries (Greylisting):
--retry N Delay (in seconds) if get temporary 4xx error (greylisting) for each retry
--max-retry N Do not retry for more then N seconds (use 180+, maybe 600).
Verbosity:
--verbose, -v Verbosity for verifier logic
--smtp-verbose, -s Verbosity for SMTP conversation
~~~
Raw data
{
"_id": null,
"home_page": null,
"name": "grey_verifier",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.8",
"maintainer_email": null,
"keywords": "MAIL FROM, RCPT TO, SMTP, bulk, e-mail, email, grey, greylist, greylisting, mail, mailfrom, validate, verifier",
"author": null,
"author_email": "Yaroslav Polyakov <yaroslaff@gmail.com>",
"download_url": "https://files.pythonhosted.org/packages/ed/02/c0830b9c6f3340f74bd22393763d1edb4166a2608063a4cab64fc21de041/grey_verifier-0.1.6.tar.gz",
"platform": null,
"description": "# Grey verifier: Smart SMTP Email Verifier (python)\nGrey Verifier makes correct SMTP conversation to verify email address or list of addresses and properly handles 4xx SMTP errors (such as greylisting).\n\nThis tool could be slow - it's not working parallel.\n\nverifier prints successfully verified email addresses to stdout, and failed addresses (and reason) to stderr.\n\n## Why yet another mail list verifier?\nBecause many other verifiers are working incorrectly, e.g. They use incorrect `HELO` host, do not issue `MAIL FROM` command before `RCPT TO` and on some mailserver this makes incorrect result (e.g. RCPT TO fails because of missed MAIL FROM, but not because something wrong with recipient).\n\nSMTP Email verifier:\n1. Connects to main MX for domain (with lowest MX priority)\n2. Makes correct (configurable) SMTP conversation with `HELO` / `MAIL FROM` / `RCPT TO`\n3. For each failed email prints (easy to parse with `cut -f 1 -d:` )\n4. Supports Greylisting! If verification returns a temporary error, it will retry every `--retry` seconds for up to `--max-retry` seconds.\n5. Supports IPv6 (and IPv4-only, sure). Yes, some recipients in your big maillist has main MX on IPv6 address.\n\n## Install\n~~~\npipx install grey-verifier\n~~~\n\n## Usage\n### Verify one email address\n~~~\n$ grey-verifier yaroslaff@gmail.com\nyaroslaff@gmail.com\n\n$ grey-verifier yaroslaff-NoSuchEmail@gmail.com\nyaroslaff-NoSuchEmail@gmail.com: RCPT TO error: 550 b\"5.1.1 The email account that you tried to reach does not exist. Please try\\n5.1.1 double-checking the recipient's email address for typos or\\n5.1.1 unnecessary spaces. For more information, go to\\n5.1.1 https://support.google.com/mail/?p=NoSuchUser 38308e7fff4ca-2ef05d163c2si289891fa.270 - gsmtp\"\n~~~\n\nOptionally provide options `--helo HOSTNAME` and `--from ADDRESS`. Some mail servers will give false negative results if will not like HELO or FROM address.\n\n\n### Verify list\n~~~\n# See verification status for each email address\n$ grey-verifier -f /tmp/test.txt \naaa@example.com: DNS error for example.com\nbbb@example.com: DNS error for example.com\nyaroslaff@gmail.com\n\n# Get only verified emails\n$ grey-verifier -f /tmp/test.txt 2> /dev/null \nyaroslaff@gmail.com\n\n# Or with redirections and custom HELO and MAIL FROM address\n$ grey-verifier -f /tmp/test.txt --helo localhost --from noreply@example.com > /tmp/test-ok.txt 2> /tmp/test-fail.txt\n# now get all failed addresses:\n$cut -f 1 -d: < /tmp/test-fail.txt\n~~~\n\n\n### Greylisting\nTo pass greylisting protection, use `--max-retry N` option to set retry limit (in seconds). If `--max-retry` is set, verifier will retry every `--retry N` seconds (default: 60), for up to `--max-retry` limit.\n\n> **Note**: Default value for `--max-retry` is 0 (retries disabled). Set it to something like `--max-retry 600` (or even more) to properly handle greylisting.\n\n### Verbose\nIf you want to see how exactly verification happens for email address, use `-v` / `--verbose` to see internal debug messages and `-s` / `--smtp-verbose` to see SMTP conversation. Example:\n\n~~~\n$ grey-verifier -sv yaroslaff@gmail.com\n# Verifying yaroslaff@gmail.com\nconnect: to ('gmail-smtp-in.l.google.com.', 25) None\nreply: b'220 mx.google.com ESMTP 2adb3069b0e04-52ed252cfc0si2901698e87.159 - gsmtp\\r\\n'\nreply: retcode (220); Msg: b'mx.google.com ESMTP 2adb3069b0e04-52ed252cfc0si2901698e87.159 - gsmtp'\nconnect: b'mx.google.com ESMTP 2adb3069b0e04-52ed252cfc0si2901698e87.159 - gsmtp'\nsend: 'helo mir.localdomain\\r\\n'\nreply: b'250 mx.google.com at your service\\r\\n'\nreply: retcode (250); Msg: b'mx.google.com at your service'\nsend: 'mail FROM:<noreply@example.com>\\r\\n'\nreply: b'250 2.1.0 OK 2adb3069b0e04-52ed252cfc0si2901698e87.159 - gsmtp\\r\\n'\nreply: retcode (250); Msg: b'2.1.0 OK 2adb3069b0e04-52ed252cfc0si2901698e87.159 - gsmtp'\nsend: 'rcpt TO:<yaroslaff@gmail.com>\\r\\n'\nreply: b'250 2.1.5 OK 2adb3069b0e04-52ed252cfc0si2901698e87.159 - gsmtp\\r\\n'\nreply: retcode (250); Msg: b'2.1.5 OK 2adb3069b0e04-52ed252cfc0si2901698e87.159 - gsmtp'\nsend: 'quit\\r\\n'\nreply: b'221 2.0.0 closing connection 2adb3069b0e04-52ed252cfc0si2901698e87.159 - gsmtp\\r\\n'\nreply: retcode (221); Msg: b'2.0.0 closing connection 2adb3069b0e04-52ed252cfc0si2901698e87.159 - gsmtp'\n\nyaroslaff@gmail.com\n~~~\n\n### Command-line parameters\n~~~\nusage: grey-verifier [-h] [--file FILE] [-4] [--dns] [--from EMAIL] [--helo HELO] [--timeout N] [--retry N] [--max-retry N] [--verbose] [--smtp-verbose] [email]\n\ngrey-verifier Email address verifier (0.1.6) which knows about SMTP, Greylisting and IPv6\n\noptions:\n -h, --help show this help message and exit\n\nMain Options:\n email Email address to verify\n --file FILE, -f FILE email list\n\nVerification options:\n -4 Check only IPv4 MXes, ignore IPv6 ones\n --dns Simplified DNS-only domain check, without connecting to mailserver and checking recipient address\n --from EMAIL email for MAIL FROM\n --helo HELO HELO host\n --timeout N Timeout for SMTP operations\n\nOptions for retries (Greylisting):\n --retry N Delay (in seconds) if get temporary 4xx error (greylisting) for each retry\n --max-retry N Do not retry for more then N seconds (use 180+, maybe 600).\n\nVerbosity:\n --verbose, -v Verbosity for verifier logic\n --smtp-verbose, -s Verbosity for SMTP conversation\n~~~\n",
"bugtrack_url": null,
"license": null,
"summary": "Smart SMTP email verifier which can even bypass greylisting!",
"version": "0.1.6",
"project_urls": {
"Homepage": "https://github.com/yaroslaff/grey-verifier",
"Issues": "https://github.com/yaroslaff/grey-verifier/issues"
},
"split_keywords": [
"mail from",
" rcpt to",
" smtp",
" bulk",
" e-mail",
" email",
" grey",
" greylist",
" greylisting",
" mail",
" mailfrom",
" validate",
" verifier"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "e603b96afcad74d157e01251bf6af480c15c1152870ecfc8c35d06bf40005dcf",
"md5": "bbd682c14d683b1d5fd95e55400eab82",
"sha256": "aa3fa86b59abcdd5e3318d3bc81799cd9be114e5df2026fc628568d688756c24"
},
"downloads": -1,
"filename": "grey_verifier-0.1.6-py3-none-any.whl",
"has_sig": false,
"md5_digest": "bbd682c14d683b1d5fd95e55400eab82",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.8",
"size": 6525,
"upload_time": "2024-07-18T08:43:57",
"upload_time_iso_8601": "2024-07-18T08:43:57.677854Z",
"url": "https://files.pythonhosted.org/packages/e6/03/b96afcad74d157e01251bf6af480c15c1152870ecfc8c35d06bf40005dcf/grey_verifier-0.1.6-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "ed02c0830b9c6f3340f74bd22393763d1edb4166a2608063a4cab64fc21de041",
"md5": "2c9c8df3918e78254d8e184763d68941",
"sha256": "b58120b4c5b4e0bad4f16edf46741fc1259c037271929feb17883e3fdc68add0"
},
"downloads": -1,
"filename": "grey_verifier-0.1.6.tar.gz",
"has_sig": false,
"md5_digest": "2c9c8df3918e78254d8e184763d68941",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.8",
"size": 6932,
"upload_time": "2024-07-18T08:43:59",
"upload_time_iso_8601": "2024-07-18T08:43:59.283927Z",
"url": "https://files.pythonhosted.org/packages/ed/02/c0830b9c6f3340f74bd22393763d1edb4166a2608063a4cab64fc21de041/grey_verifier-0.1.6.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-07-18 08:43:59",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "yaroslaff",
"github_project": "grey-verifier",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"lcname": "grey_verifier"
}