Giter Club home page Giter Club logo

email-verifier's Introduction

email-verifier

βœ‰οΈ A Go library for email verification without sending any emails.

Build Status Godoc Coverage Status Go Report Card license

Features

  • Email Address Validation: validates if a string contains a valid email.
  • Email Verification Lookup via SMTP: performs an email verification on the passed email (catchAll detection enabled by default)
  • MX Validation: checks the DNS MX records for the given domain name
  • Misc Validation: including Free email provider check, Role account validation, Disposable emails address (DEA) validation
  • Email Reachability: checks how confident in sending an email to the address

Install

Use go get to install this package.

go get -u github.com/AfterShip/email-verifier

Usage

Basic usage

Use Verify method to verify an email address with different dimensions

package main

import (
	"fmt"
	
	emailverifier "github.com/AfterShip/email-verifier"
)

var (
	verifier = emailverifier.NewVerifier()
)


func main() {
	email := "[email protected]"

	ret, err := verifier.Verify(email)
	if err != nil {
		fmt.Println("verify email address failed, error is: ", err)
		return
	}
	if !ret.Syntax.Valid {
		fmt.Println("email address syntax is invalid")
		return
	}

	fmt.Println("email validation result", ret)
	/*
		result is:
		{
			"email":"[email protected]",
			"disposable":false,
			"reachable":"unknown",
			"role_account":false,
			"free":false,
			"syntax":{
			"username":"example",
				"domain":"exampledomain.org",
				"valid":true
			},
			"has_mx_records":true,
			"smtp":null,
			"gravatar":null
		}
	*/
}

Email verification Lookup

Use CheckSMTP to performs an email verification lookup via SMTP.

var (
    verifier = emailverifier.
        NewVerifier().
        EnableSMTPCheck()
)

func main() {

    domain := "domain.org"
    username := "username"
    ret, err := verifier.CheckSMTP(domain, username)
    if err != nil {
        fmt.Println("check smtp failed: ", err)
        return
    }

    fmt.Println("smtp validation result: ", ret)

}

If you want to disable catchAll checking, use the DisableCatchAllCheck() switch (in effect only when SMTP verification is enabled).

 verifier = emailverifier.
        NewVerifier().
        EnableSMTPCheck().
        DisableCatchAllCheck()

Note: because most of the ISPs block outgoing SMTP requests through port 25 to prevent email spamming, the module will not perform SMTP checking by default. You can initialize the verifier with EnableSMTPCheck() to enable such capability if port 25 is usable, or use a socks proxy to connect over SMTP

Use a SOCKS5 proxy to verify email

Support setting a SOCKS5 proxy to verify the email, proxyURI should be in the format: socks5://user:[email protected]:1080?timeout=5s

The protocol could be socks5, socks4 and socks4a.

var (
    verifier = emailverifier.
        NewVerifier().
        EnableSMTPCheck().
    	Proxy("socks5://user:[email protected]:1080?timeout=5s")
)

func main() {

    domain := "domain.org"
    username := "username"
    ret, err := verifier.CheckSMTP(domain, username)
    if err != nil {
        fmt.Println("check smtp failed: ", err)
        return
    }

    fmt.Println("smtp validation result: ", ret)

}

Misc Validation

To check if an email domain is disposable via IsDisposable

var (
    verifier = emailverifier.
        NewVerifier().
        EnableAutoUpdateDisposable()
)

func main() {
    domain := "domain.org"
    if verifier.IsDisposable(domain) {
        fmt.Printf("%s is a disposable domain\n", domain)
        return
    }
    fmt.Printf("%s is not a disposable domain\n", domain)
}

Note: It is possible to automatically update the disposable domains daily by initializing verifier with EnableAutoUpdateDisposable()

Suggestions for domain typo

Will check for typos in an email domain in addition to evaluating its validity. If we detect a possible typo, you will find a non-empty "suggestion" field in the validation result containing what we believe to be the correct domain. Also, you can use the SuggestDomain() method alone to check the domain for possible misspellings

func main() {
    domain := "gmai.com"
    suggestion := verifier.SuggestDomain(domain) 
    // suggestion should be `gmail.com`
    if suggestion != "" {
        fmt.Printf("domain %s is misspelled, right domain is %s. \n", domain, suggestion)
        return 
    }
    fmt.Printf("domain %s has no possible misspellings. \n", domain)
}

Note: When using the Verify() method, domain typo checking is not enabled by default, you can enable it in a verifier with EnableDomainSuggest()

For more detailed documentation, please check on godoc.org πŸ‘‰ email-verifier

API

We provide a simple self-hosted API server script for reference.

The API interface is very simple. All you need to do is to send a GET request with the following URL.

The email parameter would be the target email you want to verify.

https://{your_host}/v1/{email}/verification

Similar Libraries Comparison

email-verifier trumail check-if-email-exists freemail
Features 〰️ 〰️ 〰️ 〰️
Disposable email address validation βœ… βœ…, but not available in free lib βœ… βœ…
Disposable address autoupdate βœ… πŸ€” ❌ ❌
Free email provider check βœ… βœ…, but not available in free lib ❌ βœ…
Role account validation βœ… ❌ βœ… ❌
Syntax validation βœ… βœ… βœ… ❌
Email reachability βœ… βœ… βœ… ❌
DNS records validation βœ… βœ… βœ… ❌
Email deliverability βœ… βœ… βœ… ❌
Mailbox disabled βœ… βœ… βœ… ❌
Full inbox βœ… βœ… βœ… ❌
Host exists βœ… βœ… βœ… ❌
Catch-all βœ… βœ… βœ… ❌
Gravatar βœ… βœ…, but not available in free lib ❌ ❌
Typo check βœ… βœ…, but not available in free lib ❌ ❌
Use proxy to connect over SMTP βœ… ❌ βœ… ❌
Honeyport dection πŸ”œ ❌ ❌ ❌
Bounce email check πŸ”œ ❌ ❌ ❌
Tech 〰️ 〰️ 〰️ 〰️
Provide API βœ… βœ… βœ… ❌
Free API βœ… ❌ ❌ ❌
Language Go Go Rust JavaScript
Active maintain βœ… ❌ βœ… βœ…
High Performance βœ… ❌ βœ… βœ…

FAQ

The library hangs/takes a long time after 30 seconds when performing email verification lookup via SMTP

Most ISPs block outgoing SMTP requests through port 25 to prevent email spamming. email-verifier needs to have this port open to make a connection to the email's SMTP server. With the port being blocked, it is not possible to perform such checking, and it will instead hang until timeout error. Unfortunately, there is no easy workaround for this issue.

For more information, you may also visit this StackOverflow thread.

The output shows "connection refused" in the smtp.error field.

This error can also be due to SMTP ports being blocked by the ISP, see the above answer.

What does reachable: "unknown" means

This means that the server does not allow real-time verification of an email right now, or the email provider is a catch-all email server.

Credits

Contributing

For details on contributing to this repository, see the contributing guide.

License

This package is licensed under MIT license. See LICENSE for details.

email-verifier's People

Contributors

bossa573 avatar calvinxiao avatar chuan-t avatar daisy1754 avatar dependabot[bot] avatar gosom avatar henhouse avatar lguminski avatar lryong avatar neocn avatar oiscircle avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

email-verifier's Issues

API Call response shows SMTP null

Why smtp shows null?

@{
email: "[email protected]",
reachable: "unknown",
syntax: {
username: "abcd",
domain: "gmail.com",
valid: true
},
smtp: null,
gravatar: null,
suggestion: "",
disposable: false,
role_account: false,
free: true,
has_mx_records: true
}

Failed when check STMP use SOCKS5 proxy

Hi there,
I tried to use the new feature "Support Use the specified SOCKS5 proxy host to perform email verification" of @lryong
When I check smtp, the response is:
"check smtp failed: EOF : EOF"
I debugged, the code throw exception in function NewClient() (located in file stmp.go), in line 64 when call text.ReadResponse(220)
Please help me for that.

Failed when check STMP use SOCKS5 proxy

I have the same problem, why in the doc it is indicated "with EnableSMTPCheck() to enable such capability if port 25 is usable, or use a socks proxy to connect over SMTP" we can understand with this sentence that the arrival of socks proxy solve the problem of SMTP with port 25 while the problem persists

Originally posted by @devlamine in #51 (comment)

Add disposable domain via code?

Is there a way to add more disposable domains via code? I have couple more domains so I opened PR for disposable/disposable#62 but PR has been open for 2+ weeks. I want to put override on emailverifier side but I cannot seem to find any method for that

proxy server

Great work!
Is there a way to use the smtp go client through a SOCKS proxy?
Thank you

Proxy not working

Hi, Could you plz suggest a proxy name which supports your code? bcz I tried many but does not supporting.

Making catchAll detection optional

The catchAll detection relies on checking the response to a randomly generated email. Effectively it doubles the number of checks, which for batch processing is a problem, as it increases the chance of being blacklisted.

So it would be nice to perform catchAll detection once and then run the entire batch without it. For that it would be nice to have DisableCatchAllCheck() functional switch.

PR follows

Option to Enable/Disable MX Records Check

We encountered an issue with the CheckMX functionality as it currently lacks a configurable option for disabling this check. It would be highly beneficial to have a similar functionality to that of CheckSMTP, which already implements an option to enable or disable SMTP checks using a bool variable:

func (v *Verifier) CheckSMTP(domain, username string) (*SMTP, error) {
    if !v.smtpCheckEnabled {
        return nil, nil
    }
    // ...
}

To address this limitation, I propose introducing a new field specifically for enabling or disabling MX checks in the Verifier. This approach would align with the existing implementation in CheckSMTP.

For example, the modified code snippet could look like this:

func (v *Verifier) CheckMX(domain string) (*Mx, error) {
    if !v.mxCheckEnabled {
        return nil, nil
    }
    // ...
}

I think it makes sense to set mxCheckEnabled value to true by default, so it won't change current behavior.

I am enthusiastic about contributing to this enhancement if my proposal aligns with your vision.

Suggestion working differently in Verify and SuggestDomain functions

package main

import (
	"fmt"
	emailverifier "github.com/AfterShip/email-verifier"
)

func main() {
	verifier := emailverifier.
		NewVerifier().
		EnableDomainSuggest()

	ret, _ := verifier.Verify("[email protected]")
	fmt.Println("Suggestion 1: ", ret.Suggestion)

	suggestion := verifier.SuggestDomain(ret.Syntax.Domain)
	fmt.Println("Suggestion 2: ", suggestion)
}

Real result

Suggestion 1: 
Suggestion 2:  gmail.com

Expected result:

Suggestion 1:  gmail.com
Suggestion 2:  gmail.com

These two examples should have the same results however the Verify function results an empty suggestion while SuggestDomain function works as expected.

However testing the same code with this example [email protected] has the same result with both cases:

Suggestion 1:  gmal.com
Suggestion 2:  gmal.com

Tested with Go version 1.21

Help installing this on ubuntu 22.04

Hi I'm trying install it on ubuntu 22.04 but when i execute the command to install it i see the following error

go get -u github.com/AfterShip/email-verifier

go: go.mod file not found in current directory or any parent directory.
	'go get' is no longer supported outside a module.
	To build and install a command, use 'go install' with a version,
	like 'go install example.com/cmd@latest'
	For more information, see https://golang.org/doc/go-get-install-deprecation
	or run 'go help get' or 'go help install'.

NOTE: i also used the gollowing command but is not working neither

go install github.com/AfterShip/email-verifier@latest
package github.com/AfterShip/email-verifier is not a main package

How to get Faster Resposne from email-verifier when checking list of emails.

well,
First thanks for contributors for awesome library.

I already created a Go application using this library. I created a post endpoint that takes only a list of emails. Then Using this library I generate a custom validation response. But for a list of 10 emails, it took 32~40 seconds. I want to reduce that one. Note that my internet speed is well. Sample code for lists of email verifications.

Thanks in Advance.


func ProcessEmailList(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {

	w.Header().Set("Content-Type", "application/json")

	errorResponse := ErrorResponse{
		Code:    400,
		Message: "Error",
	}

	// Read the request body
	body, err := io.ReadAll(r.Body)
	if err != nil {
		errorResponse.Message = err.Error()
		error_json, _ := json.Marshal(errorResponse)
		w.WriteHeader(http.StatusBadRequest)
		fmt.Fprint(w, string(error_json))

		return
	}

	// Unmarshal the JSON request body into EmailListRequest struct
	var request EmailListRequest
	if err := json.Unmarshal(body, &request); err != nil {
		errorResponse.Message = "Error parsing JSON"
		error_json, _ := json.Marshal(errorResponse)
		w.WriteHeader(http.StatusBadRequest)
		fmt.Fprint(w, string(error_json))
		return
	}

	// Split the comma-separated string into a slice of email addresses
	emails := strings.Split(request.Emails, ",")
	responseList := []EmailRespose{}

	// Process the list of emails
	for _, email := range emails {
		responseList = append(responseList, SimplyVerifyEmail(email))
	}

	// Respond to the client
	w.WriteHeader(http.StatusOK)
	jsonResponse, err := json.Marshal(responseList)
	fmt.Fprint(w, string(jsonResponse))
}

Initiate disposable domain list from the update URL

Hi,

it would be really nice if you could make updateDisposableDomains optionally triggered when EnableAutoUpdateDisposable is called. This way one could initialize the map immediately instead of waiting for 24h. I know there is AddDisposableDomains and one could fetch from the same source and push it in... but due to this it's then permanent which some may not want.

Cheers!

Does Yahoo work?

Does this work with @yahoo emails? Usually I have seen other providers use Yahoo API for validating those emails.

Some existing mailbox on domain without CatchAll are identified as unreachable

Hi,

I tried SMTP check on personnal outlook.fr mailbox and it seems that mx record eur.olc.protection.outlook.com don't like consecutive RCPT TO requests.

On smtp.go, I moved the catchAll block code below the test of the real username and the username is correctly detected as deliverable with 250 smtp response code, however this time the RCPT TO request with random username is rejected by mx record with 452 response code.

This issue probably doesn't concern only outlook.fr.

More generally, it may be a good idea to add a feature "safe check" that check the smtp response code and if it is different to 450 the user’s mailbox was unavailable or similare code it doesn't qualified the mailbox as unreachable. I put this idea here but it may be a different issue.

Thanks for all your work

Wrong Results On Verification Of Outlook Emails

On verifying emails of outlook domain from verifier, it gives reachable: no for emails which actually exists and are currently in use.

These are the results on verification of a valid email address :

{
email: "[email protected]",
reachable: "no",
syntax: {
username: "ratnesh.xdeliver",
domain: "outlook.com",
valid: true,
},
smtp: {
host_exists: true,
full_inbox: false,
catch_all: false,
deliverable: false,
disabled: false,
},
gravatar: null,
suggestion: "",
disposable: false,
role_account: false,
free: true,
has_mx_records: true,
}

Please review and provide solution or reasons @lryong .
Thank You!!

Address Verify("abce") returns no error?

For invalid syntax email address, the Verify() func returns err is nil. For example

emailverifier.NewVerifier()
ret, verifyErr := verifier.Verify("abce")
// verifyErr is nil 

In code, I think at least here will return a error, rather than nil?

	if !syntax.Valid {
		return &ret, nil
	}

Yahoo seems to incorrectly return catch_all=true and deliverable=false

Hi, The results for yahoo seem to be incorrect.

I get this result for valid yahoo addresses.

{"host_exists":true,"full_inbox":false,"catch_all":true,"deliverable":false,"disabled":false}

If I try and email a random yahoo email like the ones used for catch_all detection, I receive a bounce back.

It seems like SMTP RCPT verification is not enough for yahoo and possibly other providers.

Perhaps this project could maintain a list of providers that don't work and return an 'unknown' response.

Ps, thanks for the nice project.

Undefined variables and functions in verifier.go

Hello,

I'm having trouble building the email verifier program from the AfterShip repository. When I run the "go build" command in the terminal, I get the following error:

command-line-arguments
./verifier.go:15:24: undefined: schedule
./verifier.go:24:15: undefined: Syntax
./verifier.go:25:16: undefined: SMTP
./verifier.go:26:16: undefined: Gravatar
./verifier.go:39:17: undefined: disposableDomains
./verifier.go:40:3: undefined: disposableSyncDomains
./verifier.go:47:25: undefined: defaultFromEmail
./verifier.go:48:25: undefined: defaultHelloName
./verifier.go:58:14: undefined: reachableUnknown
./verifier.go:203:42: undefined: SMTP
./verifier.go:58:14: too many errors

It seems that the variables and functions used in the verifier.go file are undefined. I have tried running the "go get" command to download the necessary packages, but I still get the same error.

Could you please help me with this issue? I would greatly appreciate any assistance you can provide.

Thank you!

Gravatar is always valid.

Even if the gravatar image does not exist the verifier return true and a link.

The URL should have d parameter to get 404 code from gravatar.
For example, https://www.gravatar.com/avatar/00000000000000000000000000000001?d=404
instead of https://www.gravatar.com/avatar/00000000000000000000000000000001

550 5.5.0 Invalid EHLO/HELO domain

package email :

func Split(Email string) (domain string, username string) {
	split := strings.Split(Email, "@")
	domain = split[1]
	username = split[0]
	return
}

func CheckSMTP(Email string) (response string, Error error) {
	verifier := emailverifier.NewVerifier().EnableSMTPCheck()
	domain, username := Split(Email)
	check, error := verifier.CheckSMTP(domain, username)
	if error != nil {
		Error = error
	}

	var json = jsoniter.ConfigCompatibleWithStandardLibrary
	var buffer bytes.Buffer
	var interfaces interface{} = check
	error = json.NewEncoder(&buffer).Encode(&interfaces)
	if error != nil {
		Error = error
	}

	response = buffer.String()

	return
}

package main :

func main() {
c, error := email.CheckSMTP("[email protected]")
	if error != nil {
		print(error.Error())
	} else {
		print(c)
	}

I'm got an error Mail server is unavailable : 550 5.5.0 Invalid EHLO/HELO domain. does mail server block connection to port 25 ?

Unable to run code

I am unable to run this code . can you please let us know the process. how to run this code. its showing error
main.go:6:2: found packages emailverifier (address.go) and main (main.go) in /Users/user/workplace/email-verifier

Screenshot 2021-05-12 at 1 08 13 AM

the api gxlu?email= of gmail no longer active

Sorry for this to say but after testing the api we all using for gmail unlimited account has been disable
its no longer return compass cookies
anyone know how to overcome this or we have to fallback to smtp

how can i do smtp check with general validation?

I need result like this format
{ "email": "[email protected]", "disposable": false, "reachable": "unknown", "role_account": false, "free": false, "syntax": { "username": "tuyensinh", "domain": "ued.udn.vn", "valid": true }, "has_mx_records": true, "smtp": { "host_exists": true, "full_inbox": false, "catch_all": true, "deliverable": false, "disabled": false }, "gravatar": null, "suggestion": "" }

data file load issue if compile and runtime are in different computer

In your documentation, there is no mention that this library has a dependency on the data folder. Until I want to compile my code on the CI server and deploy it to the production server. I found this library loading data file base on runtime.Caller(). However, runtime.Caller returns the compiled GOPATH instead of the real "runtime" path. This makes this cross-machine deployment impossible. https://stackoverflow.com/questions/51368837/golang-runtime-package-sets-filepaths-from-the-system-on-which-it-was-built

I am not expert on golang, no sure how your guys to cope with this? Any reason use a compile time base path?

Here is how your code get data basePath:
_, b, _, _ = runtime.Caller(0)
basePath = filepath.Dir(b)

One more question, is this project still alive? I don't see any activities after initial commit. Thank you.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.