469,086 Members | 1,113 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,086 developers. It's quick & easy.

Email Verification

what else can done to reach every domain

Expand|Select|Wrap|Line Numbers
  1. @app.route('/<string:email>',methods=['GET','POST'])
  2. def post(email):
  3.     blocked_keywords = ["spamhaus",
  4.             "proofpoint",
  5.             "cloudmark",
  6.             "banned",
  7.             "blacklisted",
  8.             "blocked",
  9.             "block list",
  10.             "denied"]
  11.  
  12.  
  13.  
  14.     proxy = {
  15.         'socks4': socks.SOCKS4,
  16.         'socks5': socks.SOCKS5,
  17.         'http': socks.HTTP # does not guareentee it will work with HTTP
  18.     }
  19.  
  20.     class UnknownProxyError(Exception):
  21.         def __init__(self, proxy_type):
  22.             self.msg = f"The proxy type {proxy_type} is not known\n Try one of socks4, socks5 or http"
  23.  
  24.     class EmailFormatError(Exception):
  25.  
  26.         def __init__(self, msg):
  27.             self.msg = msg
  28.  
  29.     class SMTPRecepientException(Exception): # don't cover
  30.  
  31.         def __init__(self, code, response):
  32.             self.code = code
  33.             self.response = response
  34.  
  35.  
  36.     ####
  37.     # SMTP RCPT error handlers
  38.     ####
  39.     def handle_550(response):
  40.         if any([keyword.encode() in response for keyword in blocked_keywords]):
  41.             return dict(message="Blocked by mail server- couldn't verify", deliverable=False, host_exists=True)
  42.         else:
  43.             return dict(deliverable=False, host_exists=True)
  44.  
  45.  
  46.  
  47.  
  48.     handle_error = {
  49.         # 250 and 251 are not errors
  50.         550: handle_550,
  51.         551: lambda _: dict(deliverable=False, host_exists=True),
  52.         552: lambda _: dict(deliverable=True, host_exists=True, full_inbox=True),
  53.         553: lambda _: dict(deliverable=False, host_exists=True),
  54.         450: lambda _: dict(deliverable=False, host_exists=True),
  55.         451: lambda _: dict(deliverable=False, message="Local error processing, try again later."),
  56.         452: lambda _: dict(deliverable=True, full_inbox=True),
  57.         # Syntax errors
  58.         # 500 (command not recognised)
  59.         # 501 (parameter/argument not recognised)
  60.         # 503 (bad command sequence)
  61.         521: lambda _: dict(deliverable=False, host_exists=False),
  62.         421: lambda _: dict(deliverable=False, host_exists=True, message="Service not available, try again later."),
  63.         441: lambda _: dict(deliverable=True, full_inbox=True, host_exists=True)
  64.     }
  65.  
  66.     handle_unrecognised = lambda a: dict(message=f"Unrecognised error: {a}", deliverable=False)
  67.  
  68.  
  69.     # create a namedtuple to hold the email address
  70.     Address = namedtuple("Address", ["name", "addr", "username", "domain"])
  71.  
  72.     class e_verifier:
  73.  
  74.         def __init__(self,
  75.                     source_addr,
  76.                     proxy_type = None,
  77.                     proxy_addr = None,
  78.                     proxy_port = None,
  79.                     proxy_username = None ,
  80.                     proxy_password = None):
  81.  
  82.  
  83.             if proxy_type:
  84.                 try:
  85.                     self.proxy_type = proxy[proxy_type.lower()]
  86.                 except KeyError as e:
  87.                     raise UnknownProxyError(proxy_type)
  88.             else:
  89.                 self.proxy_type = None
  90.             self.source_addr = source_addr
  91.             self.proxy_addr = proxy_addr
  92.             self.proxy_port = proxy_port
  93.             self.proxy_username = proxy_username
  94.             self.proxy_password = proxy_password
  95.  
  96.         def _parse_address(self, email) -> Address:
  97.  
  98.             name, addr = parseaddr(email)
  99.             if not addr:
  100.                 raise EmailFormatError(f"email does not contain address: {email}")
  101.             try:
  102.                 domain = addr.split('@')[-1]
  103.                 username = addr.split('@')[:-1][0]
  104.             except IndexError:
  105.                 raise EmailFormatError(f"address provided is invalid: {email}")
  106.             return Address(name, addr, username, domain)
  107.  
  108.         def _random_email(self, domain):
  109.  
  110.             return f'{binascii.hexlify(os.urandom(20)).decode()}@{domain}'
  111.  
  112.         def _can_deliver(self,
  113.                         exchange : str,
  114.                         address : str):
  115.  
  116.             host_exists = False
  117.             with SMTP(exchange[1],
  118.                     proxy_type=self.proxy_type,
  119.                     proxy_addr=self.proxy_addr,
  120.                     proxy_port=self.proxy_port,
  121.                     proxy_username=self.proxy_username,
  122.                     proxy_password=self.proxy_password) as smtp:
  123.                 host_exists = True
  124.                 smtp.helo()
  125.                 smtp.mail(self.source_addr)
  126.                 test_resp = smtp.rcpt(address.addr)
  127.                 catch_all_resp = smtp.rcpt(self._random_email(address.domain))
  128.                 if test_resp[0] == 250:
  129.                     deliverable = True
  130.                     if catch_all_resp[0] == 250:
  131.                         catch_all = True
  132.                     else:
  133.                         catch_all = False
  134.                 elif test_resp[0] >= 400:
  135.                     raise SMTPRecepientException(*test_resp)
  136.             return host_exists, deliverable, catch_all
  137.  
  138.         def verify(self, email):
  139.  
  140.             lookup = {
  141.                 'address': None,
  142.                 'valid_format': False,
  143.                 'deliverable': False,
  144.                 'full_inbox': False,
  145.                 'host_exists': False,
  146.                 'catch_all': False,
  147.             }
  148.             try:
  149.                 lookup['address'] = self._parse_address(email)
  150.                 lookup['valid_format'] = True
  151.             except EmailFormatError:
  152.                 lookup['address'] = f"{email}"
  153.                 return lookup
  154.  
  155.             # look for mx record and create a list of mail exchanges
  156.             try:
  157.                 mx_record = resolver.query(lookup['address'].domain, 'MX')
  158.                 mail_exchangers = [exchange.to_text().split() for exchange in mx_record]
  159.                 lookup['host_exists'] = True
  160.             except (resolver.NoAnswer, resolver.NXDOMAIN, resolver.NoNameservers):
  161.                 lookup['host_exists'] = False
  162.                 return lookup
  163.  
  164.             for exchange in mail_exchangers:
  165.                 try:
  166.                     host_exists, deliverable, catch_all = self._can_deliver(exchange, lookup['address'])
  167.                     if deliverable:
  168.                         lookup['host_exists'] = host_exists
  169.                         lookup['deliverable'] = deliverable
  170.                         lookup['catch_all'] = catch_all
  171.                         break
  172.                 except SMTPRecepientException as err:
  173.                     # Error handlers return a dict that is then merged with 'lookup'
  174.                     kwargs = handle_error.get(err.code, handle_unrecognised)(err.response)
  175.                     # This expression merges the lookup dict with kwargs
  176.                     lookup = {**lookup, **kwargs}
  177.  
  178.                 except smtplib.SMTPServerDisconnected as err:
  179.                     lookup['message'] = "Internal Error"
  180.                 except smtplib.SMTPConnectError as err:
  181.  
  182.                     lookup['message'] = "Internal Error. Maybe blacklisted"
  183.  
  184.             return lookup
  185.  
  186.     v = e_verifier(source_addr='user@example.com')
  187.     email = email
  188.     l = v.verify(email)
  189.     return l  
  190.  
  191. if __name__ == "__main__":
  192.     app.run(debug=True)
  193.  
  194.  
Jul 26 '21 #1
0 2681

Post your reply

Sign in to post your reply or Sign up for a free account.

Similar topics

reply views Thread by email verification | last post: by
7 posts views Thread by SOR | last post: by
2 posts views Thread by toedipper | last post: by
1 post views Thread by Jagadesh | last post: by
4 posts views Thread by shalinikonatam | last post: by
1 post views Thread by CARIGAR | last post: by
reply views Thread by kglaser89 | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.