Cómo enviar emails en Python: Métodos SMTP y API de email explicados

On febrero 11, 2025
26min read
Aleksandr Varnin Full Stack Developer @ Railsware
Veljko Ristić Content Manager @ Mailtrap
How to Send an Email in Python

Este artículo cubre todo lo que necesita saber sobre el envío de emails en Python, incluyendo ejemplos de código, seguridad y pruebas de email.

Si tiene smtplib configurado, vaya directamente a enviar usando SMTP o enviar usando API de email.

¿Listo para enviar sus emails?
Pruebe Mailtrap Gratis

Configurando ‘smtplib’

El módulo ‘smtplib’ de Python simplifica el proceso de enviar emails directamente desde sus aplicaciones, ofreciendo una interfaz sencilla para interactuar con servidores SMTP.

Esta sección lo guía a través de la importación de ‘smtplib’, la creación de un objeto SMTP para su servidor y el aprovechamiento de sus funciones principales para enviar emails. Continúe leyendo para aprender cómo integrar funcionalidades de email en sus scripts de Python.

El módulo incorporado smtplib se puede importar utilizando la siguiente declaración:

import smtplib

Para enviar un email más adelante, cree un objeto SMTP (Protocolo Simple de Transferencia de email):

smtpObj = smtplib.SMTP( [host [, port]] )

Detalles de los parámetros:

  • host − este es un argumento opcional y es el host que ejecuta su servidor SMTP. Se puede especificar la dirección IP del host o un nombre de dominio.
  • port − si se especifica el argumento host, especifique un puerto, donde el servidor SMTP está escuchando.
  • local_hostname − si el servidor SMTP utilizado se está ejecutando en su máquina local, específica localhost.

Un objeto SMTP tiene un método de instancia llamado sendmail que se utiliza para enviar un mensaje y tiene tres parámetros:

  • sender − string con la dirección del remitente.
  • receivers − lista de strings, una para cada destinatario.
  • message − un mensaje como un string formateado como se especifica en los RFC.
smtpObj.sendmail(sender, receivers, message)

Para asegurarse de que el módulo de email ha sido importado correctamente y obtener la descripción completa de sus clases y argumentos, escriba en una sesión interactiva de Python:

help(smtplib)

Consulte la documentación de Python para revisar más a fondo el resto de los objetos SMTP (por ejemplo, smtp.ehlo; smtp.send message(msg), etc.) y cómo aplicarlos.

La siguiente sección le indica cómo enviar emails a través de Python utilizando Email API/SMTP de Mailtrap, una característica de la Plataforma de Email Delivery de Mailtrap. Primero, cubriré el método SMTP y luego le mostraré cómo hacerlo con nuestro SDK de Python.

Enviar emails usando SMTP

El método es muy similar a lo que expliqué en la sección de ‘smtplib’, sin embargo, necesita configurar credenciales SMTP personalizadas. Aquí, asumo que ya se registró en Mailtrap y verificó su dominio.

Si no es así, consulte nuestra guía detallada.

Asegúrese también de revisar nuestras instrucciones en video sobre cómo enviar emails en Python con Mailtrap usando smtplib.

Nota: El código a continuación contiene credenciales de Mailtrap de prueba (excepto el endpoint del servidor), asegúrese de reemplazarlas con sus credenciales reales.

Aquí le presentamos un script básico para enviar emails de “texto plano” con Python usando SMTP de Mailtrap.

import smtplib
from email.mime.text import MIMEText

# Configuración
port = 587
smtp_server = "live.smtp.mailtrap.io"
login = "api"  # Su usuario generado por Mailtrap
password = "1a2b3c4d5e6f7g"  # Su contraseña generada por Mailtrap

sender_email = "mailtrap@ejemplo.com"  
receiver_email = "nuevo@ejemplo.com"

# Contenido de texto plano
text = """\
Hola, 
Eche un vistazo a la nueva publicación en el blog de Mailtrap: 
SMTP Server for Testing: Cloud-based or Local?
https://mailtrap.io/es/blog/cloud-or-local-smtp-server/
¡Siéntase libre de hacernos saber qué contenido le sería útil!
"""

# Cree objeto MIMEText
message = MIMEText(text, "plain")
message["Subject"] = "Email de texto plano"
message["From"] = sender_email
message["To"] = receiver_email

# Enviar el email
with smtplib.SMTP(smtp_server, port) as server:
    server.starttls()  # Asegurar la conexión
    server.login(login, password)
    server.sendmail(sender_email, receiver_email, message.as_string())

print('Enviado')

Resumen rápido:

  • Importaciones y configuración – He importado los módulos necesarios de la biblioteca estándar de Python para el envío de emails (‘smtplib’ y ‘MIMEText’).
  • Configuración del servidor de email – Los detalles del servidor SMTP, incluyendo la dirección del servidor, el número de puerto y las credenciales de autenticación.
  • Contenido del email – He creado un mensaje MIMEText que puede contener solo texto plano. Más adelante, le mostraré cómo incluir versiones HTML y de texto plano del email.
  • Envío del email – He usado un gestor de contexto (declaración with) para garantizar que la conexión al servidor SMTP se cierre correctamente después de enviar el email.

Consejo adicional: Codifique información confidencial como credenciales de inicio de sesión e información del servidor directamente en su script puede representar un riesgo de seguridad. Por eso, le recomiendo usar variables de entorno para almacenar información confidencial. Esto hace que su código sea más seguro y flexible al moverse entre diferentes entornos (desarrollo, pruebas, producción).

Enviar un email HTML

Si quiere aprender más sobre el envío de emails HTML en Python, consulte nuestro tutorial dedicado.

Para modificar el script y enviar emails HTML (mientras se incluyen varios destinatarios), ajustaré cómo se crea y adjunta el cuerpo del email. Aquí está el script revisado:

import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart

# Configuración
port = 587
smtp_server = "live.smtp.mailtrap.io"  
login = "api" # Su usuario generado por Mailtrap
password = "1a2b3c4d5e6f7g" # Su contraseña generada por Mailtrap
  
sender_email = "mailtrap@ejemplo.com"
receiver_email = "nuevo1@ejemplo.com"

# Contenido del email  
subject = "Email HTML sin adjunto"
html = """\
<html>
  <body>
    <p>Hola,<br>  
    Este es un email de <b>prueba</b> sin adjunto enviado usando <a href="https://www.python.org">Python</a>.</p>
  </body>
</html>
"""

# Cree un mensaje multiparte y establecer encabezados
message = MIMEMultipart()
message["From"] = sender_email
message["To"] = receiver_email
message["Subject"] = subject

# Adjuntar la parte HTML  
message.attach(MIMEText(html, "html"))

# Enviar el email
with smtplib.SMTP(smtp_server, port) as server:
    server.starttls()
    server.login(login, password)
    server.sendmail(sender_email, receiver_email, message.as_string())

print('Enviado')

Resumen rápido:

  • Adjuntar el contenido HTML – El contenido HTML se adjunta al mensaje de email usando ‘MIMEText(html, “html”)’ en lugar de ‘MIMEText (text, “plain”)’. Al especificar html como el segundo argumento, informamos al cliente de email que esta parte del email debe interpretarse como HTML.

Enviar email a varios destinatarios

Aquí, reutilizaré el script anterior y ajustaré cómo se manejan las direcciones de los destinatarios.

import smtplib
from email.mime.text import MIMEText

# Configuración
port = 587
smtp_server = "live.smtp.mailtrap.io"
login = "api"  # Su usuario generado por Mailtrap  
password = "1a2b3c4d5e6f7g" # Su contraseña generada por Mailtrap

sender_email = "mailtrap@ejemplo.com"
# Lista de direcciones de email de destinatarios  
receiver_emails = ["nuevo1@ejemplo.com", "nuevo2@ejemplo.com", "nuevo3@ejemplo.com"]

# Contenido de texto plano
text = """\
Hola,
Eche un vistazo a la nueva publicación en el blog de Mailtrap:
SMTP Server para pruebas: Cloud-based or Local? 
https://mailtrap.io/es/blog/cloud-or-local-smtp-server/
¡Siéntase libre de hacernos saber qué contenido le sería útil! 
"""

# Cree objeto MIMEText
message = MIMEText(text, "plain")
message["Subject"] = "Email de texto plano"
message["From"] = sender_email
# Unir la lista de emails de destinatarios en una string (lista) separada por comas  
message["To"] = ", ".join(receiver_emails)

# Enviar el email
with smtplib.SMTP(smtp_server, port) as server:
    server.starttls()  # Secure the connection
    server.login(login, password)
    # Recorrer cada destinatario y enviar el email individualmente
    for recipient in receiver_emails:
        server.sendmail(sender_email, recipient, message.as_string())

print('Enviado')

Resumen rápido de lo que es diferente del script original de “texto plano”:

  • Configuración de varios destinatarios – Cambié la variable receiver_email a receiver_emails. Ahora es una lista de direcciones de email en lugar de un solo string (una sola lista).
  • Configuración del encabezado To – El encabezado To en el objeto de mensaje MIMEText se establece uniendo la lista de emails de destinatarios en una sola lista separada por comas. Esto es importante para que el encabezado del email muestre correctamente a todos los destinatarios cuando reciban el email.
    • Nota: Algunos clientes de email (Outlook, Yahoo, Gmail, etc.) pueden mostrar a todos los destinatarios en el campo To a cada destinatario, lo que no es deseable por razones de privacidad. Puede “solucionarlo” usando CC y/o BCC.
  • Envío de emails en bucle – En lugar de enviar el email una vez, el script ahora recorre cada destinatario en la lista receiver_emails y les envía el email individualmente.

Consejo profesional: ⬆️ Este enfoque funciona bien para un pequeño número de destinatarios. Sin embargo, para enviar emails a un gran número de destinatarios, puede ser más eficiente utilizar la capacidad del servidor SMTP de manejar varios destinatarios en una sola operación de envío, dependiendo de las limitaciones y políticas del servidor.

Enviar email con archivos adjuntos

Usaré MIMEMultipart ya que los adjuntos requieren un email multiparte. Además, utilizaré la clase MIMEBase para adjuntar archivos. Aquí está el script actualizado:

import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
from email import encoders

# Configuración
port = 587
smtp_server = "live.smtp.mailtrap.io"
login = "api"  # Su usuario generado por Mailtrap
password = "1a2b3c4d5e6f7g" # Su contraseña generada por Mailtrap

sender_email = "mailtrap@ejemplo.com"  
receiver_email = "nuevo@ejemplo.com" # Destinatario único

# Contenido del email
subject = "Email con adjunto"  
body = "Hola,\nEste es un email de prueba con adjunto."

# Cree un mensaje multiparte y establecer encabezados
message = MIMEMultipart()
message["From"] = sender_email
message["To"] = receiver_email
message["Subject"] = subject

# Agregar cuerpo al email
message.attach(MIMEText(body, "plain"))

# Especificar la ruta del archivo adjunto  
filename = "ruta/a/su/archivo.pdf" # Cambie esto a la ruta correcta

# Abrir el archivo en modo binario  
with open(filename, "rb") as attachment:
    part = MIMEBase("application", "octet-stream")
    part.set_payload(attachment.read())

# Codifique el archivo en caracteres ASCII para enviarlo por email
encoders.encode_base64(part)

# Agregar encabezado como par clave/valor a la parte del adjunto
part.add_header("Content-Disposition", f"attachment; filename= {filename}")

# Agregar archivo adjunto al mensaje 
message.attach(part)

# Enviar el email
with smtplib.SMTP(smtp_server, port) as server:
    server.starttls()
    server.login(login, password)
    server.sendmail(sender_email, receiver_email, message.as_string())

print('Enviado')

Resumen rápido:

  • Uso de MIMEMultipart – Pasé de MIMEText para el cuerpo a MIMEMultipart para la estructura general del mensaje. Esto nos permite agregar tanto la parte de texto como el adjunto como partes separadas del email.
  • Agregar el adjunto:
    • Preparación del archivo – El archivo adjunto se abre en modo binario rb, y se lee su contenido.
    • Objeto MIMEBase – Se crea un objeto MIMEBase para el adjunto, con el tipo establecido en application/octet-stream. Este tipo es un flujo binario genérico, lo que significa que es adecuado para cualquier tipo de archivo, y los clientes de email normalmente lo tratarán como un adjunto.
    • Codificación – El contenido del archivo se codifica en base64 para garantizar que se pueda transmitir de manera segura por email. Esto se hace usando la función encoders.encode_base64(part).
    • Agregar encabezados – Se agrega un encabezado a la parte del adjunto para indicar el nombre del archivo y que debe tratarse como un adjunto (encabezado Content-Disposition).
    • Adjuntar el archivo al mensaje – La parte del adjunto se adjunta luego al mensaje usando message.attach(part).

Enviar un email con una imagen incrustada

Para enviar emails con una imagen incrustada (en el contenido HTML), usaré la clase MIMEImage.

Incrustar una imagen directamente en el email permite que se muestre como parte del contenido del email en lugar de como un archivo adjunto separado. Así es como puede hacerlo:

import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.image import MIMEImage
from email.mime.base import MIMEBase
from email import encoders
import os

# Configuración
port = 587
smtp_server = "live.smtp.mailtrap.io"
login = "api"  # Su usuario generado por Mailtrap
password = "1a2b3c4d5e6f7g"  # Su contraseña generada por Mailtrap

sender_email = "mailtrap@ejemplo.com"
receiver_email = "nuevo1@ejemplo.com"

# Contenido HTML con una imagen incrustada
html = """\
<html>
  <body>
    <p>Hola,<br>
    Este es un email de <b>prueba</b> con una imagen incrustada.<br>
    Aquí hay una imagen: <img src="cid:image1">.</p>
  </body>
</html>
"""

# Cree un mensaje multiparte y establecer encabezados
message = MIMEMultipart()
message["From"] = sender_email
message["To"] = receiver_email
message["Subject"] = "Email HTML con imagen incrustada"

# Adjuntar la parte HTML
message.attach(MIMEText(html, "html"))

# Especificar la ruta a su imagen
image_path = "ruta/a/su/imagen.jpg"  # Cambie esto a la ruta correcta

# Abrir el archivo de imagen en modo binario
with open(image_path, 'rb') as img:
    # Adjuntar el archivo de imagen
    msg_img = MIMEImage(img.read(), name=os.path.basename(image_path))
    # Definir el encabezado Content-ID para usar en el cuerpo HTML
    msg_img.add_header('Content-ID', '<image1>')
    # Adjuntar la imagen al mensaje
    message.attach(msg_img)

# Enviar el email
with smtplib.SMTP(smtp_server, port) as server:
    server.starttls()
    server.login(login, password)
    server.sendmail(sender_email, receiver_email, message.as_string())

print('Enviado')

Resumen rápido:

  • Actualización del contenido HTML: El contenido HTML ahora incluye una etiqueta <img> con un atributo src que apunta al Content-ID (cid) de la imagen que desea incrustar. Este cid debe coincidir con el valor del encabezado Content-ID del adjunto de imagen.
  • Incrustar la imagen:
    • Usando MIMEImage – El script ahora incluye la clase MIMEImage para manejar el archivo de imagen. Esta clase está diseñada específicamente para adjuntar imágenes a los emails.
    • Abrir archivo de imagen – La imagen que desea incrustar se abre en modo binario.
    • Cree objeto MIMEImage – Los datos binarios de la imagen se utilizan para crear un objeto MIMEImage. Este objeto representa el adjunto de imagen.
    • Encabezado Content-ID – Al objeto MIMEImage se le asigna un encabezado Content-ID, al que se hace referencia mediante el atributo src en la etiqueta <img> del contenido HTML. Este vínculo es lo que permite al cliente de email incrustar la imagen directamente en el cuerpo del email en lugar de mostrarla como un archivo adjunto descargable.
    • Adjuntar la imagen – El objeto MIMEImage se adjunta al mensaje multiparte, de manera similar a como se adjuntan otras partes.

Envío asincrónico de emails

Para el envío asincrónico de emails, necesita usar la librería asyncio de Python junto con aiosmtplib, un cliente SMTP asincrónico.

Esta modificación permite que su script envíe emails sin bloquear la ejecución de su programa, haciéndolo más eficiente, especialmente cuando se envían múltiples emails o se realizan otras tareas simultáneamente.

Para simplificar, enviaré un email de texto/plano a un solo destinatario sin adjuntos ni imágenes incrustadas. Así es cómo funciona.

Primero, asegúrese de instalar aiosmtplib.

pip install aiosmtplib

Ahora, aquí está el script:

import asyncio
from email.mime.text import MIMEText
from aiosmtplib import SMTP

async def send_email_async(sender_email, receiver_email, smtp_server, port, login, password, subject, body):
    message = MIMEText(body)
    message["From"] = sender_email
    message["To"] = receiver_email
    message["Subject"] = subject
    
    async with SMTP(hostname=smtp_server, port=port) as smtp:
        await smtp.connect()
        await smtp.starttls()
        await smtp.login(login, password)
        await smtp.send_message(message)

async def main():
    # Configuración del email
    smtp_server = "live.smtp.mailtrap.io"
    port = 587
    sender_email = "mailtrap@ejemplo.com"
    receiver_email = "nuevo@ejemplo.com"  # Destinatario único 
    login = "api"  # Su usuario generado por Mailtrap
    password = "1a2b3c4d5e6f7g"  # Su contraseña generada por Mailtrap
    subject = "Email asincrónico de prueba"
    body = "Este es un email de texto plano enviado de forma asincrónica."
    
    await send_email_async(sender_email=sender_email, receiver_email=receiver_email, smtp_server=smtp_server, port=port, login=login, password=password, subject=subject, body=body)
    print("Email enviado de forma asincrónica.")

if __name__ == "__main__":
    asyncio.run(main())

Resumen rápido:

  • Definición de función asincrónica: El script ahora define funciones asincrónicas usando async def.
  • Funcionalidad asincrónica: Utilizando asyncio y aiosmtplib, el script establece una conexión SMTP de forma asincrónica, inicia sesión y envía el email. Este enfoque permite el envío de emails de manera libre de bloqueos, lo cual es particularmente útil en aplicaciones que requieren mantener la capacidad de respuesta mientras se realizan operaciones de red.
  • Ejecución del script: La función asincrónica main configura los detalles del email y llama a send_email_async para enviar el email. Demuestra cómo ejecutar tareas asincrónicas en Python de manera efectiva, con asyncio.run(main()) iniciando la ejecución asincrónica.

Envío de emails masivos

El código anterior usa live.smtp.mailtrap.io, que es el endpoint para emails transaccionales. Pero el paquete de email de Mailtrap Email Delivery Platform te permite enviar emails masivos a través de un flujo separado bulk.smtp.mailtrap.io bajo el mismo plan.

Configuración de flujo masivo de Mailtrap

Ahora, lo único diferente es el Host (endpoint), y tendría que ajustar su script a eso. Pero tenga en cuenta que los emails transaccionales y masivos tienen infraestructuras separadas, aunque sus credenciales sean casi las mismas. Eso ayuda a mejorar la entregabilidad y la gestión de emails.

Para ilustrar los cambios, creé un script simple usando el endpoint SMTP proporcionado.

import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart

# Configuración para el servidor SMTP masivo de Mailtrap
smtp_server = "bulk.smtp.mailtrap.io"  
port = 587
login = "api"  # Su usuario de Mailtrap
password = "1a2b3c4d5e6f7g"  # Su contraseña de Mailtrap

sender_email = "mailtrap@ejemplo.com"
receiver_email = "nuevo@ejemplo.com"  # Destinatario único

# Cree un mensaje MIMEText para texto plano  
subject = "Email de texto plano vía SMTP masivo"
body = "Este es un email de texto plano enviado a través del servidor SMTP masivo de Mailtrap."

# Cree un mensaje MIMEMultipart y establezca encabezados
message = MIMEMultipart()
message["From"] = sender_email
message["To"] = receiver_email
message["Subject"] = subject

# Adjuntar la parte de texto
message.attach(MIMEText(body, "plain"))

# Enviar el email
with smtplib.SMTP(smtp_server, port) as server:
    server.starttls()  # Asegurar la conexión
    server.login(login, password)  # Iniciar sesión en el servidor SMTP
    server.sendmail(sender_email, receiver_email, message.as_string())  # Enviar el email

print('Email enviado con éxito.')

Resumen rápido:

  • Uso de MIMEMultipart: Aunque el email es de texto plano y se envía a un solo destinatario, he conservado el uso de MIMEMultipart. Este enfoque ofrece flexibilidad si decide agregar adjuntos o contenido HTML en el futuro. Sin embargo, podría simplificarse aún más usando solo MIMEText.
  • Envío del email: La llamada a server.sendmail es sencilla, especificando el remitente, el destinatario y convirtiendo el objeto de mensaje a formato de string (lista) para enviarlo.

Consejo profesional: Si está usando variables de entorno o un archivo de configuración externo para las credenciales SMTP, es mejor tener archivos separados para la configuración transaccional y masiva.

Enviar emails usando API de email

Para hacer que su integración sea más sencilla, Mailtrap tiene un SDK oficial de Python (consulta el enlace de GitHub ◀️). Lo usaré para mostrarle cómo enviar un email de texto plano, enviarlo a múltiples destinatarios, enviar emails masivos, etc.

Aquí no cubriré el método de envío de emails asincrónico ya que Mailtrap no lo soporta y no es algo que tenga mucho sentido en los contextos de API.

Como recordatorio, necesitará conectar y verificar su dominio con Mailtrap. Consulta nuestra guía detallada y un video instructivo adicional sobre cómo hacer esto.

Una vez que haya hecho eso, regrese a su aplicación de Python e instale el SDK oficial de Python de Mailtrap con el siguiente comando:

pip install mailtrap

Nota: asegúrese de que la versión del paquete sea la 3.6+ o superior.

Luego debe crear el objeto de email y completar las variables (como email y nombre) con sus credenciales de Mailtrap. Tenga en cuenta que debe indicar la dirección con el dominio de envío verificado.

import mailtrap as mt

# cree el objeto de email
mail = mt.Mail(
    sender=mt.Address(email="mailtrap@ejemplo.com", name="Prueba Mailtrap"),  
    to=[mt.Address(email="su@email.com")],
    subject="Usted es increíble!",
    text="¡Felicidades por enviar un email de prueba con Mailtrap",
)

# cree el cliente y envíe
client = mt.MailtrapClient(token="su-clave-api")
client.send(mail)

También necesitará crear el cliente con su token de API. Vaya a su cuenta de Mailtrap expandiendo el menú desplegable “Settings”, luego elija la pestaña “API Tokens”. Copie las credenciales presionando “Copy” junto a su token.

Luego, puede usar el siguiente comando para enviar el email.

# Cree el cliente y envíe
client = mt.MailtrapClient(token="su-clave-api")
client.send(mail)

Dicho esto, procederé a mostrarte cómo aprovechar el SDK para diferentes casos de uso.

Aquí hay un script básico para enviar un email de texto plano:

from mailtrap import Mail, Address, MailtrapClient

# Cree un objeto Mail con detalles básicos para un email de texto plano
mail = Mail(
    # Especificar la dirección de email del remitente y el nombre opcional
    sender=Address(email="mailtrap@ejemplo.com", name="Prueba Mailtrap"),
    # Especificar uno o más destinatarios; aquí usamos una lista con un solo destinatario
    to=[Address(email="su@email.com", name="su nombre")],
    # Asunto del email
    subject="Email de texto plano simple",
    # El contenido de texto plano del email
    text="Este es un email de texto plano enviado usando el SDK de Mailtrap. Simple y directo.",
    # Opcional: categorize este email para una clasificación o gestión más fácil en el servicio Mailtrap
    category="Prueba",
    # Opcional: Se pueden especificar encabezados adicionales, pero no son necesarios para emails de texto plano
    headers={"X-Ejemplo-Encabezado": "HeaderValue"}
)

# Iniciar el MailtrapClient con su token de API
client = MailtrapClient(token="su-clave-api")

# Enviar el email usando el método send del cliente
client.send(mail)

print("Email de texto plano enviado con éxito.")

Resumen rápido:

  • Importar clases: Solo se importan las clases Mail, Address y MailtrapClient de la biblioteca Mailtrap, ya que nos enfocamos en enviar un email de texto plano simple.
  • Creación del objeto Mail:
    • El constructor Mail se utiliza para crear un objeto de email.
    • sender – Utiliza la clase Address para definir el email y el nombre del remitente.
    • to – Una lista de objetos Address para cada destinatario. Para emails de texto plano, normalmente tiene uno o más destinatarios directos enumerados aquí.
    • subject – La línea de asunto del email.
    • text – El contenido real del email, en formato de texto plano.
    • category y headers – Campos opcionales que permiten una categorización adicional y encabezados personalizados. Aunque no son estrictamente necesarios para enviar un email de texto plano, pueden ser útiles para fines organizativos o técnicos dentro del servicio Mailtrap o para el manejo del cliente de email.
  • Enviar el email:
    • Se crea una instancia de MailtrapClient y se autentica con un token de API.
    • Luego se llama al método send del MailtrapClient, pasando el objeto mail como argumento para enviar el email.
    • Finalmente, se imprime un mensaje de confirmación para indicar que el email ha sido enviado.

Enviar un email HTML

Ajustaré el script especificando el parámetro html en el objeto Mail con el contenido HTML.

from mailtrap import Mail, Address, MailtrapClient

# Cree un objeto Mail para enviar un email HTML
mail = Mail(
    sender=Address(email="mailtrap@ejemplo.com", name="Prueba Mailtrap"),
    to=[Address(email="destinatario@email.com", name="Nombre del destinatario")],
    subject="Su asunto de email HTML aquí",
    text="Este es un texto de respaldo para clientes de email que no muestran HTML",
    html="""
    <!DOCTYPE html>
    <html>
        <head>
            <title>Título del email</title>
        </head>
        <body>
            <h1>¡Hola, mundo!</h1>
            <p>Este es un <strong>email HTML</strong> enviado desde el SDK de Python de Mailtrap.</p>
            <p>Aquí hay un enlace: <a href="https://ejemplo.com">Visite Ejemplo.com</a></p>
        </body>
    </html>
    """,
    # Usted puede categorizar este email o agregar encabezados personalizados según sea necesario
    category="Email HTML",
    headers={"X-Encabezado-Personalizado": "Value"}
)

# Iniciar el MailtrapClient con su token de API
client = MailtrapClient(token="su-clave-api")

# Enviar el email
client.send(mail)

print("Email HTML enviado con éxito.")

Resumen rápido:

  • Contenido HTML: El parámetro html del objeto Mail es donde coloca su contenido HTML. Esta es la parte del email que será renderizada por los clientes de email capaces de mostrar HTML.
  • Contenido de texto de respaldo: La versión de texto plano del contenido del email sirve como respaldo para los clientes de email que no renderizan HTML o para los usuarios que prefieren emails de texto plano.
  • Enviar el email: Con el contenido HTML definido, el resto del proceso para enviar el email continua siendo el mismo.

Enviar email a múltiples destinatarios

Modificaré la parte del destinatario de la configuración del email para incluir a múltiples destinatarios.

Hay comentarios a lo largo del script para explicar cómo manejar múltiples destinatarios tanto para el campo To como para agregar destinatarios Cc (con copia) y Bcc (con copia oculta). Por lo tanto, no agregaré la sección Resumen rápido en este caso, ya que el método es simple y la lógica es obvia en el script.

from mailtrap import Mail, Address, MailtrapClient

# Cree un objeto Mail dirigido a múltiples destinatarios, incluyendo direcciones Cc y Bcc
mail = Mail(
    # Especifique la dirección de email del remitente y el nombre opcional
    sender=Address(email="mailtrap@ejemplo.com", name="Prueba Mailtrap"),
    # Especifique múltiples destinatarios en el campo "To"
    to=[
        Address(email="destinatario1@email.com", name="Destinatario Uno"),
        Address(email="destinatario2@email.com", name="Destinatario Dos"),
    ],
    # Adicionalmente, especifique destinatarios en el campo "Cc"
    cc=[
        Address(email="cc1@email.com", name="Destinatario Cc Uno"),
        Address(email="cc2@email.com", name="Destinatario Cc Dos"),
    ],
    # Y destinatarios en el campo "Bcc" para copias ocultas
    bcc=[
        Address(email="bcc1@email.com", name="Destinatario Bcc Uno"),
        Address(email="bcc2@email.com", name="Destinatario Bcc Dos"),
    ],
    # Asunto del email
    subject="Email a múltiples destinatarios",
    # El contenido de texto plano del email
    text="Este email se envía a múltiples destinatarios, incluyendo direcciones Cc y Bcc.",
    # Opcional: categorice este email o agregue encabezados personalizados según sea necesario
    category="Email masivo",
    headers={"X-Encabezado-Personalizado": "Value"}
)

# Iniciar el MailtrapClient con su token de API
client = MailtrapClient(token="su-clave-api")

# Enviar el email usando el método send del cliente
client.send(mail)

print("Email enviado a múltiples destinatarios con éxito.")

Enviar un email con archivos adjuntos

Aquí, me enfocaré principalmente en cómo se usa la clase Attachment para incluir archivos en su email. Este ejemplo demostrará cómo adjuntar un archivo genérico, pero el enfoque es similar para cualquier tipo de archivo.

from mailtrap import Mail, Address, MailtrapClient, Attachment, Disposition
import base64
from pathlib import Path

# Prepare el archivo que desea adjuntar
file_path = Path("ruta/a/su/archivo.pdf")  # Actualice esto a la ruta de su archivo
file_content = file_path.read_bytes()  # Lea el contenido del archivo como bytes

# Codifique el contenido del archivo en base64
encoded_content = base64.b64encode(file_content)

# Cree un objeto Mail con un adjunto
mail = Mail(
    sender=Address(email="mailtrap@ejemplo.com", name="Prueba Mailtrap"),
    to=[Address(email="destinatario@email.com", name="Nombre del destinatario")],
    subject="Email con adjunto",
    text="Este email contiene un adjunto. ¡Revíselo!",
    # Definir el adjunto
    attachments=[
        Attachment(
            content=encoded_content,  # El contenido codificado en base64 del archivo
            filename=file_path.name,  # El nombre del archivo como debe aparecer en el email
            disposition=Disposition.ATTACHMENT,  # Indica que el archivo es un adjunto
            mimetype="application/pdf",  # El tipo MIME del archivo
            # `content_id` es opcional y generalmente se usa para incrustar imágenes directamente en el cuerpo HTML
        )
    ],
)

# Iniciar el MailtrapClient con su token de API
client = MailtrapClient(token="su-clave-api")

# Enviar el email
client.send(mail)

print("Email con archivo adjunto enviado con éxito.")

Resumen rápido:

  • Prepare el archivo: El script comienza especificando la ruta al archivo que desea adjuntar y leyendo su contenido como bytes. Es importante leer el archivo en modo binario (read_bytes()) para asegurar que el contenido se codifique y transmita correctamente.
  • Codificación base64: Dado que los protocolos de email no son seguros para datos binarios, el contenido del archivo debe codificarse en base64. Esta codificación convierte los datos binarios en un formato de texto que puede transmitirse de manera segura por email. El método base64.b64encode se utiliza para este propósito.
  • Cree el adjunto: La clase Attachment se instancia con varios parámetros:
    • content – El contenido codificado en base64 del archivo.
    • filename – El nombre del archivo como desea que aparezca en el email.
    • disposition – Se establece en Disposition.ATTACHMENT para indicar que el archivo es un adjunto (a diferencia de inline, que se usaría para imágenes incrustadas).
    • mimetype – El tipo MIME del archivo, que ayuda a los clientes de email a entender cómo manejar el archivo. Para un PDF, esto es application/pdf.

Enviar un email con una imagen incrustada

Aquí, adjuntaré la imagen de manera que se pueda mostrar directamente dentro del contenido HTML del email. Esto generalmente se logra adjuntando la imagen con un Content-ID (cid) que puede referenciarse en el HTML. Así es cómo podrá hacerlo:

from mailtrap import Mail, Address, MailtrapClient, Attachment, Disposition
import base64
from pathlib import Path

# Especifique la ruta a su imagen
image_path = Path("ruta/a/su/imagen.jpg")
image_content = image_path.read_bytes()  # Lea el contenido de la imagen como bytes

# Codifique el contenido de la imagen en base64
encoded_image = base64.b64encode(image_content)

# Cree un objeto Mail con contenido HTML y una imagen incrustada
mail = Mail(
    sender=Address(email="mailtrap@ejemplo.com", name="Pruebe Mailtrap"),
    to=[Address(email="destinatario@email.com", name="Nombre del destinatario")],
    subject="Email con imagen incrustada",
    text="Este es un texto de respaldo para clientes de email que no renderizan HTML.",
    html="""
    <!DOCTYPE html>
    <html>
        <body>
            <h1>¡Hola, mundo!</h1>
            <p>Este email contiene una imagen incrustada.</p>
            <!-- Use 'cid:image_cid' en el atributo src para incrustar la imagen -->
            <img src="cid:image_cid">
        </body>
    </html>
    """,
    attachments=[
        Attachment(
            content=encoded_image,
            filename=image_path.name,
            disposition=Disposition.INLINE,  # Marcar el adjunto como
            mimetype="image/jpeg",  # El tipo MIME de la imagen
            content_id="image_cid",  # Content-ID usado para referenciar la imagen en el atributo src del HTML
        )
    ],
)

# Iniciar el MailtrapClient con su token de API
client = MailtrapClient(token="su-clave-api")

# Enviar el email
client.send(mail)

print("Email con una imagen incrustada enviado con éxito.")

Resumen rápido:

  • Prepare la imagen: Antes de adjuntar la imagen, lea su contenido como bytes y luego lo codifica en base64. Esta codificación es necesaria porque el contenido del email (incluyendo los adjuntos) debe transmitirse en un formato basado en texto.
  • Contenido HTML: En el parámetro html del objeto Mail, incluye una etiqueta <img> donde el atributo src usa un esquema cid: seguido del Content-ID del adjunto de imagen (image_cid en este caso). Este cid vincula la imagen incrustada en el contenido HTML con el archivo de imagen adjunto.
  • Adjuntar la imagen: La imagen se adjunta utilizando la clase Attachment con varios parámetros específicos:
    • content – El contenido de la imagen codificado en base64.
    • filename – El nombre del archivo de imagen. Se utiliza como respaldo en algunos clientes de email si la imagen no se puede mostrar.
    • disposition – Se establece en Disposition.INLINE para indicar que el adjunto debe mostrarse en línea con el contenido HTML, no como un adjunto separado y descargable.
    • mimetype – Especifique el tipo MIME de la imagen (por ejemplo, “image/jpeg”). Esto ayuda al cliente de email a entender cómo manejar el archivo.
    • content_id – Un identificador único para el adjunto referenciado en el atributo src del HTML para incrustar la imagen.
    • Enviar el email – El proceso para enviar el email permanece sin cambios.

Envío de emails masivos

Para recordarle, la Plataforma de Email Delivery de Mailtrap le permite enviar emails masivos además de transaccionales, bajo el mismo plan. Necesita seleccionar el flujo, presionar el botón API y elegir la integración de Python.

Configuración de API de flujo masivo de Mailtrap

Dicho esto, acá está lo que necesita hacer.

  1. Asegúrese de tener instalada la biblioteca requests. Si no, puede instalarla usando pip:
pip install requests
  1. Construya un payload JSON que especifique los detalles del email y ajuste el campo to para incluir a múltiples destinatarios.
  1. Usando la biblioteca requests, haga una solicitud POST al endpoint de la API masiva de Mailtrap, proporcionando los encabezados necesarios (incluyendo la autorización) y el payload. Verifique el script de ejemplo a continuación.
import requests
import json

def send_mailtrap_email(payload):
    url = "https://bulk.api.mailtrap.io/api/send"
    headers = {
      "Authorization": "Bearer su_token_api",  # Reemplace con su token de API de Mailtrap
      "Content-Type": "application/json"
    }

    response = requests.post(url, headers=headers, data=json.dumps(payload))
    return response.text

payload = {
    "from": {"email": "mailtrap@mailtrapdemo.com", "name": "Pruebe Mailtrap"},
    "to": [{"email": "destinatario@ejemplo.com"}],  # Agregue más destinatarios según sea necesario
    "subject": "¡Eres increíble!",
    "text": "¡Felicidades por enviar un email de prueba con Mailtrap!",
    "category": "Prueba de integración"
}

response_text = send_mailtrap_email(payload)
print(response_text)

Resumen rápido:

  • payload – Es un diccionario que coincide con la estructura JSON esperada por la API masiva de Mailtrap. Puede modificar este diccionario para incluir los detalles de su email, como el remitente, destinatario(s), asunto y cuerpo.
  • send_mailtrap_email – La función encapsula el proceso de enviar el email. Toma el payload como entrada, la convierte a formato JSON y hace una solicitud POST a la API masiva de Mailtrap.

Consideraciones de seguridad para el envío de emails

Si planea automatizar el envío de emails para enviarlos a un gran número de destinatarios de manera consistente, es mejor tomar precauciones adicionales. (Principalmente relacionadas con el método SMTP).

Aquí, cubriré algunos métodos probados para evitar codificar las credenciales directamente en sus scripts y manejar los errores. Tenga en cuenta que los siguientes consejos se aplican independientemente del proveedor de email que esté utilizando (SendGrid, SES, cuenta de Gmail, etc.).

Usar variables de entorno para información sensible

Las variables de entorno son una forma segura de administrar la configuración y la información sensible fuera del código de su aplicación.

En Python, puede usar el módulo os para acceder a las variables de entorno.

import os

smtp_server = os.getenv("SMTP_SERVER", "default.smtp.server")
login = os.getenv("SMTP_LOGIN")
password = os.getenv("SMTP_PASSWORD")

# Ejemplo de uso en una configuración de conexión SMTP
# smtp.login(login, password)

Antes de ejecutar su script, establezca las variables de entorno en su sistema operativo. Por ejemplo, en una terminal de Linux o macOS, puede establecerlas temporalmente de la siguiente manera:

export SMTP_SERVER=live.smtp.mailtrap.io
export SMTP_LOGIN=su_usuario
export SMTP_PASSWORD=su_contraseña

En Windows, puede establecerlas a través de una línea de comandos de la siguiente manera:

set SMTP_SERVER=live.smtp.mailtrap.io
set SMTP_LOGIN=su_usuario
set SMTP_PASSWORD=su_contraseña

Manejo de errores

Aquí se muestra cómo manejar errores inesperados, como errores de red, problemas de autenticación u otras excepciones que pueden ocurrir durante el proceso de envío de emails.

try:
    # Intente enviar un email
    server.sendmail(sender_email, recipient_email, message.as_string())
except smtplib.SMTPException as e:
    print(f"Ocurrió un error SMTP: {e}")
except Exception as e:
    print(f"Ocurrió un error: {e}")

Uso de SSL

Aquí hay un esquema básico de cómo podría usar smtplib.SMTP_SSL en un script para enviar un email:

import smtplib
from email.mime.text import MIMEText


# Configuración
port = 465
smtp_server = "live.smtp.mailtrap.io"
login = "usuario"
password = "contraseña"


sender_email = "remitente@dominio_registrado.com"
receiver_email = "destinatario@gmail.com"


text = """\
Hola,
¡Siéntase libre de hacernos saber qué contenido le sería útil!
"""


message = MIMEText(text, "plain")
message["Subject"] = "Email de texto plano"
message["From"] = sender_email
message["To"] = receiver_email




with smtplib.SMTP_SSL(smtp_server, port) as server:
    server.login(login, password)
    server.sendmail(sender_email, receiver_email, message.as_string())
    print("¡Email enviado con éxito!")

Configuración externa

Almacenar los datos de configuración (como los detalles del servidor SMTP y las direcciones de email) en archivos externos o variables de entorno mejora la seguridad y flexibilidad de su script. Para configuraciones más complejas, puede considerar usar un archivo JSON o similar.

  • Ejemplo de configuración JSON (config.json):
{
    "smtp_server": "live.smtp.mailtrap.io",
    "smtp_port": 587,
    "login": "su_usuario",
    "password": "su_contraseña"
}
  • Cómo cargar la configuración:
import json

with open('config.json', 'r') as config_file:
    config = json.load(config_file)

smtp_server = config.get('smtp_server')
smtp_port = config.get('smtp_port')
login = config.get('login')
password = config.get('password')

Consejo: Si desea enviar emails desde su cuenta de Google y aprovechar el servidor SMTP de Gmail (smtp.gmail.com), ya hemos escrito sobre ello. Consulte el artículo aquí.

Probar emails y envío de emails en staging

Al crear una nueva aplicación o agregar cualquier funcionalidad, especialmente cuando lo hace por primera vez, es esencial experimentar en un servidor de prueba. Aquí hay una breve lista de razones:

  1. No llegará a los buzones de sus amigos y clientes. Esto es vital cuando prueba el envío masivo de emails o trabaja con una base de datos de email.
  2. No inundará su bandeja de entrada con emails de prueba.
  3. Su dominio no será incluido en la lista negra por spam.

Un entorno de servidor SMTP de prueba imita el trabajo de un servidor web real de terceros. En los siguientes ejemplos, usaré Email Testing de Mailtrap, que permite a los desarrolladores capturar el tráfico SMTP de staging e inspeccionar y depurar los emails antes de que se envíen a los destinatarios reales.

Además de eso, Email Testing puede ayudar a validar su HTML/CSS, analizar el contenido del email, previsualizar el contenido txt, y dar una puntuación de spam relevante. La herramienta es fácil de configurar; todo lo que necesita es copiar las credenciales generadas por la aplicación y pegarlas en su código.

Nota: Cubriré los métodos SMTP y API por separado. Y si quiere un tutorial detallado sobre las pruebas con Python, consulte este artículo.

SMTP

Diríjase a Mailtrap, seleccione Email Testing, luego My Inbox. En la pestaña SMTP Settings, haga clic en “Show credentials” para revelar las credenciales de prueba.

Configuración SMTP de Email Testing de Mailtrap

Así es como se ve en la práctica:

import smtplib
port = 2525 
smtp_server = "sandbox.smtp.mailtrap.io"
login = "1b2c3d4e5d66f" # su usuario generado por Mailtrap
password = "1b2c3d4e5d66f"  # su contraseña generada por Mailtrap

Mailtrap hace las cosas aún más fáciles. Vaya a la sección Integraciones en la pestaña de configuración SMTP y obtenga la plantilla lista para usar del mensaje de texto simple con sus credenciales de Mailtrap.

Nota importante: Los fragmentos usan credenciales de prueba por seguridad, asegúrese de copiar y pegar sus credenciales reales en el código.

La opción más básica para instruir a su código de Python sobre quién envía qué a quién es el método de instancia sendmail(), que usaré aquí. Pero también tenemos integraciones ejemplares para Django y Flask.

Integración smtplib de Email Testing de Mailtrap

Veamos el ejemplo más de cerca y agreguemos algo de manejo de errores (consulte las #explicaciones entre paréntesis). Para capturar errores, usamos los bloques try y except. Consulte la documentación para ver la lista de excepciones aquí.

# el primer paso siempre es el mismo: importar todos los componentes necesarios:
import smtplib
from socket import gaierror

# ahora puede jugar con su código. Definamos el servidor SMTP por separado aquí:
port = 2525 
smtp_server = "sandbox.smtp.mailtrap.io"
login = "1b2c3d4e5d66f" # pegue su usuario generado por Mailtrap
password = "1b2c3d4e5d66f"  # pegue su contraseña generada por Mailtrap
# especifique las direcciones de email del remitente y el destinatario
sender = "remitente@ejemplo.com"
receiver = "mailtrap@ejemplo.com"
# escriba su mensaje: use dos nuevas líneas (\n) para separar el asunto del cuerpo del mensaje, y use 'f' para insertar automáticamente variables en el texto
message = f"""\
Subject: Hola Mailtrap
To: {receiver}
From: {sender}

Este es mi primer mensaje con Python."""

try:
    # envíe su mensaje con las credenciales especificadas anteriormente
    with smtplib.SMTP(smtp_server, port) as server:
        server.login(login, password)
        server.sendmail(sender, receiver, message)
    # dígale al script que informe si su mensaje fue enviado o qué errores deben corregirse
    print('Enviado')
except (gaierror, ConnectionRefusedError):
    print('Error al conectarse al servidor. ¿Configuración de conexión incorrecta?')
except smtplib.SMTPServerDisconnected:
    print('Error al conectarse al servidor. ¿Usuario/contraseña incorrectos?')
except smtplib.SMTPException as e:
    print('Ocurrió un error SMTP:' + str(e))

Una vez que obtenga el resultado Enviado en Shell, debería ver su mensaje en la bandeja de entrada de Mailtrap:

Mensaje de prueba de Python en Mailtrap

Si prefiere trabajar en un entorno local, el servidor de depuración SMTP local podría ser una opción. Para este propósito, Python ofrece un módulo smtpd. Tiene una característica DebuggingServer, que descartará los mensajes que está enviando e imprimirá en stdout. Es compatible con todos los sistemas operativos.

Establezca su servidor SMTP en localhost:1025

python -m smtpd -n -c DebuggingServer localhost:1025

Para ejecutar el servidor de email SMTP en el número de puerto 25, necesitará permisos de root:

sudo python -m smtpd -n -c DebuggingServer localhost:25

Le ayudará a verificar si su código está funcionando y señalar los posibles problemas, en caso de que los haya. Sin embargo, no le permitirá verificar cómo se renderiza su plantilla de email HTML.

API

Puede consultar nuestra documentación de la API para obtener detalles completos sobre las pruebas de API. Usaré Python 3 para mostrarle el método y guiarlo paso a paso.

  1. Establezca una conexión al endpoint de la API de Email Testing de Mailtrap usando http.client.HTTPSConnection.
  2. Defina el contenido de su email, incluyendo destinatarios (to, cc, bcc), remitente (from), asunto, contenido de texto y cualquier adjunto o variable personalizada como una carga útil JSON.
  3. Realice una solicitud POST a la API de Email Testing de Mailtrap con su payload y los encabezados necesarios, incluyendo su token de API para la autorización. Aquí tiene un ejemplo:
import http.client
import json

def test_send_email():
    conn = http.client.HTTPSConnection("sandbox.api.mailtrap.io")
    
    payload = {
        "to": [{"email": "john_doe@ejemplo.com", "name": "John Doe"}],
        "cc": [{"email": "jane_doe@ejemplo.com", "name": "Jane Doe"}],
        "bcc": [{"email": "james_doe@ejemplo.com", "name": "Jim Doe"}],
        "from": {"email": "ventas@ejemplo.com", "name": "Equipo de ventas de ejemplo"},
        "attachments": [
            {
                "content": "base64_encoded_content_here",
                "filename": "index.html",
                "type": "text/html",
                "disposition": "attachment"
            }
        ],
        "custom_variables": {"user_id": "45982", "batch_id": "PSJ-12"},
        "headers": {"X-Message-Source": "dev.midominio.com"},
        "subject": "Confirmación de su pedido de ejemplo",
        "text": "Felicitaciones por su pedido no. 1234",
        "category": "Prueba API"
    }

    headers = {
        'Content-Type': "application/json",
        'Accept': "application/json",
        'Api-Token': "su_token_api_aqui"  # Reemplace con su token de API real
    }

    # Convierta el payload en una lista JSON
    json_payload = json.dumps(payload)

    # Realice la solicitud POST
    conn.request("POST", "/api/send/inbox_id", json_payload, headers)  # Reemplace 'inbox_id' con su ID de bandeja real

    # Obtenga la respuesta
    response = conn.getresponse()
    data = response.read()

    print(data.decode("utf-8"))

if __name__ == "__main__":
    test_send_email()

Notas:

  • Payload: El diccionario contiene todos los detalles del email que desea probar. Asegúrese de reemplazar los valores de marcador de posición con datos reales y relevantes para su caso de prueba. Para los adjuntos, codifique el contenido de su archivo en Base64 e inclúyalo en el campo content.
  • Encabezados: Incluya sus encabezados Content-Type, Accept y Api-Token. El Api-Token debe ser su token de API de Mailtrap.
  • Solicitud y respuesta: El script realiza una solicitud POST al endpoint /api/send/inbox_id, reemplazando inbox_id con su ID de bandeja real. Luego, lee e imprime la respuesta para verificar el resultado.

Próximos pasos con emails en Python

Demostré las opciones de envío de emails con Python para describir la lógica y una gama de sus capacidades. ¡Pero le recomiendo revisar la documentación de Python y experimentar con su propio código para obtener excelentes resultados!

Hay un montón de varios frameworks y bibliotecas de Python que hacen que la creación de aplicaciones sea más elegante y dedicada. En particular, algunos de ellos pueden ayudar a mejorar su experiencia con la creación de funcionalidad de envío de emails:

Los frameworks más populares son:

  1. Flask, que ofrece una interfaz simple para el envío de emails: Flask Mail. Siéntase libre de aprender más con nuestra guía sobre cómo enviar emails con Flask.
  2. Django puede ser una excelente opción para construir plantillas HTML. Además, eche un vistazo a nuestro tutorial de envío de emails de Django.
  3. Zope es útil para el desarrollo de sitios web.
  4. Marrow Mailer es un framework dedicado a la entrega de emails que agrega varias configuraciones útiles.
  5. Plotly y su Dash pueden ayudar con los gráficos y reportes por email.

¡Buena suerte y no olvide mantenerse del lado seguro al enviar sus emails!

Article by Aleksandr Varnin Full Stack Developer @ Railsware
Article by Veljko Ristić Content Manager @ Mailtrap

Linguist by trade, digital marketer at heart, I’m a Content Manager who’s been in the online space for 10+ years. From ads to e-books, I’ve covered it all as a writer, editor, project manager, and everything in between. Now, my passion is with email infrastructure with a strong focus on technical content and the cutting-edge in programming logic and flows. But I still like spreading my gospels while blogging purely about marketing.