Introduction to Gomail

Gomail is a simple and efficient package for sending emails in Golang. It has been thoroughly tested and documented.

Gomail can only send emails using SMTP servers. However, the API is flexible and can easily implement methods such as using local Postfix, APIs, etc., to send emails.

It uses gopkg.in for version control, so there will be no incompatible changes within each version.

It requires the use of Go 1.2 or a later version. In Go 1.5, external dependencies will not be used.

Features of Gomail

Gomail supports the following features:

  • Attachments
  • Inline images
  • HTML and text templates
  • Automatic encoding of special characters
  • SSL and TLS
  • Sending multiple emails using the same SMTP connection

Installation

go get gopkg.in/gomail.v2

Example

m := gomail.NewMessage()
m.SetHeader("From", "[email protected]")
m.SetHeader("To", "[email protected]", "[email protected]")
m.SetAddressHeader("Cc", "[email protected]", "Dan")
m.SetHeader("Subject", "Hello!")
m.SetBody("text/html", "Hello <b>Bob</b> and <i>Cora</i>!")
m.Attach("/home/Alex/lolcat.jpg")

d := gomail.NewDialer("smtp.example.com", 587, "user", "123456")

// Send an email to Bob, Cora, and Dan.
if err := d.DialAndSend(m); err != nil {
    panic(err)
}

Example (Daemon)

A daemon that listens to a channel and sends all received messages.

ch := make(chan *gomail.Message)

go func() {
    d := gomail.NewDialer("smtp.example.com", 587, "user", "123456")

    var s gomail.SendCloser
    var err error
    open := false
    for {
        select {
        case m, ok := <-ch:
            if !ok {
                return
            }
            if !open {
                if s, err = d.Dial(); err != nil {
                    panic(err)
                }
                open = true
            }
            if err := gomail.Send(s, m); err != nil {
                log.Print(err)
            }
        // Close the connection to the SMTP server if no email has been sent in the last 30 seconds.
        case <-time.After(30 * time.Second):
            if open {
                if err := s.Close(); err != nil {
                    panic(err)
                }
                open = false
            }
        }
    }
}()

// Send emails using this channel in your program.

// Close the channel to stop the email daemon.
close(ch)

Example (Email Subscription)

Effectively send customized email subscriptions to a group of recipients.

// List of recipients.
var list []struct {
    Name    string
    Address string
}

d := gomail.NewDialer("smtp.example.com", 587, "user", "123456")
s, err := d.Dial()
if err != nil {
    panic(err)
}

m := gomail.NewMessage()
for _, r := range list {
    m.SetHeader("From", "[email protected]")
    m.SetAddressHeader("To", r.Address, r.Name)
    m.SetHeader("Subject", "Newsletter #1")
    m.SetBody("text/html", fmt.Sprintf("Hello %s!", r.Name))

    if err := gomail.Send(s, m); err != nil {
        log.Printf("Could not send email to %q: %v", r.Address, err)
    }
    m.Reset()
}

Example (No authentication)

Send emails using a local SMTP server.

m := gomail.NewMessage()
m.SetHeader("From", "[email protected]")
m.SetHeader("To", "[email protected]")
m.SetHeader("Subject", "Hello!")
m.SetBody("text/plain", "Hello!")

d := gomail.Dialer{Host: "localhost", Port: 587}
if err := d.DialAndSend(m); err != nil {
    panic(err)
}

Example (No SMTP)

Send emails using API or postfix.

m := gomail.NewMessage()
m.SetHeader("From", "[email protected]")
m.SetHeader("To", "[email protected]")
m.SetHeader("Subject", "Hello!")
m.SetBody("text/plain", "Hello!")

s := gomail.SendFunc(func(from string, to []string, msg io.WriterTo) error {
    // Implement your email sending function by calling an API or running postfix, etc.
    fmt.Println("From:", from)
    fmt.Println("To:", to)
    return nil
})

if err := gomail.Send(s, m); err != nil {
    panic(err)
}

FAQ

x509: certificate signed by unknown authority

If you encounter this error, it means the client running Gomail considers the certificate used by the SMTP server to be invalid. As a workaround, you can bypass the validation of the server's certificate chain and hostname by using SetTLSConfig:

package main

import (
	"crypto/tls"
	
	"gopkg.in/gomail.v2"
)

func main() {
	d := gomail.NewDialer("smtp.example.com", 587, "user", "123456")
	d.TLSConfig = &tls.Config{InsecureSkipVerify: true}

    // Use d to send emails.
}

However, please note that this is insecure and should not be used in a production environment.