Producto

Enviar emails con Golang: Envía correos transaccionales con Go en cuestión de minutos

Hemos lanzado un envoltorio nuevo para Golang que hará más fácil que nunca gestionar los contactos y procesar los emails.
octubre 3, 2025

Si estás creando con Go y necesitas un email fiable para inscripciones, recibos, restablecimiento de contraseñas o alertas, esta guía te muestra el camino más rápido.

Configurarás un remitente, enviarás tu primer mensaje con el Go SDK de Mailjet y aprenderás patrones para plantillas, archivos adjuntos, envíos masivos, webhooks y SMTP.

Se trata de un enfoque de la integración del correo electrónico basado en ejemplos y listo para la producción.

En 2009 Google lanzó un lenguaje llamado Go, a menudo conocido como "Golang". Go se introdujo como un robusto lenguaje de programación del lado del servidor. Desde entonces, nunca ha dejado de cumplir sus promesas con patrones de programación de bajo nivel y potentes estructuras de datos.

A quién va dirigida esta guía

Esta guía está pensada para:

  • Desarrolladores e ingenieros DevOps que desean una solución sencilla y duradera para "enviar emails en Go".
  • Equipos que se preocupan por la entregabilidad, los análisis y la escala sin la complejidad de la gestión por SMTP.

Requisitos previos

Antes de empezar necesitarás:

  • Una cuenta de Mailjet con sus claves de API y secreta.
  • Un email/dominio de remitente validado (se recomienda SPF y DKIM para una llegada a la bandeja de entrada óptima).
  • Go 1.20+ (el SDK admite Go 1.13+) y acceso para establecer variables de entorno.

💡 Consejo profesional: Autentica tu dominio mediante SPF/DKIM para mejorar las tasas de entrega de la bandeja de entrada. Consulta la guía completa de autenticación para ver detalles de configuración y ejemplos.

Inicio rápido: Envía tu primer email con Go (API v3.1)

Vamos a conseguir que envíes correos electrónicos rápidamente utilizando el SDK Go oficial de Mailjet y la API de envíos v3.1.

1. Instalar dependencias y establecer claves de API

Primero instala el SDK Go de Mailjet:

                            

                                go get github.com/mailjet/mailjet-apiv3-go/v4
                            
                        

A continuación configura tus variables de entorno:

                            

                                export MJ_APIKEY_PUBLIC=tu_clave_api
export MJ_APIKEY_PRIVATE=tu_clave_secreta
export SENDER_EMAIL=tu_remitente_verificado@tudominio.com
                            
                        

2. Crea tu primer programa de emails

Crea un archivo main.go con el siguiente código:

                            

                                package main

import (
    "fmt"
    "log"
    "os"

    "github.com/mailjet/mailjet-apiv3-go/v4"
)

func main() {
    mj := mailjet.NewMailjetClient(os.Getenv("MJ_APIKEY_PUBLIC"), os.Getenv("MJ_APIKEY_PRIVATE"))

    msgs := []mailjet.InfoMessagesV31{
        {
            From: &mailjet.RecipientV31{Email: os.Getenv("SENDER_EMAIL"), Name: "Go App"},
            To: &mailjet.RecipientsV31{
                {Email: "recipient@example.com", Name: "Recipient"},
            },
            Subject:  "Hello from Go + Mailjet",
            TextPart: "This is a plain-text fallback.",
            HTMLPart: "<h3>Hello from Go + Mailjet</h3><p>It works.</p>",
        },
    }

    messages := mailjet.MessagesV31{Info: msgs}
    res, err := mj.SendMailV31(&messages)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Printf("Status: %+v\n", res)
}

                            
                        

Por qué funciona

El SDK Go envuelve los puntos finales REST de Mailjet y proporciona un práctico ayudante SendMailV31 que acepta una matriz Messages. Este enfoque te proporciona toda la potencia de la API de Mailjet con una necesidad mínima de código.

Enviar por SMTP en Go (biblioteca estándar)

Si prefieres SMTP o ya utilizas un MTA SMTP, puedes utilizar el servidor SMTP de Mailjet con tus credenciales de API.

                            

                                package main

import (
    "net/smtp"
    "os"
)

func main() {
    host := "in-v3.mailjet.com"
    auth := smtp.PlainAuth("", os.Getenv("MJ_APIKEY_PUBLIC"), os.Getenv("MJ_APIKEY_PRIVATE"), host)

    to := []string{"recipient@example.com"}
    from := "sender@yourdomain.com"
    msg := []byte(
        "To: recipient@example.com\r\n" +
            "From: Go App <sender@yourdomain.com>\r\n" +
            "Subject: SMTP from Go via Mailjet\r\n" +
            "MIME-Version: 1.0\r\n" +
            "Content-Type: text/html; charset=UTF-8\r\n\r\n" +
            "<p>Hello via SMTP</p>",
    )

    // Port 587 (TLS) or 465 (SSL) are common choices
    err := smtp.SendMail(host+":587", auth, from, to, msg)
    if err != nil {
        log.Fatal(err)
    }
}

                            
                        

Notas sobre la configuración de SMTP

  • Host SMTP: in-v3.mailjet.com.
  • Puertos comunes: 587 (TLS) o 465 (SSL).
  • Consideraciones sobre el puerto 25: Puede estar bloqueado por tu ISP o proveedor de la nube.

Para más detalles, consulta la guía de configuración de SMTP.

Personalizar con plantillas y variables

Diseña tu plantilla de email una vez en el panel de Mailjet, y luego pasa un TemplateID y Variables de tu código Go para el contenido dinámico.

                            

                                msgs := []mailjet.InfoMessagesV31{
 {
  From: &mailjet.RecipientV31{Email: os.Getenv("SENDER_EMAIL"), Name: "Go App"},
  To: &mailjet.RecipientsV31{{Email: "destinatario@ejemplo.com", Name: "Tomás"}},
  TemplateID: 123456, // sustitúyelo por el ID de tu plantilla
  TemplateLanguage: true, // activa el lenguaje de plantillas de Mailjet
  Variables: map[string]any{"first_name": "Tomás", "plan": "Pro"},
  Subject: "Te damos la bienvenida, {{var:first_name:\"pasa sin miedo\"}}",
 },
}

                            
                        

Sintaxis de la variable de plantilla

  • Variables de la API: Utiliza {{var:first_name:&quot;default_value&quot;}} para insertar variables de tu llamada a la API.
  • Datos de contacto: Utiliza [[data:property:default]] para los datos almacenados en los contactos de Mailjet.

Para ver más ejemplos de plantillas, consulta este hilo en Stack Overflow.

Adjuntar archivos e imágenes en línea

Envía archivos adjuntos e inserta imágenes en línea en tus emails. El límite de tamaño total de los mensajes es de 15 MB.

                            

                                // Primero lee y codifica en base64 tus archivos, luego:
msgs := []mailjet.InfoMessagesV31{
 {
  From: &mailjet.RecipientV31{Email: os.Getenv("SENDER_EMAIL")},
  To: &mailjet.RecipientsV31{{Email: "destinatario@ejemplo.com"}},
  Subject: "Factura adjunta + logotipo en línea",
  HTMLPart: `<p>¡Gracias por tu compra!</p><img src="cid:logo1" alt="Logotipo de la empresa"/>`,
  Attachments: &[]mailjet.AttachmentV31{
 {
  ContentType: "application/pdf",
  Filename: "factura.pdf",
  Base64Content: &quot;<BASE64_STRING>&quot;, // tu PDF codificado en base64
 },
 },
  InlinedAttachments: &[]mailjet.InlinedAttachmentV31{
 {
  AttachmentV31: mailjet.AttachmentV31{
  ContentType: "image/png",
  Filename: "logo.png",
  Base64Content: &quot;<BASE64_PNG>&quot;, // tu imagen codificada en base64
 },
  ContentID: "logo1", // referenciado en HTML como cid:logo1
 },
 },
 },
}
                            
                        

Mejores prácticas para adjuntar archivos

  • Límite de tamaño: Mantén el tamaño total del mensaje ≤ 15 MB.
  • Envíos masivos de emails: Para mejorar la entregabilidad, considera la posibilidad de enlazar a archivos alojados en lugar de adjuntar archivos grandes.
  • Imágenes en línea: Utiliza el campo ContentID para hacer referencia a las imágenes en tu HTML con la sintaxis cid:.

Envíos masivos (mensajes múltiples)

Envía varios mensajes personalizados en una sola llamada a la API. Cada mensaje se valida de forma independiente, por lo que se enviarán los mensajes correctos aunque alguno falle.

                            

                                msgs := []mailjet.InfoMessagesV31{
 {
  From: &mailjet.RecipientV31{Email: os.Getenv("SENDER_EMAIL")},
  To: &mailjet.RecipientsV31{{Email: "usuario1@ejemplo.com"}},
  Subject: "¡Te damos la bienvenida, usuario 1!",
  HTMLPart: "<p>Hola, usuario 1</p>",
 },
 {
  From: &mailjet.RecipientV31{Email: os.Getenv("SENDER_EMAIL")},
  To: &mailjet.RecipientsV31{{Email: "usuario2@ejemplo.com"}},
  Subject: "¡Te damos la bienvenida, usuario 2!",
  HTMLPart: "<p>Hola, usuario 2</p>",
 },
}

res, err := mj.SendMailV31(&mailjet.MessagesV31{Info: msgs})
if err != nil {
  log.Fatal(err)
}

// Procesa los resultados: Cada mensaje recibe su propio estado e ID
for i, result := range res.ResultsV31 {
  fmt.Printf("Message %d: Status=%s, MessageID=%d\n", i, result.Status, result.To[0].MessageID)
}

                            
                        

La API de envío v3.1 devuelve el estado y los ID de cada mensaje, lo que facilita la correlación de los resultados con tus mensajes originales. Utiliza el MessageID para hacer un seguimiento posterior del estado de la entrega.

Seguimiento de entregas, aperturas y clics (webhooks)

Configura webhooks para recibir notificaciones en tiempo real sobre eventos de correo electrónico como entregas, aperturas, clics, rebotes y bajas.

Configurar webhooks

  1. Registra tu punto de conexión de webhook en el panel de control de Mailjet en «Seguimiento de eventos».
  2. O utiliza programáticamente el punto de conexión de API /v3/REST/eventcallbackurl.

Ejemplo de controlador de webhook

                            

                                package main

import (
  "encoding/json"
  "net/http"
  "log"
)

type MailjetEvent struct {
  Event string `json:"event"`
  Time int64 `json:"time"`
  MessageID int64 `json:"MessageID"`
  Email string `json:"email"`
  URL string `json:"url,omitempty"` // para eventos de clics
  Error string `json:"error,omitempty"` // para eventos de rebotes/errores
}

func webhookHandler(w http.ResponseWriter, r *http.Request) {
  defer r.Body.Close()

  var events []MailjetEvent
  if err := json.NewDecoder(r.Body).Decode(&events); err != nil {
  http.Error(w, "bad request", http.StatusBadRequest)
  return
 }

  // Procesa los eventos (considera el uso de una cola para la producción)
  for _, event := range events {
  switch event.Event {
  case "sent":
  log.Printf("Message %d sent to %s", event.MessageID, event.Email)
  case "open":
  log.Printf("Message %d opened by %s", event.MessageID, event.Email)
  case "click":
  log.Printf("Message %d clicked by %s (URL: %s)", event.MessageID, event.Email, event.URL)
  case "bounce":
  log.Printf("Message %d bounced for %s: %s", event.MessageID, event.Email, event.Error)
 }
 }

  // Devuelve siempre 200 para acusar recibo
  w.WriteHeader(http.StatusOK)
}

func main() {
  http.HandleFunc("/mj/events", webhookHandler)
  log.Fatal(http.ListenAndServe(":8080", nil))
}

                            
                        

Mejores prácticas para webhooks

  • Devolver HTTP 200 rápidamente para acusar recibo.
  • Procesa los eventos de forma asíncrona para evitar tiempos de espera.
  • Gestiona los reintentos: Mailjet reintenta las respuestas no 200 hasta 24 horas.

Para consultar la documentación completa sobre eventos, consulta la guía de la API de seguimiento de eventos.

Aspectos esenciales de la entregabilidad

Aquí tienes tres aspectos esenciales de la entregabilidad que debes tener en cuenta.

1. Autenticación de dominio

Configura la autenticación SPF y DKIM de tu dominio de envío para mejorar la ubicación en la bandeja de entrada y reducir el riesgo de suplantación de identidad (<em>spoofing</em>):

  • Registro SPF: Autoriza a Mailjet a enviar emails en nombre de tu dominio.
  • Firma DKIM: Añade firmas criptográficas para verificar la autenticidad del email.

Sigue la guía completa de autenticación de dominios para obtener instrucciones de configuración paso a paso.

2. Configuración regional

Si tu cuenta de Mailjet está en la infraestructura de EE. UU., configura el SDK para utilizar el punto de conexión de API de EE. UU.:

                            

                                // Para cuentas de la región de EE. UU.
mj := mailjet.NewMailjetClient(apiKey, secretKey)
mj.SetAPIBase("https://api.us.mailjet.com/v3.1/")

                            
                        

3. Configuración SMTP

  • Región por defecto: in-v3.mailjet.com.
  • Puertos recomendados: 587 (TLS) o 465 (SSL).

Consideraciones sobre el cortafuegos: Comprueba el acceso a puertos de tu red; muchos proveedores bloquean el puerto 25.

Solución de problemas comunes

Aquí tienes los problemas más comunes y cómo solucionarlos.

Errores de autenticación (401 unauthorized)

  • Comprueba que tus claves de API están correctamente configuradas en las variables de entorno.
  • Verifica la región de la API: Utiliza api.us.mailjet.com para cuentas de EE. UU., api.mailjet.com para cuentas de la UE.

Errores de validación de contenido (400 bad request)

  • &quot;At least HTMLPart, TextPart or TemplateID must be provided&quot;/&quot;Se debe proporcionar al menos HTMLPart, TextPart o TemplateID&quot;: Asegúrate de incluir el contenido del email o especifica un ID de plantilla.
  • Faltan campos obligatorios: Comprueba que From, To y Subject están correctamente configurados.

Errores de tamaño del mensaje (413 payload too large)

  • Comprueba el tamaño total del mensaje: Mantén los archivos adjuntos y el contenido por debajo de 15 MB en total.
  • Considera alternativas: Para archivos grandes, utiliza enlaces alojados en lugar de archivos adjuntos.

Problemas con los webhooks

  • No se capturan eventos: Asegúrate de que el punto de conexión de tu webhook devuelve el estado HTTP 200.
  • Tiempos de espera de procesamiento demasiado largos: Gestiona el procesamiento de webhooks de forma asíncrona para evitar el bloqueo del mecanismo de reintento de Mailjet.

Preguntas frecuentes

¿Cuál es la forma más rápida de enviar un correo electrónico en Go?

Utiliza el SDK oficial con SendMailV31 como se indica en la sección Inicio rápido. Es una sola llamada a una función una vez que tus claves de API están configuradas.

¿Puedo enviar emails utilizando SMTP en lugar de la API?

Sí. Apunta el paquete net/smtp de Go a in-v3.mailjet.com utilizando tu clave de API y tu clave secreta como credenciales, con el puerto 587 o 465.

¿Cómo personalizo las plantillas de correo electrónico?

Establece TemplateID, activa TemplateLanguage: true, y pasa tus datos en el campo Variables. Utiliza la sintaxis {{var:name:»por defecto»}} en tus plantillas.

¿Dónde puedo ver las métricas de entrega e interacción?

Utiliza webhooks para obtener datos de eventos en tiempo real, o consulta el panel de control de Mailjet y los puntos de conexión de estadísticas de la API REST para obtener métricas agregadas.

Próximos pasos

Ahora que ya funciona el envío de emails en tu aplicación Go, considera estas mejoras:

  1. Asegura tu reputación de remitente: Autentica tu dominio con registros SPF y DKIM.
  2. Añade seguimiento de eventos: Implementa webhooks para potenciar los análisis y los flujos de trabajo automatizados.
  3. Explora las funciones avanzadas: Echa un vistazo a URLTags y SandboxMode para pruebas en la documentación de la API de envío v3.1.
  4. Consulta más ejemplos: Visita el repositorio del SDK Go para ver patrones y casos de uso adicionales.

Con esta base estarás listo para crear una funcionalidad de correo electrónico sólida y adaptable en tus aplicaciones Go. La combinación de la fiable infraestructura de Mailjet y el rendimiento de Go constituye una potente solución de email.