Automatiza correos con Python y smtplib

Actualizado el: 20/08/2026
Tempo de leitura: 3 minutos
Python e ícone de e-mail sobre teclado de notebook

Automatizar correos electrónicos con Python permite enviar informes, alertas, confirmaciones y recordatorios sin repetir tareas manuales. La biblioteca estándar incluye smtplib para comunicarse con un servidor SMTP y el paquete email para construir mensajes con texto, HTML y archivos adjuntos.

En esta guía crearás una solución reutilizable con credenciales en variables de entorno, destinatarios múltiples, adjuntos, manejo de errores y una estructura preparada para programarse. Antes de instalar herramientas adicionales, revisa cómo crear entornos virtuales con Python.

Cómo funciona el envío de correo

Tu programa no entrega directamente el mensaje al destinatario. Se conecta a un servidor SMTP autorizado, inicia una sesión segura, se autentica y solicita el envío. Cada proveedor define host, puerto, requisitos de TLS y métodos de autenticación.

La documentación oficial de smtplib describe las conexiones SMTP, SSL, STARTTLS y las excepciones disponibles.

Guardar credenciales de forma segura

No escribas contraseñas ni tokens dentro del archivo Python. Utiliza variables de entorno:

export SMTP_USER="usuario@example.com"
export SMTP_PASSWORD="clave-de-aplicacion"
import os

usuario = os.getenv("SMTP_USER")
contrasena = os.getenv("SMTP_PASSWORD")

if not usuario or not contrasena:
    raise RuntimeError("Faltan las credenciales SMTP")

La guía para leer variables de entorno en Python explica archivos .env, validación y despliegue.

Crear un mensaje de texto

from email.message import EmailMessage

mensaje = EmailMessage()
mensaje["From"] = "usuario@example.com"
mensaje["To"] = "destinatario@example.com"
mensaje["Subject"] = "Informe semanal"
mensaje.set_content(
    "Hola,\n\nEl informe semanal ya está disponible.\n"
)

EmailMessage organiza cabeceras, cuerpos alternativos y adjuntos. Consulta la referencia oficial de email.message.

Enviar con STARTTLS

import os
import smtplib
from email.message import EmailMessage

HOST = "smtp.example.com"
PUERTO = 587

usuario = os.environ["SMTP_USER"]
contrasena = os.environ["SMTP_PASSWORD"]

mensaje = EmailMessage()
mensaje["From"] = usuario
mensaje["To"] = "destinatario@example.com"
mensaje["Subject"] = "Prueba desde Python"
mensaje.set_content("Mensaje enviado correctamente.")

with smtplib.SMTP(HOST, PUERTO, timeout=20) as servidor:
    servidor.ehlo()
    servidor.starttls()
    servidor.ehlo()
    servidor.login(usuario, contrasena)
    servidor.send_message(mensaje)

Usa los datos oficiales de tu proveedor. Algunos servicios exigen una contraseña de aplicación o un método moderno de autenticación.

Enviar contenido HTML

mensaje.set_content(
    "Tu cliente de correo no muestra HTML. El informe está listo."
)

mensaje.add_alternative(
    """
    <html>
      <body>
        <h1>Informe listo</h1>
        <p>Los datos fueron procesados correctamente.</p>
      </body>
    </html>
    """,
    subtype="html",
)

Mantén una versión de texto para clientes que no renderizan HTML. No insertes contenido externo sin escapar.

Añadir un archivo adjunto

import mimetypes
from pathlib import Path

ruta = Path("informes") / "ventas.csv"
tipo, _ = mimetypes.guess_type(ruta.name)
tipo_principal, subtipo = (tipo or "application/octet-stream").split("/", 1)

mensaje.add_attachment(
    ruta.read_bytes(),
    maintype=tipo_principal,
    subtype=subtipo,
    filename=ruta.name,
)

Comprueba que el archivo exista y limita su tamaño. Para trabajar con rutas de forma portable, consulta pathlib en Python.

Destinatarios múltiples

destinatarios = [
    "ana@example.com",
    "luis@example.com",
]

mensaje["To"] = ", ".join(destinatarios)

Para envíos masivos, no expongas direcciones privadas en una cabecera compartida. Usa Bcc o genera mensajes individuales, respetando las políticas del proveedor y las normas aplicables.

Crear una función reutilizable

import os
import smtplib
from email.message import EmailMessage


def enviar_correo(destinatarios, asunto, texto):
    usuario = os.environ["SMTP_USER"]
    contrasena = os.environ["SMTP_PASSWORD"]

    mensaje = EmailMessage()
    mensaje["From"] = usuario
    mensaje["To"] = ", ".join(destinatarios)
    mensaje["Subject"] = asunto
    mensaje.set_content(texto)

    with smtplib.SMTP("smtp.example.com", 587, timeout=20) as servidor:
        servidor.starttls()
        servidor.login(usuario, contrasena)
        servidor.send_message(mensaje)

Separar la lógica en una función facilita las pruebas y el mantenimiento. La guía de funciones en Python explica parámetros, retornos y responsabilidades pequeñas.

Manejar errores y registrar resultados

import logging
import smtplib

try:
    enviar_correo(
        ["destinatario@example.com"],
        "Alerta",
        "El proceso terminó.",
    )
except smtplib.SMTPAuthenticationError:
    logging.exception("Autenticación SMTP rechazada")
except smtplib.SMTPException:
    logging.exception("Error al enviar el correo")
except OSError:
    logging.exception("Problema de red o del sistema")

Evita registrar credenciales o el contenido sensible del mensaje. La guía del módulo logging ayuda a crear registros útiles, y try y except en Python muestra cómo capturar excepciones específicas.

Programar el envío

Para una tarea diaria, la opción más fiable suele ser ejecutar el script mediante cron, el Programador de tareas de Windows o un servicio administrado. El propio script debe realizar una única ejecución, devolver un código de salida claro y registrar el resultado.

Cuando el asunto o el nombre del archivo incluyen fechas, utiliza objetos estructurados. La guía de datetime en Python explica formatos y zonas horarias.

Buenas prácticas

  • Usa conexiones cifradas y la configuración oficial del proveedor.
  • Guarda credenciales fuera del código y del repositorio.
  • Configura timeouts y captura errores SMTP específicos.
  • No reintentes indefinidamente mensajes rechazados.
  • Valida destinatarios, asunto, adjuntos y tamaño total.
  • Evita enviar información sensible sin una política adecuada.
  • Prueba primero con una cuenta y una lista de destinatarios controlada.

Conclusión

Automatizar correos con Python requiere más que llamar a una función de envío. Un flujo fiable protege credenciales, usa TLS, construye mensajes con EmailMessage, configura timeouts y registra los errores sin revelar secretos. Empieza con un mensaje de texto simple y añade HTML, adjuntos y programación solamente después de validar el envío básico.

Compartilhe:

Facebook
WhatsApp
Twitter
LinkedIn

Contenido del artículo

    Artículos relacionados

    Imagem ilustrativa de conteúdo Python para YouTube
    Automatización y Scripts
    Foto de perfil de Leandro Hirt da Academify

    YouTube con Python: descarga vídeos propios con yt-dlp

    Descarga copias de tus propios vídeos o contenido autorizado con Python y yt-dlp, validación, historial, límites, FFmpeg y prácticas responsables.

    Ler mais

    Tempo de leitura: 6 minutos
    12/07/2026
    Automação de postagens no Twitter usando Python
    Automatización y Scripts
    Foto de perfil de Leandro Hirt da Academify

    Tweepy: automatiza publicaciones en X con Python

    Automatiza publicaciones en X con Tweepy, credenciales seguras, validación, deduplicación, programación, logs y prácticas responsables contra el spam.

    Ler mais

    Tempo de leitura: 5 minutos
    12/07/2026
    Geração e edição de planilhas Excel usando Python
    Automatización y Scripts
    Foto de perfil de Leandro Hirt da Academify

    Excel con Python: crea y edita con openpyxl

    Crea y edita Excel con Pandas y openpyxl: hojas, fórmulas, estilos, filtros, validación, gráficos, rutas seguras y manejo de archivos

    Ler mais

    Tempo de leitura: 4 minutos
    12/07/2026
    Gerando aplicativo APK Android com Python
    Automatización y Scripts
    Foto de perfil de Leandro Hirt da Academify

    APK Android con Python, Kivy y Buildozer

    Genera un APK Android con Python, Kivy y Buildozer: configuración, permisos, recursos, compilación, pruebas, almacenamiento, firma y publicación.

    Ler mais

    Tempo de leitura: 6 minutos
    12/07/2026
    Web scraper de notícias em Python com envio para Telegram
    Automatización y Scripts
    Foto de perfil de Leandro Hirt da Academify

    Scraper de noticias con Python y Telegram

    Crea un scraper de noticias con Requests y Beautiful Soup, elimina duplicados y envía titulares a Telegram de forma segura

    Ler mais

    Tempo de leitura: 5 minutos
    11/07/2026
    Compactação de arquivos ZIP usando Python
    Automatización y Scripts
    Foto de perfil de Leandro Hirt da Academify

    zipfile: descomprime archivos ZIP con seguridad

    Descomprime archivos ZIP con Python de forma segura: valida rutas, evita Zip Slip, limita tamaños, verifica integridad y procesa archivos

    Ler mais

    Tempo de leitura: 4 minutos
    11/07/2026