Go Mail
A cross platform mail driver for GoLang.
Overview
- ✅ Multiple mail drivers for your needs or even create your own custom Mailer.
- ✅ Direct dependency free, all requests are made with the standard lib http.Client.
- ✅ Send attachments with two struct fields, it's extremely simple.
- ✅ Send CC & BCC messages.
- ✅ Extremely lightweight.
Supported API's
Introduction
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)
Installation
go get -u github.com/ainsleyclark/go-mail
Docs
Documentation can be found at the Go Docs, but we have included a
kick-start guide below to get you started.
Creating a new client:
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)
}
Sending Data:
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)
Response:
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:
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,
},
},
}
Examples
Mailgun
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)
Postal
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)
Postmark
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)
SendGrid
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)
SMTP
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)
SparkPost
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)
Writing a Mailable
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)
}
Debugging
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
Development
Setup
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
Env
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.
Testing
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
Contributing
We welcome contributors, but please read the contributing document before making a pull request.
Licence
Code Copyright 2021 Go Mail. Code released under the MIT Licence.