module MailVerifier

Constants

VERSION

Public Class Methods

close_connection() click to toggle source
# File lib/mail_verifier/verifier.rb, line 62
def close_connection
  @smtp.finish if @smtp && @smtp.started?
end
connect() click to toggle source
# File lib/mail_verifier/verifier.rb, line 45
def connect
  begin
    server = next_server
    raise OutOfMailServersException.new("Unable to connect to any one of mail servers for #{@dest_email}") if server.nil?
    @smtp = Net::SMTP.start server[:address], 25, @origin_domain
    return true
  rescue OutOfMailServersException => e
    raise OutOfMailServersException, e.message
  rescue => e
    retry
  end
end
ensure_250(smtp_return) click to toggle source
# File lib/mail_verifier/verifier.rb, line 90
def ensure_250(smtp_return)
  if smtp_return.status.to_i == 250
    return true
  else
    raise FailureException.new "Mail server responded with #{smtp_return.status} when we were expecting 250"
  end
end
ensure_connected() click to toggle source
# File lib/mail_verifier/verifier.rb, line 86
def ensure_connected
  raise NotConnectedException.new("You have to connect first") if @smtp.nil?
end
is_connected() click to toggle source
# File lib/mail_verifier/verifier.rb, line 41
def is_connected
  !@smtp.nil?
end
list_mxs(domain) click to toggle source
# File lib/mail_verifier/verifier.rb, line 28
def list_mxs(domain)
  return [] unless domain
  mxs = []
  res = Resolv::DNS.new.getresources(domain, Resolv::DNS::Resource::IN::MX)

  raise NoMailServerException.new("#{domain} does not exist") if res == []

  res.each do |resource|
    mxs << { priority: resource.preference, address: resource.exchange.to_s }
  end
  mxs.sort_by { |mx| mx[:priority] }
end
mailfrom(address) click to toggle source
# File lib/mail_verifier/verifier.rb, line 66
def mailfrom(address)
  ensure_connected

  ensure_250 @smtp.mailfrom(address)
end
next_server() click to toggle source
# File lib/mail_verifier/verifier.rb, line 58
def next_server
  @servers.shift
end
rcptto(address) click to toggle source
# File lib/mail_verifier/verifier.rb, line 72
def rcptto(address)
  ensure_connected

  begin
    ensure_250 @smtp.rcptto(address)
  rescue => e
    if e.message[/^550/]
      return false
    else
      raise FailureException.new(e.message)
    end
  end
end
verify(origin_email, dest_email) click to toggle source

Entry point.

# File lib/mail_verifier/verifier.rb, line 8
def verify(origin_email, dest_email)
  @origin_email  = origin_email # Some servers require a real mail as "from" to check for destination mails.
  @dest_email    = dest_email
  @dest_domain   = dest_email.split("@")[1]
  @origin_domain = @origin_email.split("@")[1]
  @servers       = list_mxs @dest_domain
  @smtp          = nil

  raise NoMailServerException.new("No mail server for #{@dest_email}") if @servers.empty?
  verify!
end
verify!() click to toggle source
# File lib/mail_verifier/verifier.rb, line 20
def verify!
  connect
  self.mailfrom @origin_email
  self.rcptto(@dest_email).tap do
    close_connection
  end
end