A cross-platform mail driver for GoLang. Featuring Mailgun, Postal, Postmark, SendGrid, SparkPost & SMTP.
Go Mail aims to unify multiple popular mail APIs into a singular, easy to use interface. Email sending is seriously simple and great for allowing the developer or end user to choose what platform they use.
cfg := mail.Config{
URL: "https://api.eu.sparkpost.com",
APIKey: "my-key",
FromAddress: "hello@gophers.com",
FromName: "Gopher",
}
mailer, err := drivers.NewSparkPost(cfg)
if err != nil {
log.Fatalln(err)
}
tx := &mail.Transmission{
Recipients: []string{"hello@gophers.com"},
Subject: "My email",
HTML: "<h1>Hello from Go Mail!</h1>",
}
result, err := mailer.Send(tx)
if err != nil {
log.Fatalln(err)
}
fmt.Printf("%+v\n", result)
go get -u github.com/ainsleyclark/go-mail
Documentation can be found at the Go Docs, but we have included a kick-start guide below to get you started.
You can create a new driver by calling the drivers
package and passing in a configuration type which is required to
create a new mailer. Each platform requires its own data, for example, Mailgun requires a domain, but SparkPost doesn't.
This is based of the requirements for the API. For more details see the examples below.
cfg := mail.Config{
URL: "https://api.eu.sparkpost.com",
APIKey: "my-key",
FromAddress: "hello@gophers.com",
FromName: "Gopher",
Client: http.DefaultClient, // Client is optional
}
mailer, err := drivers.NewSparkpost(cfg)
if err != nil {
log.Fatalln(err)
}
A transmission is required to transmit to a mailer as shown below. Once send is called, a mail.Response
and an error
be returned indicating if the transmission was successful.
tx := &mail.Transmission{
Recipients: []string{"hello@gophers.com"},
CC: []string{"cc@gophers.com"},
BCC: []string{"bcc@gophers.com"},
Subject: "My email",
HTML: "<h1>Hello from Go Mail!</h1>",
PlainText: "Hello from Go Mail!",
Headers: map[string]string{
"X-Go-Mail": "Test",
},
}
result, err := mailer.Send(tx)
if err != nil {
log.Fatalln(err)
}
fmt.Printf("%+v\n", result)
The mail response is used for debugging and inspecting results of the mailer. Below is the Response
type.
// Response represents the data passed back from a successful transmission.
type Response struct {
StatusCode int // e.g. 200
Body []byte // e.g. {"result: success"}
Headers http.Header // e.g. map[X-Ratelimit-Limit:[600]]
ID string // e.g "100"
Message string // e.g "Email sent successfully"
}
Adding attachments to the transmission is as simple as passing a byte slice and filename. Go Mail takes care of the rest for you.
image, err := ioutil.ReadFile("gopher.jpg")
if err != nil {
log.Fatalln(err)
}
tx := &mail.Transmission{
Recipients: []string{"hello@gophers.com"},
Subject: "My email",
HTML: "<h1>Hello from Go Mail!</h1>",
PlainText: "plain text",
Attachments: []mail.Attachment{
{
Filename: "gopher.jpg",
Bytes: image,
},
},
}
cfg := mail.Config{
URL: "https://api.eu.mailgun.net", // Or https://api.mailgun.net
APIKey: "my-key",
FromAddress: "hello@gophers.com",
FromName: "Gopher",
Domain: "my-domain.com",
}
mailer, err := drivers.NewMailgun(cfg)
if err != nil {
log.Fatalln(err)
}
tx := &mail.Transmission{
Recipients: []string{"hello@gophers.com"},
CC: []string{"cc@gophers.com"},
BCC: []string{"bcc@gophers.com"},
Subject: "My email",
HTML: "<h1>Hello from Go Mail!</h1>",
PlainText: "Hello from Go Mail!",
}
result, err := mailer.Send(tx)
if err != nil {
log.Fatalln(err)
}
fmt.Printf("%+v\n", result)
cfg := mail.Config{
URL: "https://postal.example.com",
APIKey: "my-key",
FromAddress: "hello@gophers.com",
FromName: "Gopher",
}
mailer, err := drivers.NewPostal(cfg)
if err != nil {
log.Fatalln(err)
}
tx := &mail.Transmission{
Recipients: []string{"hello@gophers.com"},
CC: []string{"cc@gophers.com"},
BCC: []string{"bcc@gophers.com"},
Subject: "My email",
HTML: "<h1>Hello from Go Mail!</h1>",
PlainText: "Hello from Go Mail!",
}
result, err := mailer.Send(tx)
if err != nil {
log.Fatalln(err)
}
fmt.Printf("%+v\n", result)
cfg := mail.Config{
APIKey: "my-key",
FromAddress: "hello@gophers.com",
FromName: "Gopher",
}
mailer, err := drivers.NewPostmark(cfg)
if err != nil {
log.Fatalln(err)
}
tx := &mail.Transmission{
Recipients: []string{"hello@gophers.com"},
CC: []string{"cc@gophers.com"},
BCC: []string{"bcc@gophers.com"},
Subject: "My email",
HTML: "<h1>Hello from Go Mail!</h1>",
PlainText: "Hello from Go Mail!",
}
result, err := mailer.Send(tx)
if err != nil {
log.Fatalln(err)
}
fmt.Printf("%+v\n", result)
cfg := mail.Config{
APIKey: "my-key",
FromAddress: "hello@gophers.com",
FromName: "Gopher",
}
mailer, err := drivers.NewSendGrid(cfg)
if err != nil {
log.Fatalln(err)
}
tx := &mail.Transmission{
Recipients: []string{"hello@gophers.com"},
CC: []string{"cc@gophers.com"},
BCC: []string{"bcc@gophers.com"},
Subject: "My email",
HTML: "<h1>Hello from Go Mail!</h1>",
PlainText: "Hello from Go Mail!",
}
result, err := mailer.Send(tx)
if err != nil {
log.Fatalln(err)
}
fmt.Printf("%+v\n", result)
cfg := mail.Config{
URL: "smtp.gmail.com",
FromAddress: "hello@gophers.com",
FromName: "Gopher",
Password: "my-password",
Port: 587,
}
mailer, err := drivers.NewSMTP(cfg)
if err != nil {
log.Fatalln(err)
}
tx := &mail.Transmission{
Recipients: []string{"hello@gophers.com"},
CC: []string{"cc@gophers.com"},
BCC: []string{"bcc@gophers.com"},
Subject: "My email",
HTML: "<h1>Hello from Go Mail!</h1>",
PlainText: "Hello from Go Mail!",
}
result, err := mailer.Send(tx)
if err != nil {
log.Fatalln(err)
}
fmt.Printf("%+v\n", result)
cfg := mail.Config{
URL: "https://api.eu.sparkpost.com", // Or https://api.sparkpost.com/api/v1
APIKey: "my-key",
FromAddress: "hello@gophers.com",
FromName: "Gopher",
}
mailer, err := drivers.NewSparkPost(cfg)
if err != nil {
log.Fatalln(err)
}
tx := &mail.Transmission{
Recipients: []string{"hello@gophers.com"},
CC: []string{"cc@gophers.com"},
BCC: []string{"bcc@gophers.com"},
Subject: "My email",
HTML: "<h1>Hello from Go Mail!</h1>",
PlainText: "Hello from Go Mail!",
}
result, err := mailer.Send(tx)
if err != nil {
log.Fatalln(err)
}
fmt.Printf("%+v\n", result)
You have the ability to create your own custom Mailer by implementing the singular method interface shown below.
type Mailer interface {
// Send accepts a mail.Transmission to send an email through a particular
// driver/provider. Transmissions will be validated before sending.
//
// A mail.Response or an error will be returned. In some circumstances
// the body and status code will be attached to the response for debugging.
Send(t *mail.Transmission) (mail.Response, error)
}
To debug any errors or issues you are facing with Go Mail, you are able to change the Debug
variable in the
mail
package. This will write the HTTP requests in curl to stdout. Additional information will also be
displayed in the errors such as method operations.
mail.Debug = true
To get set up with Go Mail simply clone the repo and run the following:
go get github.com/vektra/mockery/v2/.../
make setup
make mocks
All secrets are contained within the .env
file for testing drivers. To begin with, make a copy of the .env.example
file and name it .env
. You can the set the environment variables to match your credentials for the mail drivers.
You can set the recipients of emails by modifying the EMAIL
variables as show below.
EMAIL_TO
: Recipients of test emails in a comma delimited list.EMAIL_CC
: CC recipients of test emails in a comma delimited list.EMAIL_BCC
: BCC recipients of test emails in a comma delimited list.To run all driver tests, execute the following command:
make test-driver
To run a specific driver test, prepend the driver
flag as show below:
make test-driver driver=sparkpost
The driver flag can be one of the following:
mailgun
postal
postmark
sendgrid
smtp
sparkpost
We welcome contributors, but please read the contributing document before making a pull request.
Shout out to the incredible Maria Letta for her excellent Gopher illustrations.
Code Copyright 2022 Go Mail. Code released under the MIT Licence.