package main import ( "crypto/tls" "fmt" "net/smtp" "strings" ) type Emailer struct { From string SMTP string POP3 string Password string } func (e *Emailer) Send(to, subj, msg string) error { headers := e.headers(to, e.From, subj) body := e.body(headers, msg) smtp, err := e.smtp() if err != nil { return err } defer smtp.Quit() if err := smtp.Mail(e.From); err != nil { return err } if err := smtp.Rcpt(to); err != nil { return err } w, err := smtp.Data() if err != nil { return err } if _, err := w.Write([]byte(body)); err != nil { return err } return w.Close() } func (e *Emailer) headers(to, from, subj string) map[string]string { return map[string]string{ "To": to, "From": from, "Subject": subj, } } func (e *Emailer) body(headers map[string]string, body string) string { b := "" for k, v := range headers { b += fmt.Sprintf("%s: %s\r\n", k, v) } return b + "\r\n" + body } func (e *Emailer) smtp() (*smtp.Client, error) { host := strings.Split(e.SMTP, ":")[0] auth := smtp.PlainAuth("", e.From, e.Password, host) tlsconfig := &tls.Config{ServerName: host} conn, err := tls.Dial("tcp", e.SMTP, tlsconfig) if err != nil { return nil, fmt.Errorf("cannot dial %v: %v", e.SMTP, err) } smtp, err := smtp.NewClient(conn, host) if err != nil { return nil, fmt.Errorf("cannot new client %v: %v", host, err) } if err := smtp.Auth(auth); err != nil { return nil, fmt.Errorf("cannot auth client: %v", err) } return smtp, nil }