# Go Simple Mail The best way to send emails in Go with SMTP Keep Alive and Timeout for Connect and Send. Go Report Card go.dev # IMPORTANT Examples in this README are for v2.2.0 and above. Examples for older versions can be found [here](https://gist.github.com/xhit/54516917473420a8db1b6fff68a21c99). Go 1.13+ is required. Breaking change in 2.2.0: The signature of `SetBody` and `AddAlternative` used to accept strings ("text/html" and "text/plain") and not require on of the `contentType` constants (`TextHTML` or `TextPlain`). Upgrading, while not quite following semantic versioning, is quite simple: ```diff email := mail.NewMSG() - email.SetBody("text/html", htmlBody) - email.AddAlternative("text/plain", plainBody) + email.SetBody(mail.TextHTML, htmlBody) + email.AddAlternative(mail.TextPlain, plainBody) ``` # Introduction Go Simple Mail is a simple and efficient package to send emails. It is well tested and documented. Go Simple Mail can only send emails using an SMTP server. But the API is flexible and it is easy to implement other methods for sending emails using a local Postfix, an API, etc. This package contains (and is based on) two packages by **Joe Grasse**: - https://github.com/joegrasse/mail (unmaintained since Jun 29, 2018), and - https://github.com/joegrasse/mime (unmaintained since Oct 1, 2015). A lot of changes in Go Simple Mail were sent with not response. ## Features Go Simple Mail supports: - Multiple Attachments with path - Multiple Attachments in base64 - Multiple Attachments from bytes (since v2.6.0) - Inline attachments from file, base64 and bytes (bytes since v2.6.0) - Multiple Recipients - Priority - Reply to - Set sender - Set from - Allow sending mail with different envelope from (since v2.7.0) - Embedded images - HTML and text templates - Automatic encoding of special characters - SSL/TLS and STARTTLS - Unencrypted connection (not recommended) - Sending multiple emails with the same SMTP connection (Keep Alive or Persistent Connection) - Timeout for connect to a SMTP Server - Timeout for send an email - Return Path - Alternative Email Body - CC and BCC - Add Custom Headers in Message - Send NOOP, RESET, QUIT and CLOSE to SMTP client - PLAIN, LOGIN and CRAM-MD5 Authentication (since v2.3.0) - Allow connect to SMTP without authentication (since v2.10.0) - Custom TLS Configuration (since v2.5.0) - Send a RFC822 formatted message (since v2.8.0) - Send from localhost (yes, Go standard SMTP package cannot do that because... WTF Google!) - Support text/calendar content type body (since v2.11.0) - Support add a List-Unsubscribe header (since v2.11.0) - Support to add a DKIM signarure (since v2.11.0) ## Documentation https://pkg.go.dev/github.com/xhit/go-simple-mail/v2?tab=doc ## Download This package uses go modules. ```console $ go get github.com/xhit/go-simple-mail/v2 ``` # Usage ```go package main import ( "log" "github.com/xhit/go-simple-mail/v2" "github.com/toorop/go-dkim" ) const htmlBody = ` Hello Gophers!

This is the Go gopher.

Go gopher

Image created by Renee French

` const privateKey = `-----BEGIN RSA PRIVATE KEY----- MIIEpAIBAAKCAQEAwGrscUxi9zEa9oMOJbS0kLVHZXNIW+EBjY7KFWIZSxuGAils wBVl+s5mMRrR5VlkyLQNulAdNemg6OSeB0R+2+8/lkHiMrimqQckZ5ig8slBoZhZ wUoL/ZkeQa1bacbdww5TuWkiVPD9kooT/+TZW1P/ugd6oYjpOI56ZjsXzJw5pz7r DiwcIJJaaDIqvvc5C4iW94GZjwtmP5pxhvBZ5D6Uzmh7Okvi6z4QCKzdJQLdVmC0 CMiFeh2FwqMkVpjZhNt3vtCo7Z51kwHVscel6vl51iQFq/laEzgzAWOUQ+ZEoQpL uTaUiYzzNyEdGEzZ2CjMMoO8RgtXnUo2qX2FDQIDAQABAoIBAHWKW3kycloSMyhX EnNSGeMz+bMtYwxNPMeebC/3xv+shoYXjAkiiTNWlfJ1MbbqjrhT1Pb1LYLbfqIF 1csWum/bjHpbMLRPO++RH1nxUJA/BMqT6HA8rWpy+JqiLW9GPf2DaP2gDYrZ0+yK UIFG6MfzXgnju7OlkOItlvOQMY+Y501u/h6xnN2yTeRqXXJ1YlWFPRIeFdS6UOtL J2wSxRVdymHbGwf+D7zet7ngMPwFBsbEN/83KGLRjkt8+dMQeUeob+nslsQofCZx iokIAvByTugmqrB4JqhNkAlZhC0mqkRQh7zUFrxSj5UppMWlxLH+gPFZHKAsUJE5 mqmylcECgYEA8I/f90cpF10uH4NPBCR4+eXq1PzYoD+NdXykN65bJTEDZVEy8rBO phXRNfw030sc3R0waQaZVhFuSgshhRuryfG9c1FP6tQhqi/jiEj9IfCW7zN9V/P2 r16pGjLuCK4SyxUC8H58Q9I0X2CQqFamtkLXC6Ogy86rZfIc8GcvZ9UCgYEAzMQZ WAiLhRF2MEmMhKL+G3jm20r+dOzPYkfGxhIryluOXhuUhnxZWL8UZfiEqP5zH7Li NeJvLz4pOL45rLw44qiNu6sHN0JNaKYvwNch1wPT/3/eDNZKKePqbAG4iamhjLy5 gjO1KgA5FBbcNN3R6fuJAg1e4QJCOuo55eW6vFkCgYEA7UBIV72D5joM8iFzvZcn BPdfqh2QnELxhaye3ReFZuG3AqaZg8akWqLryb1qe8q9tclC5GIQulTInBfsQDXx MGLNQL0x/1ylsw417kRl+qIoidMTTLocUgse5erS3haoDEg1tPBaKB1Zb7NyF8QV +W1kX2NKg5bZbdrh9asekt0CgYA6tUam7NxDrLv8IDo/lRPSAJn/6cKG95aGERo2 k+MmQ5XP+Yxd+q0LOs24ZsZyRXHwdrNQy7khDGt5L2EN23Fb2wO3+NM6zrGu/WbX nVbAdQKFUL3zZEUjOYtuqBemsJH27e0qHXUls6ap0dwU9DxJH6sqgXbggGtIxPsQ pQsjEQKBgQC9gAqAj+ZtMXNG9exVPT8I15reox9kwxGuvJrRu/5eSi6jLR9z3x9P 2FrgxQ+GCB2ypoOUcliXrKesdSbolUilA8XQn/M113Lg8oA3gJXbAKqbTR/EgfUU kvYaR/rTFnivF4SL/P4k/gABQoJuFUtSKdouELqefXB+e94g/G++Bg== -----END RSA PRIVATE KEY-----` func main() { server := mail.NewSMTPClient() // SMTP Server server.Host = "smtp.example.com" server.Port = 587 server.Username = "test@example.com" server.Password = "examplepass" server.Encryption = mail.EncryptionSTARTTLS // Since v2.3.0 you can specified authentication type: // - PLAIN (default) // - LOGIN // - CRAM-MD5 // - None // server.Authentication = mail.AuthPlain // Variable to keep alive connection server.KeepAlive = false // Timeout for connect to SMTP Server server.ConnectTimeout = 10 * time.Second // Timeout for send the data and wait respond server.SendTimeout = 10 * time.Second // Set TLSConfig to provide custom TLS configuration. For example, // to skip TLS verification (useful for testing): server.TLSConfig = &tls.Config{InsecureSkipVerify: true} // SMTP client smtpClient,err := server.Connect() if err != nil{ log.Fatal(err) } // New email simple html with inline and CC email := mail.NewMSG() email.SetFrom("From Example "). AddTo("xhit@example.com"). AddCc("otherto@example.com"). SetSubject("New Go Email"). SetListUnsubscribe("") email.SetBody(mail.TextHTML, htmlBody) // also you can add body from []byte with SetBodyData, example: // email.SetBodyData(mail.TextHTML, []byte(htmlBody)) // or alternative part // email.AddAlternativeData(mail.TextHTML, []byte(htmlBody)) // add inline email.Attach(&mail.File{FilePath: "/path/to/image.png", Name:"Gopher.png", Inline: true}) // you can add dkim signature to the email. // to add dkim, you need a private key already created one. if privateKey != "" { options := dkim.NewSigOptions() options.PrivateKey = []byte(privateKey) options.Domain = "example.com" options.Selector = "default" options.SignatureExpireIn = 3600 options.Headers = []string{"from", "date", "mime-version", "received", "received"} options.AddSignatureTimestamp = true options.Canonicalization = "relaxed/relaxed" email.SetDkim(options) } // always check error after send if email.Error != nil{ log.Fatal(email.Error) } // Call Send and pass the client err = email.Send(smtpClient) if err != nil { log.Println(err) } else { log.Println("Email Sent") } } ``` ## Send multiple emails in same connection ```go //Set your smtpClient struct to keep alive connection server.KeepAlive = true for _, to := range []string{ "to1@example1.com", "to3@example2.com", "to4@example3.com", } { // New email simple html with inline and CC email := mail.NewMSG() email.SetFrom("From Example "). AddTo(to). SetSubject("New Go Email") email.SetBody(mail.TextHTML, htmlBody) // add inline email.Attach(&mail.File{FilePath: "/path/to/image.png", Name:"Gopher.png", Inline: true}) // always check error after send if email.Error != nil{ log.Fatal(email.Error) } // Call Send and pass the client err = email.Send(smtpClient) if err != nil { log.Println(err) } else { log.Println("Email Sent") } } ``` ## More examples See [example/example_test.go](example/example_test.go).