Skip to content

Commit

Permalink
build CLI and output (#8)
Browse files Browse the repository at this point in the history
* build CLI and output

* add runner

* change to ubuntu
  • Loading branch information
mattbr0wn authored Aug 8, 2024
1 parent 1864fc8 commit 2bf75fe
Show file tree
Hide file tree
Showing 7 changed files with 150 additions and 55 deletions.
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 @@ import (

"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 @@ func writeResultsFile(results []DomainResponse, filePath string) error {
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 @@ func RunDataStudy(inputFilePath, outputFilePath string) {
}

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 @@ func RunDataStudy(inputFilePath, outputFilePath string) {
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

0 comments on commit 2bf75fe

Please sign in to comment.