-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by: adarsh-jaiss <its.adarshjaiss@gmail.com>
- Loading branch information
1 parent
a399fac
commit 5f008a3
Showing
8 changed files
with
617 additions
and
0 deletions.
There are no files selected for viewing
Validating CODEOWNERS rules …
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
@Adarsh-jaiss |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
# Mailify | ||
|
||
Mailify is a Go package for validating email addresses by checking their format, verifying the existence of MX records for the domain, and attempting to connect to the mail servers using SMTP. | ||
|
||
## Installation | ||
|
||
To install the package, run: | ||
|
||
```sh | ||
go get github.com/adarsh-jaiss/mailify | ||
|
||
``` | ||
|
||
## Usage | ||
|
||
### Creating a Client | ||
|
||
To create a new client, use the NewClient function: | ||
|
||
```go | ||
client, err := mailify.NewClient("sender@example.com") | ||
if err != nil { | ||
log.Fatalf("Failed to create mailify client: %v", err) | ||
} | ||
``` | ||
|
||
### Validating an Email Address | ||
|
||
To validate an email address, use the ValidateEmail method: | ||
|
||
```go | ||
result, err := client.ValidateEmail("recipient@example.com") | ||
if err != nil { | ||
log.Fatalf("Failed to validate email: %v", err) | ||
} | ||
|
||
fmt.Println("Validation result:", client.FormatValidationResult("recipient@example.com", result)) | ||
``` | ||
|
||
### Getting Mail Servers | ||
To get the mail servers for a domain, use the GetMailServers method: | ||
|
||
```go | ||
mailServers, err := client.GetMailServers("example.com") | ||
if err != nil { | ||
log.Fatalf("Failed to get mail servers: %v", err) | ||
} | ||
|
||
fmt.Println("Mail servers:", mailServers) | ||
``` | ||
|
||
To get the mail servers for a recipient email, use the GetMailServersFromReceipientEmail method: | ||
|
||
```go | ||
|
||
mailServers, err := client.GetMailServersFromReceipientEmail("recipient@example.com") | ||
if err != nil { | ||
log.Fatalf("Failed to get mail servers: %v", err) | ||
} | ||
|
||
fmt.Println("Mail servers:", mailServers) | ||
``` | ||
|
||
### Example | ||
Here is a complete example demonstrating how to use the package : [check examples]() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
package mailify | ||
|
||
// | ||
// Client represents an email client with a sender email address. | ||
type Client struct { | ||
SenderEmail string | ||
} | ||
|
||
// NewClient creates a new Client instance with the provided sender email address. | ||
// It returns a pointer to the Client and an error, if any. | ||
// | ||
// Parameters: | ||
// - SenderEmail: A string representing the sender's email address. | ||
// | ||
// Returns: | ||
// - *Client: A pointer to the newly created Client instance. | ||
// - error: An error if there is any issue during the creation of the Client. | ||
func NewClient(SenderEmail string) (*Client, error) { | ||
return &Client{ | ||
SenderEmail: SenderEmail, | ||
}, nil | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
package main | ||
|
||
import ( | ||
"log" | ||
"fmt" | ||
|
||
"github.com/adarsh-jaiss/mailify" | ||
) | ||
|
||
func main() { | ||
// Create a new mailguard client | ||
senderEmail := "its.adarshjaiss@gmail.com" | ||
receipientEmail := "hello@namanrai.tech" | ||
|
||
client, err := mailify.NewClient(senderEmail) | ||
if err != nil { | ||
log.Fatalf("Failed to create mailguard client: %v", err) | ||
} | ||
|
||
// Get mail servers for a domain | ||
resp, err := client.GetMailServers("namanrai.tech") | ||
if err != nil { | ||
log.Fatalf("Failed to get mail servers: %v", err) | ||
} | ||
log.Println("Mail servers:", resp) | ||
|
||
// Get mail servers for a recepient email | ||
res, err := client.GetMailServersFromReceipientEmail(receipientEmail) | ||
if err != nil { | ||
log.Fatalf("Failed to get mail servers: %v", err) | ||
} | ||
log.Println("Mail servers:", res) | ||
|
||
// Validate an email address | ||
result, err := client.ValidateEmail(receipientEmail) | ||
if err!= nil { | ||
log.Fatalf("Failed to validate email: %v", err) | ||
} | ||
|
||
fmt.Println("Validation result:", client.FormatValidationResult(receipientEmail,result)) | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
module github.com/adarsh-jaiss/mailify | ||
|
||
go 1.22.1 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
package mailify | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"net" | ||
"strings" | ||
"time" | ||
) | ||
|
||
// GetMailServers retrieves the mail servers (MX records) for a given domain. | ||
// It uses a custom DNS resolver that queries Google's public DNS server (8.8.8.8). | ||
|
||
// Parameters: | ||
// - domain: The domain name for which to look up MX records. | ||
|
||
// Returns: | ||
// - A slice of strings containing the mail server hostnames. | ||
// - An error if there was an issue looking up the MX records. | ||
|
||
// Example: | ||
// mailServers, err := GetMailServers("example.com") | ||
// if err != nil { | ||
// log.Fatalf("Failed to get mail servers: %v", err) | ||
// } | ||
// fmt.Println("Mail servers:", mailServers) | ||
|
||
func(c *Client) GetMailServers(domain string) ([]string, error) { | ||
// Use custom DNS resolver to query Google's public DNS server | ||
|
||
resolver := net.Resolver{ | ||
PreferGo: true, | ||
Dial: func(ctx context.Context, network, address string) (net.Conn, error) { | ||
d := net.Dialer{} | ||
return d.DialContext(ctx, network, "8.8.8.8:53") // Use Google DNS | ||
}, | ||
} | ||
|
||
// Lookup MX records for the domain | ||
mx, err := resolver.LookupMX(context.Background(), domain) | ||
// mx, err := net.LookupMX(domain) | ||
if err != nil { | ||
return nil, fmt.Errorf("error looking up MX records: %v", err) | ||
} | ||
|
||
// Extract mail server hostnames | ||
var mailServers []string | ||
for _, record := range mx { | ||
mailServers = append(mailServers, strings.TrimSuffix(record.Host, ".")) | ||
} | ||
|
||
// Print mail servers | ||
// fmt.Printf("Found mail servers for %s: %v\n", domain, mailServers) | ||
return mailServers, nil | ||
} | ||
|
||
// GetSMTPServer attempts to find an available SMTP server for the given mail server. | ||
// It performs a DNS lookup to get all IP addresses (both IPv4 and IPv6) associated with the mail server, | ||
// and then tries to connect to common SMTP ports (587, 25, 465) on each IP address. | ||
// | ||
// If a connection is successfully established, it returns the SMTP server details including | ||
// the server name, port, protocol, and IP address. If no available SMTP servers are found, | ||
// it returns an error. | ||
// | ||
// Parameters: | ||
// - mailServer: The domain name of the mail server to look up. | ||
// | ||
// Returns: | ||
// - *SMTPDetails: A struct containing the details of the SMTP server if found. | ||
// - error: An error if no available SMTP servers are found or if there is a lookup failure. | ||
func(c *Client) GetSMTPServer(mailServer string) (*SMTPDetails, error) { | ||
// Get all IPs (both IPv4 and IPv6) | ||
ips, err := net.LookupIP(mailServer) | ||
if err != nil { | ||
return nil, fmt.Errorf("failed to lookup IP for %s: %v", mailServer, err) | ||
} | ||
|
||
// Try each IP address | ||
for _, ip := range ips { | ||
// Try common SMTP ports | ||
ports := []string{"587", "25", "465"} | ||
for _, port := range ports { | ||
// Format address based on IP version | ||
var address string | ||
if ip.To4() != nil { | ||
// IPv4 | ||
address = fmt.Sprintf("%s:%s", ip.String(), port) | ||
} else { | ||
// IPv6 - wrap in square brackets | ||
address = fmt.Sprintf("[%s]:%s", ip.String(), port) | ||
} | ||
|
||
// Set timeout for connection | ||
smtpTimeout := time.Duration(time.Second * 5) | ||
|
||
// Try to connect | ||
conn, err := net.DialTimeout("tcp", address, smtpTimeout) | ||
if err != nil { | ||
continue | ||
} | ||
defer conn.Close() | ||
|
||
return &SMTPDetails{ | ||
Server: mailServer, | ||
Port: port, | ||
Protocol: "SMTP", | ||
IPAddress: ip.String(), | ||
}, nil | ||
} | ||
} | ||
return nil, fmt.Errorf("no available SMTP servers found for %s", mailServer) | ||
} | ||
|
||
// GetMailServersFromReceipientEmail extracts the domain from the given email address | ||
// and retrieves the mail servers associated with that domain. | ||
// | ||
// Parameters: | ||
// email (string): The recipient's email address. | ||
// | ||
// Returns: | ||
// []string: A slice of mail server addresses. | ||
// error: An error object if there was an issue extracting the domain or retrieving the mail servers. | ||
func(c *Client) GetMailServersFromReceipientEmail(email string) ([]string, error) { | ||
// Extract domain from email address | ||
domain,err := c.ExtractDomainFromEmailAddress(email) | ||
if err != nil { | ||
return nil, fmt.Errorf("error extracting domain from email address: %v", err) | ||
} | ||
|
||
return c.GetMailServers(domain) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
package mailify | ||
|
||
|
||
// SMTPDetails holds the details required to connect to an SMTP server. | ||
type SMTPDetails struct { | ||
// Server is the address of the SMTP server. | ||
Server string | ||
// Port is the port number on which the SMTP server is listening. | ||
Port string | ||
// Protocol is the protocol used by the SMTP server (e.g., "SMTP", "SMTPS"). | ||
Protocol string | ||
// UsedTLS indicates whether TLS is used for the connection. | ||
UsedTLS bool | ||
// IPAddress is the IP address of the SMTP server. | ||
IPAddress string | ||
} | ||
|
||
// ValidationResult represents the result of an email validation check. | ||
type ValidationResult struct { | ||
// IsValid indicates whether the email address is valid. | ||
IsValid bool | ||
// IsCatchAll indicates whether the domain has a catch-all address. | ||
IsCatchAll bool | ||
// HasMX indicates whether the domain has MX records. | ||
HasMX bool | ||
// ErrorMessage contains any error message encountered during validation. | ||
ErrorMessage string | ||
// SMTPDetails contains the SMTP server details used for validation. | ||
SMTPDetails *SMTPDetails | ||
} | ||
|
Oops, something went wrong.