Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

build CLI and output #8

Merged
merged 3 commits into from
Aug 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
name: Build MailSherpa

on:
push:
branches: [main]
pull_request:
branches: [main]

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3

- name: Set up Go
uses: actions/setup-go@v4
with:
go-version: "1.20"

- name: Build
run: go build -v ./...

- name: Test
run: go test -v ./...
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,4 @@ go.work.sum
# env file
.env

.idea/
.idea/
9 changes: 0 additions & 9 deletions .idea/.gitignore

This file was deleted.

32 changes: 11 additions & 21 deletions datastudy/datastudy.go → bulkvalidate/bulkvalidate.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package datastudy
package bulkvalidate

import (
"encoding/csv"
Expand All @@ -10,8 +10,8 @@

"github.com/lucasepe/codename"

"github.com/customeros/mailsherpa/internal/dns"
"github.com/customeros/mailsherpa/internal/syntax"
"github.com/customeros/mailsherpa/mailvalidate"
)

type DomainResponse struct {
Expand Down Expand Up @@ -102,22 +102,7 @@
return nil
}

func RunDataStudy(inputFilePath, outputFilePath string) {
knownProviders, err := dns.GetKnownProviders("./known_email_providers.toml")
if err != nil {
log.Fatal(err)
}

freeEmails, err := mailvalidate.GetFreeEmailList("./free_emails.toml")
if err != nil {
log.Fatal(err)
}

roleAccounts, err := mailvalidate.GetRoleAccounts("./role_emails.toml")
if err != nil {
log.Fatal(err)
}

func RunBulkValidation(inputFilePath, outputFilePath string) {
testEmails, err := read_csv(inputFilePath)
if err != nil {
log.Fatal(err)
Expand All @@ -143,8 +128,14 @@
}

syntaxResults := mailvalidate.ValidateEmailSyntax(email)
domainResults := mailvalidate.ValidateDomain(request, knownProviders, validateCatchAll)
emailResults := mailvalidate.ValidateEmail(request, knownProviders, freeEmails, roleAccounts)
domainResults, err := mailvalidate.ValidateDomain(request, validateCatchAll)
if err != nil {
log.Printf("Error: %w", err)

Check failure on line 133 in bulkvalidate/bulkvalidate.go

View workflow job for this annotation

GitHub Actions / build

log.Printf does not support error-wrapping directive %w
}
emailResults, err := mailvalidate.ValidateEmail(request)
if err != nil {
log.Printf("Error: %w", err)

Check failure on line 137 in bulkvalidate/bulkvalidate.go

View workflow job for this annotation

GitHub Actions / build

log.Printf does not support error-wrapping directive %w
}

isRisky := false
if emailResults.IsFreeAccount || emailResults.IsRoleAccount || emailResults.IsMailboxFull || domainResults.IsCatchAll || domainResults.IsFirewalled {
Expand All @@ -169,7 +160,6 @@
isRoleAccount: emailResults.IsRoleAccount,
isMailboxFull: emailResults.IsMailboxFull,
isCatchAll: isCatchAll,
smtpError: emailResults.SmtpError,
}
output = append(output, results)
}
Expand Down
7 changes: 4 additions & 3 deletions mailvalidate/name_generator.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
package mailvalidate

import (
"github.com/lucasepe/codename"
"math/rand"
"strings"
"time"

"github.com/lucasepe/codename"
)

func generateNames() (firstName string, lastName string) {
func GenerateNames() (firstName string, lastName string) {
firstNames := []string{
"emma", "liam", "olivia", "noah", "ava", "ethan", "sophia", "mason",
"isabella", "william", "mia", "james", "charlotte", "benjamin", "amelia",
Expand Down Expand Up @@ -62,7 +63,7 @@ func generateNames() (firstName string, lastName string) {
return firstName, lastName
}

func generateCatchAllUsername() string {
func GenerateCatchAllUsername() string {
rng, err := codename.DefaultRNG()
if err != nil {
panic(err)
Expand Down
7 changes: 4 additions & 3 deletions mailvalidate/validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@ package mailvalidate

import (
"fmt"
"github.com/pkg/errors"
"log"
"strings"

"github.com/pkg/errors"

"github.com/customeros/mailsherpa/internal/dns"
"github.com/customeros/mailsherpa/internal/mailserver"
"github.com/customeros/mailsherpa/internal/syntax"
Expand Down Expand Up @@ -256,11 +257,11 @@ func validateRequest(request *EmailValidationRequest) error {
return errors.New("FromDomain is required")
}
if request.FromEmail == "" {
firstName, lastName := generateNames()
firstName, lastName := GenerateNames()
request.FromEmail = fmt.Sprintf("%s.%s@%s", firstName, lastName, request.FromDomain)
}
if request.CatchAllTestUser == "" {
request.CatchAllTestUser = generateCatchAllUsername()
request.CatchAllTestUser = GenerateCatchAllUsername()
}
return nil
}
124 changes: 106 additions & 18 deletions main.go
Original file line number Diff line number Diff line change
@@ -1,43 +1,131 @@
package main

import (
"encoding/json"
"flag"
"fmt"

"github.com/customeros/mailsherpa/bulkvalidate"
"github.com/customeros/mailsherpa/internal/syntax"
"github.com/customeros/mailsherpa/mailvalidate"
"os"
)

func mainTest() {
//datastudy.RunDataStudy("/Users/mbrown/downloads/test.csv", "/Users/mbrown/desktop/results.csv")
}
const (
fromDomain = "gmail.com"
validateFreeAccounts = true
validateRoleMailboxes = true
)

func main() {
email := parseArgs()
flag.Parse()
args := flag.Args()

// build validation request
request := mailvalidate.EmailValidationRequest{
Email: email,
FromDomain: "hubspot.com",
if len(args) < 2 {
printUsage()
return
}

syntaxResults := mailvalidate.ValidateEmailSyntax(email)
if args[0] != "verify" {
fmt.Println("Unknown command.")
printUsage()
return
}

switch args[1] {
case "bulk":
if len(args) != 4 {
fmt.Println("Usage: mailsherpa verify bulk <input file> <output file>")
return
}
bulkVerify(args[2], args[3])
case "domain":
if len(args) != 3 {
fmt.Println("Usage: mailsherpa verify domain <domain>")
return
}
verifyDomain(args[2])
case "syntax":
if len(args) != 3 {
fmt.Println("Usage: mailsherpa verify syntax <email>")
return
}
verifySyntax(args[2])
default:
if len(args) != 2 {
fmt.Println("Usage: mailsherpa verify <email>")
return
}
verifyEmail(args[1])
}
}

func printUsage() {
fmt.Println("Usage: mailhawk <command> [arguments]")
fmt.Println("Commands:")
fmt.Println(" verify bulk <input file> <output file>")
fmt.Println(" verify domain <domain>")
fmt.Println(" verify syntax <email>")
fmt.Println(" verify <email>")
}

func bulkVerify(inputFilePath, outputFilePath string) {
bulkvalidate.RunBulkValidation(inputFilePath, outputFilePath)
}

func verifyDomain(domain string) {
request := buildRequest(fmt.Sprintf("user@%s", domain))
domainResults, err := mailvalidate.ValidateDomain(request, true)
if err != nil {
fmt.Println(err)
fmt.Println("Invalid domain")
}
jsonData, err := json.MarshalIndent(domainResults, "", " ")
if err != nil {
fmt.Println("Error marshalling JSON:", err)
return
}
fmt.Println(string(jsonData))
}

func verifySyntax(email string) {
syntaxResults := mailvalidate.ValidateEmailSyntax(email)
jsonData, err := json.MarshalIndent(syntaxResults, "", " ")
if err != nil {
fmt.Println("Error marshalling JSON:", err)
return
}
fmt.Println(string(jsonData))
}

func verifyEmail(email string) {
request := buildRequest(email)
emailResults, err := mailvalidate.ValidateEmail(request)
if err != nil {
fmt.Println(err)
}
buildResponse(syntaxResults, domainResults, emailResults)
jsonData, err := json.MarshalIndent(emailResults, "", " ")
if err != nil {
fmt.Println("Error marshalling JSON:", err)
return
}
fmt.Println(string(jsonData))
}

func parseArgs() string {
if len(os.Args) != 2 {
fmt.Println("Usage: go run main.go <email>")
os.Exit(1)
func buildRequest(email string) mailvalidate.EmailValidationRequest {
firstname, lastname := mailvalidate.GenerateNames()
_, recipientDomain, ok := syntax.GetEmailUserAndDomain(email)
if !ok {
panic("Invalid email")
}

request := mailvalidate.EmailValidationRequest{
Email: email,
FromDomain: fromDomain,
FromEmail: fmt.Sprintf("%s.%s@%s", firstname, lastname, fromDomain),
CatchAllTestUser: fmt.Sprintf("%s@%S", mailvalidate.GenerateCatchAllUsername, recipientDomain),

Check failure on line 124 in main.go

View workflow job for this annotation

GitHub Actions / build

fmt.Sprintf format %s arg mailvalidate.GenerateCatchAllUsername is a func value, not called
ValidateFreeAccounts: validateFreeAccounts,
ValidateRoleAccounts: validateRoleMailboxes,
}
email := os.Args[1]
return email
return request
}

func buildResponse(syntax mailvalidate.SyntaxValidation, domain mailvalidate.DomainValidation, email mailvalidate.EmailValidation) {
Expand Down
Loading