• Stars
    star
    179
  • Rank 212,805 (Top 5 %)
  • Language
    Go
  • License
    MIT License
  • Created over 3 years ago
  • Updated 10 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

πŸ“§ A cross platform mail driver for GoLang. Featuring Mailgun, Postal, Postmark, SendGrid, SparkPost & SMTP.
Go Mail Logo

made-with-Go Go Report Card Test codecov go.dev reference Twitter Handle

πŸ“§ Go Mail

A cross-platform mail driver for GoLang. Featuring Mailgun, Postal, Postmark, SendGrid, SparkPost & SMTP.

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: "[email protected]",
    FromName:    "Gopher",
}

mailer, err := drivers.NewSparkPost(cfg)
if err != nil {
	log.Fatalln(err)
}

tx := &mail.Transmission{
    Recipients:  []string{"[email protected]"},
    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: "[email protected]",
	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{"[email protected]"},
	CC:         []string{"[email protected]"},
	BCC:        []string{"[email protected]"},
	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{"[email protected]"},
	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: "[email protected]",
	FromName:    "Gopher",
	Domain:      "my-domain.com",
}

mailer, err := drivers.NewMailgun(cfg)
if err != nil {
	log.Fatalln(err)
}

tx := &mail.Transmission{
	Recipients: []string{"[email protected]"},
	CC:         []string{"[email protected]"},
	BCC:        []string{"[email protected]"},
	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: "[email protected]",
	FromName:    "Gopher",
}

mailer, err := drivers.NewPostal(cfg)
if err != nil {
	log.Fatalln(err)
}

tx := &mail.Transmission{
	Recipients: []string{"[email protected]"},
	CC:         []string{"[email protected]"},
	BCC:        []string{"[email protected]"},
	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: "[email protected]",
	FromName:    "Gopher",
}

mailer, err := drivers.NewPostmark(cfg)
if err != nil {
	log.Fatalln(err)
}

tx := &mail.Transmission{
	Recipients: []string{"[email protected]"},
	CC:         []string{"[email protected]"},
	BCC:        []string{"[email protected]"},
	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: "[email protected]",
	FromName:    "Gopher",
}

mailer, err := drivers.NewSendGrid(cfg)
if err != nil {
	log.Fatalln(err)
}

tx := &mail.Transmission{
	Recipients: []string{"[email protected]"},
	CC:         []string{"[email protected]"},
	BCC:        []string{"[email protected]"},
	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: "[email protected]",
	FromName:    "Gopher",
	Password:    "my-password",
	Port:        587,
}

mailer, err := drivers.NewSMTP(cfg)
if err != nil {
	log.Fatalln(err)
}

tx := &mail.Transmission{
	Recipients: []string{"[email protected]"},
	CC:         []string{"[email protected]"},
	BCC:        []string{"[email protected]"},
	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: "[email protected]",
	FromName:    "Gopher",
}

mailer, err := drivers.NewSparkPost(cfg)
if err != nil {
	log.Fatalln(err)
}

tx := &mail.Transmission{
	Recipients: []string{"[email protected]"},
	CC:         []string{"[email protected]"},
	BCC:        []string{"[email protected]"},
	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.

Credits

Shout out to the incredible Maria Letta for her excellent Gopher illustrations.

Licence

Code Copyright 2022 Go Mail. Code released under the MIT Licence.

More Repositories

1

squidge

πŸ–ΌοΈ A FREE Wordpress Plugin to compress and convert images using cwebp, jpegoptim and optipng.
PHP
37
star
2

mesh

A blazingly fast, versatile, pure CSS open source framework with a modular approach to a responsive grid system and a vast amount of utilities. mesh uses wireframing to show you what it could look like, not what it will look like.
SCSS
36
star
3

system-setup

Setup scripts for macOS & Ubuntu. Installing programming languages, IDEs, productivity and communication applications as well as developer tools.
Shell
12
star
4

errors

🫠 A drop-in replacement for Go errors, with some added sugar! Error handling in Go made easy with codes, messages and more. Failure is your domain!
Go
12
star
5

stock-informer

πŸ“ˆ A small and simple DOM detection changer for when you're in desperate need of a new Nvidia graphics card or anything else that tickles your pickle.
Go
12
star
6

ryzentosh

OpenCore 0.7.4 EFI configuration for macOS Monterey 12.01 running on a ASUS Crosshair VII Hero X570 motherboard with an AMD Ryzen 7 5800x.
8
star
7

mogrus

✏️ A Go wrapper for Logrus, Errors and Mongo giving you extremley detailed log reports.
Go
3
star
8

logger

✏️ A Go wrapper for Logrus, Errors, Mongo and Facebook Workplace giving you extremely detailed log reports.
Go
2
star
9

stash

A cross driver cache store (stash) for Redis, MemCached & In-Memory storage.
Go
2
star
10

hackintosh-aorus-master

EFI Folder for Z390 Aorus Master
2
star
11

redigo

πŸ”₯ A Redis client for GoLang featuring Tags with Gob & JSON encoding.
Go
2
star
12

workplace

πŸ‘ An extremely simple Facebook Workplace client for sending transmissions to threads via Go.
Go
2
star
13

scribe-form

Full screen form
TypeScript
1
star
14

updater

Updater for VerbisCMS
Go
1
star
15

snappy

A website screenshot capture tool.
TypeScript
1
star
16

wordpress_theme

A beautiful, elegant & free - WordPress theme
CSS
1
star
17

wordpress-boilerplate

A simple wordpress boilerplate with laravel mix.
PHP
1
star
18

amsc-contact

A contact form plugin for WordPress
PHP
1
star
19

Repeat

A vanilla JS ACF styled repeater, with zero dependancies.
JavaScript
1
star
20

nlp

NLP (Natrual Language Processing) API via the pke (Python Keyphrase Extraction) engine.
Python
1
star
21

html-boilerplate

A versatile php, webpack, npm boilerplate to kick start websites & apps off.
CSS
1
star
22

mesh-site

This is the meshCSS website as found on meshcss.com. Use this repository to have an offline version of the documentation available. If you find errors in the docs, this is the place to report an issue or propose changes via pull-requests.
PHP
1
star