func main() { flag.StringVar(&htmlTemplatePath, "html", "", "html template path") flag.StringVar(&textTemplatePath, "text", "", "text template path") flag.StringVar(&csvPath, "csv", "", "path to csv of contact list") flag.StringVar(&smtpURL, "server", "", "url of smtp server") flag.StringVar(&smtpPort, "port", "", "port of smtp server") flag.StringVar(&smtpUser, "user", "", "smtp username") flag.StringVar(&smtpPassword, "password", "", "smtp password") flag.StringVar(&sender, "sender", "", "email to send from") flag.StringVar(&subject, "subject", "", "subject of email") flag.BoolVar(&debug, "debug", false, "print emails to stdout instead of sending") flag.StringVar(&attach, "attach", "", "attach a list of comma separated files") requiredFlagNames := []string{"html", "text", "csv", "server", "port", "user", "password", "sender", "subject"} flag.VisitAll(func(f *flag.Flag) { flags = append(flags, f) for _, name := range requiredFlagNames { if name == f.Name { requiredFlags = append(requiredFlags, f) } } }) flag.Usage = usage flag.Parse() if attach != "" { files = strings.Split(attach, ",") } else { files = []string{} } checkAndHandleMissingFlags(requiredFlags) csv, err := os.Open(csvPath) if err != nil { fmt.Fprintln(os.Stderr, "Error opening CSV:", err.Error()) os.Exit(2) } defer csv.Close() recipients, emailField, err := readCSV(csvPath) if err != nil { fmt.Fprintln(os.Stderr, "Error reading CSV:", err.Error()) os.Exit(2) } mailer := mail.NewMailer( smtpUser, smtpPassword, smtpURL, smtpPort, ) success := make(chan *email.Email) fail := make(chan error) go func() { for _, recipient := range *recipients { go sendMail(recipient, *emailField, &mailer, debug, success, fail) } }() for i := 0; i < len(*recipients); i++ { select { case msg := <-success: if !debug { fmt.Printf("\rEmailed recipient %d of %d...", i+1, len(*recipients)) } else { bytes, err := msg.Bytes() if err != nil { fmt.Printf("Error parsing email: %v", err) } fmt.Printf("%s\n\n\n", string(bytes)) } case err := <-fail: fmt.Fprintln(os.Stderr, "\nError sending email:", err.Error()) os.Exit(2) } } fmt.Println() }
func main() { flag.StringVar(&htmlTemplatePath, "html", "", "html template path") flag.StringVar(&textTemplatePath, "text", "", "text template path") flag.StringVar(&csvPath, "csv", "", "path to csv of contact list") flag.StringVar(&randTemp, "rand", "", "path to json file that descripte which column should pick item from list randomly") flag.StringVar(&smtpURL, "server", "", "url of smtp server") flag.StringVar(&smtpPort, "port", "", "port of smtp server") flag.StringVar(&smtpUser, "user", "", "smtp username") flag.StringVar(&smtpPassword, "password", "", "smtp password") flag.StringVar(&sender, "sender", "", "email to send from") flag.StringVar(&subject, "subject", "", "subject of email") flag.BoolVar(&debug, "debug", false, "print emails to stdout instead of sending") flag.StringVar(&attach, "attach", "", "attach a list of comma separated files") flag.IntVar(&workerCount, "c", 8, "number of concurrent requests to have") flag.IntVar(&freqPerMinute, "freq", 12, "number of requests in x minutes") flag.IntVar(&freqMinutes, "fmin", 1, "number of requests in x minutes, x value") requiredFlagNames := []string{"text", "csv", "server", "port", "user", "password", "sender", "subject"} flag.VisitAll(func(f *flag.Flag) { flags = append(flags, f) for _, name := range requiredFlagNames { if name == f.Name { requiredFlags = append(requiredFlags, f) } } }) flag.Usage = usage flag.Parse() if attach != "" { files = strings.Split(attach, ",") } else { files = []string{} } checkAndHandleMissingFlags(requiredFlags) var throttle <-chan time.Time if freqPerMinute > 0 { throttle = time.Tick(time.Duration((freqMinutes*60*1e6)/freqPerMinute) * time.Microsecond) } csv, err := os.Open(csvPath) if err != nil { fmt.Fprintln(os.Stderr, "Error opening CSV:", err.Error()) os.Exit(2) } defer csv.Close() var randDesc []RandTempDesc if len(randTemp) > 0 { jsonFile, err := os.Open(randTemp) if err != nil { fmt.Fprintln(os.Stderr, "Error opening randTemp:", err.Error()) os.Exit(2) } defer jsonFile.Close() dec := json.NewDecoder(jsonFile) err = dec.Decode(&randDesc) if err != nil { fmt.Fprintln(os.Stderr, "Decode json failed", err.Error()) os.Exit(2) } } recipients, emailField, err := readCSV(csvPath, randDesc) if err != nil { fmt.Fprintln(os.Stderr, "Error reading CSV:", err.Error()) os.Exit(2) } mailer := mail.NewMailer( smtpUser, smtpPassword, smtpURL, smtpPort, ) jobs := make(chan Recipient, len(*recipients)) success := make(chan *email.Email) fail := make(chan error) // Start workers for i := 0; i < workerCount; i++ { go func() { if freqPerMinute > 0 { <-throttle } for recipient := range jobs { sendMail(recipient, *emailField, &mailer, debug, success, fail) } }() } // Send jobs to workers for _, recipient := range *recipients { jobs <- recipient } close(jobs) for i := 0; i < len(*recipients); i++ { select { case msg := <-success: if !debug { log.Printf("\rEmailed recipient %d of %d...", i+1, len(*recipients)) } else { bytes, err := msg.Bytes() if err != nil { log.Printf("Error parsing email: %v", err) } log.Printf("%s\n\n\n", string(bytes)) } log.Println("sending recipient success", msg.To) case err := <-fail: log.Println("\nError sending email:", err.Error()) continue } } fmt.Println() }
func main() { flag.StringVar(&htmlTemplatePath, "html", "", "html template path") flag.StringVar(&textTemplatePath, "text", "", "text template path") flag.StringVar(&csvPath, "csv", "", "path to csv of contact list") flag.StringVar(&smtpURL, "server", "", "url of smtp server") flag.StringVar(&smtpPort, "port", "", "port of smtp server") flag.StringVar(&smtpUser, "user", "", "smtp username") flag.StringVar(&smtpPassword, "password", "", "smtp password") flag.StringVar(&sender, "sender", "", "email to send from") flag.StringVar(&subject, "subject", "", "subject of email") flag.VisitAll(func(f *flag.Flag) { flags = append(flags, f) }) flag.Usage = usage flag.Parse() checkAndHandleMissingFlags(flags) csv, err := os.Open(csvPath) if err != nil { fmt.Fprintln(os.Stderr, "Error opening CSV:", err.Error()) os.Exit(2) } defer csv.Close() recipients, emailField, err := readCSV(csvPath) if err != nil { fmt.Fprintln(os.Stderr, "Error reading CSV:", err.Error()) os.Exit(2) } mailer := mail.NewMailer( smtpUser, smtpPassword, smtpURL, smtpPort, ) success := make(chan Recipient) fail := make(chan error) go func() { for _, recipient := range *recipients { go sendMail(recipient, *emailField, &mailer, success, fail) } }() for i := 0; i < len(*recipients); i++ { select { case <-success: fmt.Printf("\rEmailed recipient %d of %d...", i+1, len(*recipients)) case err := <-fail: fmt.Fprintln(os.Stderr, "\nError sending email:", err.Error()) os.Exit(2) } } fmt.Println() }