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.
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
areceiver_emails
. Ahora es una lista de direcciones de email en lugar de un solo string (una sola lista).
- Configuración del encabezado
To
– El encabezadoTo
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” usandoCC
y/oBCC
.
- Nota: Algunos clientes de email (Outlook, Yahoo, Gmail, etc.) pueden mostrar a todos los destinatarios en el campo
- 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é deMIMEText
para el cuerpo aMIMEMultipart
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 objetoMIMEBase
para el adjunto, con el tipo establecido enapplication/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)
.
- Preparación del archivo – El archivo adjunto se abre en modo binario
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 atributosrc
que apunta alContent-ID (cid)
de la imagen que desea incrustar. Estecid
debe coincidir con el valor del encabezadoContent-ID
del adjunto de imagen. - Incrustar la imagen:
- Usando
MIMEImage
– El script ahora incluye la claseMIMEImage
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 objetoMIMEImage
. Este objeto representa el adjunto de imagen. - Encabezado Content-ID – Al objeto
MIMEImage
se le asigna un encabezadoContent-ID
, al que se hace referencia mediante el atributosrc
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.
- Usando
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
yaiosmtplib
, 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 asend_email_async
para enviar el email. Demuestra cómo ejecutar tareas asincrónicas en Python de manera efectiva, conasyncio.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.
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 deMIMEMultipart
. Este enfoque ofrece flexibilidad si decide agregar adjuntos o contenido HTML en el futuro. Sin embargo, podría simplificarse aún más usando soloMIMEText
. - 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
yMailtrapClient
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 claseAddress
para definir el email y el nombre del remitente.to
– Una lista de objetosAddress
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
yheaders
– 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.
- El constructor
- Enviar el email:
- Se crea una instancia de
MailtrapClient
y se autentica con un token de API. - Luego se llama al método
send
delMailtrapClient
, pasando el objetomail
como argumento para enviar el email. - Finalmente, se imprime un mensaje de confirmación para indicar que el email ha sido enviado.
- Se crea una instancia de
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 objetoMail
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 enDisposition.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 esapplication/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 objetoMail
, incluye una etiqueta<img>
donde el atributosrc
usa un esquemacid:
seguido del Content-ID del adjunto de imagen (image_cid
en este caso). Estecid
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 enDisposition.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 atributosrc
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.
Dicho esto, acá está lo que necesita hacer.
- Asegúrese de tener instalada la biblioteca
requests
. Si no, puede instalarla usando pip:
pip install requests
- Construya un payload JSON que especifique los detalles del email y ajuste el campo
to
para incluir a múltiples destinatarios.
- 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:
- 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.
- No inundará su bandeja de entrada con emails de prueba.
- 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.
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.
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:
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.
- Establezca una conexión al endpoint de la API de Email Testing de Mailtrap usando
http.client.HTTPSConnection
. - 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. - 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
yApi-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
, reemplazandoinbox_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:
- 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.
- 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.
- Zope es útil para el desarrollo de sitios web.
- Marrow Mailer es un framework dedicado a la entrega de emails que agrega varias configuraciones útiles.
- 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!