Introducción a Gomail

Gomail es un paquete simple y eficiente para enviar correos electrónicos en Golang. Ha sido ampliamente probado y documentado.

Gomail solo puede enviar correos electrónicos utilizando servidores SMTP. Sin embargo, la API es flexible y puede implementar fácilmente métodos como el uso de Postfix local, APIs, etc., para enviar correos electrónicos.

Utiliza gopkg.in para el control de versiones, por lo que no habrá cambios incompatibles dentro de cada versión.

Requiere el uso de Go 1.2 o una versión posterior. En Go 1.5, no se utilizarán dependencias externas.

Características de Gomail

Gomail admite las siguientes características:

  • Archivos adjuntos
  • Imágenes incrustadas
  • Plantillas HTML y de texto
  • Codificación automática de caracteres especiales
  • SSL y TLS
  • Envío de múltiples correos electrónicos utilizando la misma conexión SMTP

Instalación

go get gopkg.in/gomail.v2

Ejemplo

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

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

// Enviar un correo electrónico a Bob, Cora y Dan.
if err := d.DialAndSend(m); err != nil {
    panic(err)
}

Ejemplo (Demonio)

Un demonio que escucha un canal y envía todos los mensajes recibidos.

ch := make(chan *gomail.Message)

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

    var s gomail.SendCloser
    var err error
    abierto := false
    for {
        select {
        case m, ok := <-ch:
            if !ok {
                return
            }
            if !abierto {
                if s, err = d.Dial(); err != nil {
                    panic(err)
                }
                abierto = true
            }
            if err := gomail.Send(s, m); err != nil {
                log.Print(err)
            }
        // Cerrar la conexión al servidor SMTP si no se ha enviado ningún correo en los últimos 30 segundos.
        case <-time.After(30 * time.Second):
            if abierto {
                if err := s.Close(); err != nil {
                    panic(err)
                }
                abierto = false
            }
        }
    }
}()

// Envíe correos electrónicos utilizando este canal en su programa.

// Cerrar el canal para detener el demonio de correo electrónico.
close(ch)

Ejemplo (Suscripción por correo electrónico)

Enviar eficazmente suscripciones de correo electrónico personalizadas a un grupo de destinatarios.

// Lista de destinatarios.
var lista []struct {
    Nombre   string
    Dirección string
}

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

m := gomail.NewMessage()
for _, r := range lista {
    m.SetHeader("From", "[email protected]")
    m.SetAddressHeader("To", r.Dirección, r.Nombre)
    m.SetHeader("Subject", "Boletín #1")
    m.SetBody("text/html", fmt.Sprintf("¡Hola %s!", r.Nombre))

    if err := gomail.Send(s, m); err != nil {
        log.Printf("No se pudo enviar el correo electrónico a %q: %v", r.Dirección, err)
    }
    m.Reset()
}

Ejemplo (Sin autenticación)

Enviar correos electrónicos utilizando un servidor SMTP local.

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

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

Ejemplo (Sin SMTP)

Enviar correos electrónicos usando la API o postfix.

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

s := gomail.SendFunc(func(from string, to []string, msg io.WriterTo) error {
    // Implementa tu función de envío de correo electrónico llamando a una API o ejecutando postfix, etc.
    fmt.Println("From:", from)
    fmt.Println("To:", to)
    return nil
})

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

Preguntas frecuentes

x509: certificado firmado por una autoridad desconocida

Si te encuentras con este error, significa que el cliente que ejecuta Gomail considera inválido el certificado utilizado por el servidor SMTP. Como solución temporal, puedes evitar la validación de la cadena de certificados y el nombre de host del servidor utilizando SetTLSConfig:

package main

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

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

    // Utiliza d para enviar correos electrónicos.
}

Sin embargo, ten en cuenta que esto es inseguro y no debe utilizarse en un entorno de producción.