Automação de E-mails com Python — 2025 | Python Brasil

Automatize o envio de e-mails com Python usando smtplib. HTML, anexos e envio em lote com exemplos. Veja como!

6 min de leitura Equipe Python Brasil

A automação de e-mails é uma das aplicações mais práticas de Python no ambiente corporativo. Enviar relatórios diários, notificações de sistema, confirmações de cadastro ou comunicações em massa são tarefas que, quando feitas manualmente, consomem tempo e estão sujeitas a erros. Com Python e o módulo smtplib da biblioteca padrão, você pode automatizar tudo isso de forma confiável.

Neste artigo, vamos aprender a enviar e-mails simples, com formatação HTML, com anexos e até em lote, seguindo boas práticas de segurança e organização.

Configuração básica com smtplib

O módulo smtplib faz parte da biblioteca padrão do Python e implementa o protocolo SMTP (Simple Mail Transfer Protocol) para envio de e-mails:

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

def enviar_email_simples(destinatario, assunto, corpo):
    """Envia um e-mail de texto simples."""
    remetente = "seu_email@gmail.com"
    senha = "sua_senha_de_app"  # Use senha de app, não a senha normal

    mensagem = MIMEMultipart()
    mensagem["From"] = remetente
    mensagem["To"] = destinatario
    mensagem["Subject"] = assunto

    mensagem.attach(MIMEText(corpo, "plain", "utf-8"))

    with smtplib.SMTP("smtp.gmail.com", 587) as servidor:
        servidor.starttls()
        servidor.login(remetente, senha)
        servidor.send_message(mensagem)

    print(f"E-mail enviado para {destinatario}")

# Uso:
# enviar_email_simples(
#     "colega@empresa.com",
#     "Relatório Diário",
#     "Segue o relatório do dia. Tudo dentro da normalidade."
# )

Para usar com o Gmail, você precisa gerar uma “senha de app” nas configurações de segurança da sua conta Google. Nunca use sua senha principal no código.

Enviando e-mails com HTML

E-mails em HTML permitem uma apresentação visual muito mais rica, com tabelas, cores e formatação:

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

def enviar_email_html(destinatario, assunto, corpo_html):
    """Envia um e-mail com conteúdo HTML."""
    remetente = "seu_email@gmail.com"
    senha = "sua_senha_de_app"

    mensagem = MIMEMultipart("alternative")
    mensagem["From"] = remetente
    mensagem["To"] = destinatario
    mensagem["Subject"] = assunto

    # Versão texto (fallback)
    texto_simples = "Este e-mail requer um cliente que suporte HTML."
    mensagem.attach(MIMEText(texto_simples, "plain", "utf-8"))

    # Versão HTML
    mensagem.attach(MIMEText(corpo_html, "html", "utf-8"))

    with smtplib.SMTP("smtp.gmail.com", 587) as servidor:
        servidor.starttls()
        servidor.login(remetente, senha)
        servidor.send_message(mensagem)

    print(f"E-mail HTML enviado para {destinatario}")

# Exemplo de relatório em HTML
relatorio_html = """
<html>
<body>
    <h2 style="color: #2c3e50;">Relatório de Vendas - Março 2025</h2>
    <table border="1" cellpadding="8" cellspacing="0"
           style="border-collapse: collapse; width: 100%;">
        <tr style="background-color: #3498db; color: white;">
            <th>Região</th>
            <th>Meta</th>
            <th>Realizado</th>
            <th>Status</th>
        </tr>
        <tr>
            <td>Sudeste</td>
            <td>R$ 500.000</td>
            <td>R$ 532.000</td>
            <td style="color: green;">Atingida</td>
        </tr>
        <tr>
            <td>Nordeste</td>
            <td>R$ 300.000</td>
            <td>R$ 278.000</td>
            <td style="color: red;">Pendente</td>
        </tr>
        <tr>
            <td>Sul</td>
            <td>R$ 350.000</td>
            <td>R$ 361.000</td>
            <td style="color: green;">Atingida</td>
        </tr>
    </table>
    <p style="color: #7f8c8d; font-size: 12px;">
        Relatório gerado automaticamente via Python.
    </p>
</body>
</html>
"""

# enviar_email_html("gerente@empresa.com", "Relatório de Vendas - Março 2025", relatorio_html)

Sempre inclua uma versão em texto simples como fallback. Alguns clientes de e-mail corporativos bloqueiam HTML por padrão.

Enviando e-mails com anexos

Enviar relatórios, planilhas ou PDFs em anexo é um dos cenários mais comuns:

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

def enviar_email_com_anexo(destinatario, assunto, corpo, caminhos_anexos):
    """Envia um e-mail com um ou mais anexos."""
    remetente = "seu_email@gmail.com"
    senha = "sua_senha_de_app"

    mensagem = MIMEMultipart()
    mensagem["From"] = remetente
    mensagem["To"] = destinatario
    mensagem["Subject"] = assunto

    mensagem.attach(MIMEText(corpo, "plain", "utf-8"))

    for caminho in caminhos_anexos:
        arquivo = Path(caminho)
        if not arquivo.exists():
            print(f"Aviso: arquivo '{caminho}' não encontrado, pulando.")
            continue

        with open(arquivo, "rb") as f:
            parte = MIMEBase("application", "octet-stream")
            parte.set_payload(f.read())

        encoders.encode_base64(parte)
        parte.add_header(
            "Content-Disposition",
            f"attachment; filename={arquivo.name}"
        )
        mensagem.attach(parte)

    with smtplib.SMTP("smtp.gmail.com", 587) as servidor:
        servidor.starttls()
        servidor.login(remetente, senha)
        servidor.send_message(mensagem)

    print(f"E-mail com {len(caminhos_anexos)} anexo(s) enviado para {destinatario}")

# Uso:
# enviar_email_com_anexo(
#     "colega@empresa.com",
#     "Planilha de Vendas",
#     "Segue a planilha de vendas do mês em anexo.",
#     ["vendas_marco.xlsx", "resumo.pdf"]
# )

Envio em lote com personalização

Para enviar e-mails personalizados para uma lista de destinatários:

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

def enviar_emails_em_lote(arquivo_csv, assunto_template, corpo_template):
    """Envia e-mails personalizados a partir de um arquivo CSV."""
    remetente = "seu_email@gmail.com"
    senha = "sua_senha_de_app"

    enviados = 0
    erros = 0

    with smtplib.SMTP("smtp.gmail.com", 587) as servidor:
        servidor.starttls()
        servidor.login(remetente, senha)

        with open(arquivo_csv, "r", encoding="utf-8") as f:
            leitor = csv.DictReader(f)
            for linha in leitor:
                try:
                    nome = linha["nome"]
                    email = linha["email"]

                    # Personalizando o conteúdo
                    assunto = assunto_template.format(**linha)
                    corpo = corpo_template.format(**linha)

                    mensagem = MIMEMultipart()
                    mensagem["From"] = remetente
                    mensagem["To"] = email
                    mensagem["Subject"] = assunto

                    mensagem.attach(MIMEText(corpo, "plain", "utf-8"))
                    servidor.send_message(mensagem)

                    enviados += 1
                    print(f"Enviado para {nome} ({email})")

                    # Pausa entre envios para evitar bloqueio
                    time.sleep(2)

                except Exception as e:
                    erros += 1
                    print(f"Erro ao enviar para {linha.get('email', '?')}: {e}")

    print(f"\nResumo: {enviados} enviados, {erros} erros.")

# Exemplo de CSV (contatos.csv):
# nome,email,produto
# Ana Silva,ana@email.com,Notebook
# Bruno Costa,bruno@email.com,Monitor

# Uso:
# enviar_emails_em_lote(
#     "contatos.csv",
#     "Promoção especial para você, {nome}!",
#     "Olá {nome},\n\nTemos uma oferta especial do {produto} para você.\n\nAtenciosamente,\nEquipe de Vendas"
# )

Configuração segura com variáveis de ambiente

Nunca armazene senhas diretamente no código. Use variáveis de ambiente:

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

class GerenciadorEmail:
    """Gerenciador de envio de e-mails com configuração segura."""

    def __init__(self):
        self.remetente = os.environ.get("EMAIL_REMETENTE")
        self.senha = os.environ.get("EMAIL_SENHA")
        self.servidor_smtp = os.environ.get("EMAIL_SMTP", "smtp.gmail.com")
        self.porta = int(os.environ.get("EMAIL_PORTA", "587"))

        if not self.remetente or not self.senha:
            raise ValueError(
                "Configure as variáveis de ambiente "
                "EMAIL_REMETENTE e EMAIL_SENHA"
            )

    def enviar(self, destinatario, assunto, corpo, html=False):
        """Envia um e-mail."""
        mensagem = MIMEMultipart()
        mensagem["From"] = self.remetente
        mensagem["To"] = destinatario
        mensagem["Subject"] = assunto

        tipo = "html" if html else "plain"
        mensagem.attach(MIMEText(corpo, tipo, "utf-8"))

        try:
            with smtplib.SMTP(self.servidor_smtp, self.porta) as servidor:
                servidor.starttls()
                servidor.login(self.remetente, self.senha)
                servidor.send_message(mensagem)
            return True
        except smtplib.SMTPException as e:
            print(f"Erro SMTP: {e}")
            return False

# Uso:
# export EMAIL_REMETENTE="seu_email@gmail.com"
# export EMAIL_SENHA="sua_senha_de_app"
# gerenciador = GerenciadorEmail()
# gerenciador.enviar("destino@email.com", "Teste", "Mensagem de teste")

Boas práticas para automação de e-mails

Para garantir entregas confiáveis e evitar problemas:

  • Use senhas de app: nunca use sua senha pessoal no código. Serviços como Gmail exigem senhas de aplicativo.
  • Variáveis de ambiente: armazene credenciais em variáveis de ambiente ou arquivos .env fora do repositório.
  • Respeite limites de envio: serviços gratuitos limitam a quantidade de e-mails diários. O Gmail permite cerca de 500 por dia.
  • Adicione pausas entre envios: ao enviar em lote, inclua intervalos para evitar ser bloqueado pelo servidor.
  • Trate erros individualmente: em envios em massa, capture erros por destinatário para não interromper o processo inteiro.
  • Registre logs: mantenha um registro de e-mails enviados, falhas e tentativas para auditoria.
  • Valide endereços: verifique o formato dos endereços antes de tentar enviar.

Conclusão

A automação de e-mails com Python é uma habilidade que gera valor imediato em qualquer ambiente profissional. Com o módulo smtplib e as bibliotecas auxiliares email.mime, é possível enviar desde mensagens simples até relatórios elaborados em HTML com anexos, tudo de forma automatizada e segura.

Como próximos passos, explore bibliotecas como yagmail para uma API mais simples, integre o envio de e-mails com geração de relatórios usando Pandas e openpyxl, e considere usar serviços como SendGrid ou Amazon SES para envios em grande escala com taxas de entrega superiores.

E

Equipe Python Brasil

Contribuidor do Python Brasil — Aprenda Python em Português