Como Enviar Emails em HTML em Python usando SMTP e API de email

On junho 04, 2024
22min read
Veljko Ristić Content Manager @ Mailtrap
This is a cover image for an article that explains in detail how to send HTML emails with Python

Para desenvolvedores, especialmente aqueles que utilizam o poder do Python, enviar emails em HTML pode ser um divisor de águas.

Neste guia sobre enviar emails HTML em Python, o nosso objetivo é desmistificar o processo para desenvolvedores iniciantes.

Para pular o processo de configuração e ir diretamente para o envio de emails com SMTP, clique aqui.

Configuração do smtplib e biblioteca email

As bibliotecas nativas que permitem criar e enviar emails em HTML sem esforço são os módulos smtplib e email.

Módulo smtplib

O módulo smtplib é parte da biblioteca padrão do Python, tornando-o prontamente disponível para todas as instalações de Python. Ele permite estabelecer conexões com servidores SMTP e enviar emails usando o protocolo SMTP.

Aqui está uma visão geral de como o smtplib funciona:

  • Primeiro, você estabelece uma conexão com o servidor SMTP de sua escolha, como o servidor SMTP do Mailtrap, por exemplo.
  • Você fornece suas credenciais do servidor SMTP (nome de usuário e senha) e quaisquer configurações de segurança necessárias (TLS/SSL).
  • Em seguida, você cria uma mensagem de email usando o módulo email.
  • Finalmente, você envia o email usando a conexão SMTP estabelecida.

Módulo email

O módulo email, outra biblioteca interna do Python, é usado para gerenciar mensagens de email. Ele permite criar emails estruturados com vários componentes, como assunto, remetente, destinatário e, mais importante, o conteúdo do email, incluindo conteúdo HTML.

Aqui está como o módulo email geralmente funciona:

  • Você cria um objeto EmailMessage e define seus atributos, como subject, from e to.
  • Para o conteúdo HTML, você adiciona uma parte do corpo do email em HTML ao email.
  • Anexos, imagens incorporadas e conteúdo alternativo em texto simples também podem ser adicionados conforme necessário.
  • O módulo email ajuda a garantir que seu email esteja em conformidade com os padrões de email.

Juntos, esses dois módulos fornecem os blocos de construção fundamentais para enviar emails em HTML diretamente do Python, tornando-o acessível a desenvolvedores de todos os níveis de experiência.

Além disso, adicionaremos o tipo de mensagem MIME, tratado pelo módulo email.mime, já que ele pode combinar HTML e CSS e texto simples.

Nota: É aconselhável ter as versões HTML e texto simples de um email separadas e, em seguida, mesclá-las usando a instância MIMEMultipart("alternative"). Dessa forma, você garante que a versão de texto do email seja exibida caso haja um problema com a versão HTML.

Aqui está o snippet de código completo:

# import the necessary components first
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart

port = 587
smtp_server = "live.smtp.mailtrap.io"
login = "1a2b3c4d5e6f7g" # cole seu login gerado pelo Mailtrap
password = "1a2b3c4d5e6f7g" # cole sua senha gerada pelo Mailtrap

sender_email = "mailtrap@exemplo.com"
receiver_email = "novo@exemplo.com"
message = MIMEMultipart("alternative")
message["Subject"] = "multipart test"
message["From"] = sender_email
message["To"] = receiver_email

# escrever a parte do texto/simples
text = """\
Oi,
Confira o novo artigo no blogue do Mailtrap:
SMTP Server for Testing: Cloud-based or Local?
https://blog.mailtrap.io/2018/09/27/cloud-or-local-smtp-server/
Diga-nos que tipo de conteúdo é mais útil para si!"""

# escrever a parte HTML
html = """\
<html>
  <body>
    <p>Oi,<br>
      Confira o novo artigo no blogue do Mailtrap:</p>
    <p><a href="https://blog.mailtrap.io/2018/09/27/cloud-or-local-smtp-server">Servidor SMTP para Teste: Cloud-based ou Local?</a></p>
    <p><strong>Diga-nos</strong> que tipo de conteúdo é mais útil para si!</p>
  </body>
</html>
"""

# converta ambas as partes para objetos MIMEText e adicione-os à mensagem MIMEMultipart
part1 = MIMEText(text, "plain")
part2 = MIMEText(html, "html")
message.attach(part1)
message.attach(part2)

# envie seu email
with smtplib.SMTP("live.smtp.mailtrap.io", 587) as server:
    server.login(login, password)
    server.sendmail(
        sender_email, receiver_email, message.as_string()
    )

print('Enviado')

Este script estabelece uma conexão com o servidor SMTP do Mailtrap usando as credenciais fornecidas. Após criar o email com conteúdo em texto simples e HTML, ele envia o email.

Lembre-se sempre de substituir as credenciais pelo seu nome de usuário e senha reais.

Nota: api é o nome de usuário padrão para todos os usuários SMTP do Mailtrap Sending, mas a senha é única para cada usuário.

Enviar emails HTML em Python usando SMTP

Você já tem o script exemplar. Agora, vamos dividi-lo e explicar o código passo a passo.

1. Importando os módulos necessários

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

Esses módulos fornecem ferramentas para trabalhar com SMTP (Simple Mail Transfer Protocol) e para construir mensagens de email.

2. Configuração do SMTP

port = 587
smtp_server = "live.smtp.mailtrap.io"
login = "1a2b3c4d5e6f7g"
password = "1a2b3c4d5e6f7g"

Estes são os detalhes do servidor SMTP. O login e a senha são gerados pelo Mailtrap para cada usuário do Mailtrap.

3. Definindo os cabeçalhos do email

sender_email = "mailtrap@exemplo.com"
receiver_email = "novo@exemplo.com"
message = MIMEMultipart("alternative")
message["Subject"] = "multipart test"
message["From"] = sender_email
message["To"] = receiver_email

Aqui, os endereços de email do remetente e do destinatário são definidos. Uma mensagem MIMEMultipart “alternativa” é criada, o que significa que o cliente de email tentará renderizar a última parte primeiro (neste caso, HTML), e se não puder, recorrerá às partes anteriores (aqui, texto simples).

4. A versão em texto simples

text = """\
...
"""

É aqui vai a versão em texto simples (fallback) do seu email.

5. A versão HTML do email

html = """\
...
"""

A versão HTML – veja o script completo acima para o snippet completo.

6. Anexando o conteúdo ao email

part1 = MIMEText(text, "plain")
part2 = MIMEText(html, "html")
message.attach(part1)
message.attach(part2)

Ambas as partes, texto simples e HTML, são convertidas em objetos MIMEText. Estes são então anexados à mensagem MIMEMultipart, tornando o email multipart.

7. Enviando o email

with smtplib.SMTP("live.smtp.mailtrap.io", 587) as server:
    server.login(login, password)
    server.sendmail(
        sender_email, receiver_email, message.as_string()
    )

Esta seção realmente envia o email. Uma conexão SMTP com o servidor é aberta, o servidor é acessado com as credenciais fornecidas e o email é enviado usando o método sendmail. A mensagem de email é convertida para o formato de string usando message.as_string().

8. Confirmação

print('Enviado')

E é isso, esta simples declaração print() confirma que seu email foi enviado via servidor SMTP do Mailtrap. Lembre-se sempre de usar as credenciais corretas do servidor SMTP, seja do Mailtrap ou de outros provedores, e adapte o conteúdo do email às suas necessidades.

Notas importantes:

  • Para usar o Mailtrap Email Sending, você precisa adicionar e verificar um domínio connosco, caso contrário, os métodos não funcionarão.

Enviar emails HTML para múltiplos destinatários

Enviar emails para múltiplos destinatários é uma tarefa comum, especialmente ao disseminar informações como newsletters, anúncios ou atualizações. Os módulos nativos do Python tornam essa tarefa fácil e eficiente.

  • Modificando o campo do destinatário

O campo To no objeto EmailMessage aceita uma lista de endereços de email. Se você fornecer vários endereços de email nesta lista, o email será enviado para cada um desses destinatários.

Aqui está um exemplo rápido:

recipients = ['destinatario1@exemplo.com', 'destinatario2@exemplo.com', 'destinatario3@exemplo.com']
msg['To'] = ', '.join(recipients)
  • Usando CC e BCC

Ao enviar emails, às vezes você quer incluir destinatários nos campos Carbon Copy (CC) ou Blind Carbon Copy (BCC).

O primeiro é usado para enviar uma cópia para partes interessadas que não são o público principal, enquanto o último é para destinatários que não devem ver os outros endereços de email para os quais o email foi enviado.

Para enviar emails com CC e BCC em Python:

cc_recipients = ['cc1@exemplo.com', 'cc2@exemplo.com']
bcc_recipients = ['bcc1@exemplo.com', 'bcc2@exemplo.com']

msg['Cc'] = ', '.join(cc_recipients)
msg['Bcc'] = ', '.join(bcc_recipients)

Lembrete: No contexto do smtplib, os destinatários BCC não verão os endereços de email dos outros destinatários BCC, e os destinatários principais não verão nenhum dos endereços de email BCC.

No entanto, se você estiver enviando em massa, para dezenas ou centenas de destinatários, o Python economiza muito trabalho se você usar loops.

Por exemplo, uma opção é criar um banco de dados, formatado em .csv, e salvar esse arquivo na mesma pasta que seu script de envio em Python. Vou abordar este exemplo aqui, pois é o mais próximo do que você pode encontrar em um cenário de produção. Claro, assumimos que você já criou e salvou o arquivo .csv dos destinatários.

Enviando emails personalizados em HTML para múltiplos destinatários

O script exemplar abaixo envia um email de confirmação de pedido para múltiplos destinatários cujos nomes e endereços de email estão armazenados em um arquivo contacts.csv. O script usa o módulo smtplib para enviar os emails e o módulo csv para ler os contatos do arquivo CSV.

import csv, smtplib

port = 587
smtp_server = "live.smtp.mailtrap.io"
login = "1a2b3c4d5e6f7g" # cole seu login gerado pelo Mailtrap
password = "1a2b3c4d5e6f7g" # cole sua senha gerada pelo Mailtrap
sender = "novo@exemplo.com"
message = """Subject: Confirmação de encomenda
To: {recipient}
From: {sender}

Oi {name}, agradecemos sua encomenda! Estamos agora a processá-la e iremos contactá-lo em breve"""

with smtplib.SMTP("smtp.mailtrap.io", 2525) as server:
    server.login(login, password)
    with open("contacts.csv") as file:
        reader = csv.reader(file)
        next(reader)  # salta a linha do cabeçalho
        for name, email in reader:
            server.sendmail(
                sender,
                email,
                message.format(name=name, recipient=email, sender=sender)
            )
            print(f'Enviado para {name}')

Aqui está a divisão do código para que você possa entender melhor o fluxo:

  1. Importando módulos
import csv, smtplib

O módulo csv é usado para ler e escrever arquivos CSV. E o smtplib é usado para enviar emails usando SMTP.

  1. Configuração
port = 587
smtp_server = "live.smtp.mailtrap.io"
login = "1a2b3c4d5e6f7g"
password = "1a2b3c4d5e6f7g"
sender = "novo@exemplo.com"

Como antes, esta parte do script lida com os detalhes do servidor SMTP, o endereço de email do remetente e as credenciais correspondentes.

  1. Modelo de email string
message = """...
"""

Este é um modelo de string para o email. Ele usa placeholders {recipient}, {sender} e {name} que serão substituídos por valores reais para cada destinatário.

  1. Envio de email
with smtplib.SMTP("live.smtp.mailtrap.io", 587) as server:
    server.login(login, password)

Aqui, uma conexão com o servidor SMTP é estabelecida e faz login no servidor com as credenciais fornecidas.

  1. Abrir e ler o .csv
with open("contacts.csv") as file:
        reader = csv.reader(file)
        next(reader)  # salta a linha do cabeçalho

O script lê o arquivo contacts.csv. A linha next(reader) é usada para pular a linha de cabeçalho do arquivo CSV, assumindo que a primeira linha contém nomes de colunas e não dados reais.

  1. Loop através dos contatos e envio
for name, email in reader:
            server.sendmail(
                sender,
                email,
                message.format(name=name, recipient=email, sender=sender)
            )
            print(f'Enviado para {name}')

Para cada par de nome e email no arquivo CSV, as seguintes ações são realizadas:

  • O message modelo é preenchido usando o método .format() com os valores atuais de nome, email e remetente.
  • O email é enviado para o endereço de email atual usando server.sendmail().
  • Uma declaração de impressão indica ao console que o email foi enviado para o nome atual.

Para recapitular, o script permite o envio em lote de emails personalizados. É particularmente útil para situações como confirmações de pedidos, convites para eventos e outros cenários onde você pode querer enviar uma mensagem semelhante para múltiplos destinatários, mas com alguns detalhes personalizados.

Pro Tip: Se você precisar validar endereços de email antes de enviar emails, clique no link para verificar nosso tutorial detalhado.

Enviar emails HTML com anexos

Enviar anexos por email usando Python é uma tarefa bastante comum, especialmente ao automatizar certos processos, como o envio de relatórios ou faturas. Anexos podem ser de vários tipos – de simples arquivos de texto e documentos a imagens e arquivos comprimidos.

Para ser exato, você pode anexar .txt, rich text, arquivos de texto, imagens, arquivos de áudio e aplicativos. Você só precisa usar a classe certa, por exemplo:

Arquivos de áudio – email.mime.audio.MIMEAudio

Arquivos de imagem – email.mime.image.MIMEImage

Aqui está a versão modificada do script para incluir os anexos.

import smtplib

# import the corresponding modules
from email import encoders
from email.mime.base import MIMEBase
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText

port = 587
smtp_server = "live.smtp.mailtrap.io"
login = "1a2b3c4d5e6f7g" # cole seu login gerado pelo Mailtrap
password = "1a2b3c4d5e6f7g" # cole sua senha gerada pelo Mailtrap

subject = "Um exemplo de bilhete"
sender_email = "mailtrap@exemplo.com"
receiver_email = "novo@exemplo.com"

message = MIMEMultipart()
message["From"] = sender_email
message["To"] = receiver_email
message["Subject"] = subject

# Adicionar corpo ao email
body = "Este é um exemplo de como pode enviar um bilhete em anexo com Python"
message.attach(MIMEText(body, "plain"))

filename = "seubilhete.pdf"
# Abrir ficheiro PDF em modo binário

# Assumimos que o ficheiro está no diretório a partir do qual executa o seu script Python
with open(filename, "rb") as attachment:
    # O tipo de conteúdo “application/octet-stream” significa que um anexo MIME é um ficheiro binário
    part = MIMEBase("application", "octet-stream")
    part.set_payload(attachment.read())

# Codificar para base64
encoders.encode_base64(part)

# Adicionar cabeçalho
part.add_header(
    "Content-Disposition",
    f"attachment; filename= {filename}",
)

# Adicione o anexo à sua mensagem e converta-o para string
message.attach(part)
text = message.as_string()

# envie seu email
with smtplib.SMTP("live.smtp.mailtrap.io", 587) as server:
    server.login(login, password)
    server.sendmail(
        sender_email, receiver_email, text
    )
print('Enviado')

O script mostra como anexar um arquivo binário (neste caso, um PDF) a um email. O processo envolve ler o conteúdo binário do arquivo, envolvê-lo em um objeto MIME com os cabeçalhos apropriados, codificá-lo em base64 e finalmente anexá-lo à mensagem de email.

Aqui está a divisão dos passos, focando em anexar a imagem:

  1. Importando os módulos
from email import encoders
from email.mime.base import MIMEBase
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText

Note que incluímos o seguinte, além dos módulos existentes:

  • encoders – fornece acesso ao codificador base64 que usamos para codificar o anexo.
  • MIMEBase – atua como base para criar objetos MIME de um tipo de conteúdo específico.
  1. Definindo o arquivo para anexar
filename = "seubilhete.pdf"

A função da linha é bastante auto-explicativa, apenas certifique-se de que os nomes dos arquivos correspondam.

  1. Abrir o ficheiro e criar o anexo
with open(filename, "rb") as attachment:
    # O tipo de conteúdo “application/octet-stream” significa que um anexo MIME é um ficheiro binário
    part = MIMEBase("application", "octet-stream")
    part.set_payload(attachment.read())

Aqui, o arquivo é aberto no modo de leitura binária ("rb") e seu conteúdo é lido. O anexo MIME é então criado como um arquivo binário com o tipo de conteúdo "application/octet-stream". Este tipo de conteúdo é um tipo MIME geral de arquivo binário e é usado aqui para representar o PDF.

  1. Codificação do anexo
encoders.encode_base64(part)

O anexo MIME (que é o conteúdo do PDF) é então codificado usando codificação base64, o que garante a transferência segura dos dados como texto, sem quaisquer corrupções nos conteúdos do PDF.

  1. Adicionando cabeçalhos
part.add_header(
    "Content-Disposition",
    f"attachment; filename= {filename}",
)

O cabeçalho "Content-Disposition" é adicionado para indicar que o objeto MIME é um anexo. Também especifica o nome do arquivo para o anexo. Isso garante que, quando o destinatário abrir o email, verá o arquivo apresentado como um anexo nomeado “seubilhete.pdf”.

  1. Anexando o arquivo ao email
message.attach(part)
text = message.as_string()

O anexo (part) é adicionado à mensagem de email principal message. A mensagem inteira, incluindo seu texto e o anexo, é então convertida em uma string usando message.as_string(). Esta representação de string é o que é enviado pelo servidor SMTP.

Pro Tips:

  1. Relevância é fundamental: Anexe apenas arquivos relevantes ao conteúdo do seu email. Anexos desnecessários podem confundir o destinatário.
  1. Convenções de nomeação de ficheiros: Adote nomes de arquivos claros e descritivos. Isso ajuda o destinatário a entender o conteúdo sem abri-lo. Por exemplo, em vez de nomear um arquivo como report.pdf, considere um nome mais descritivo como Q3_Relatório_de_Vendas_2023.pdf.
  1. Comprimir arquivos grandes: Para garantir o envio e download eficientes de arquivos, use ferramentas de compressão para reduzir o tamanho de anexos maiores. Ferramentas como zip ou rar podem ser inestimáveis.

Nota: Se você é usuário Apple, é melhor optar pela opção de compressão/zipping nativa. Clique com dois dedos ou clique com o botão direito em um arquivo ou pasta e escolha Comprimir “nome_do_arquivo”.

  1. Considerações sobre o tipo de arquivo: Sempre certifique-se de que o tipo de arquivo que você está enviando seja comumente usado e possa ser facilmente acessado pelo destinatário. Pode ser frustrante para eles se precisarem baixar um software especial apenas para visualizar seu anexo.

A regra prática é usar formatos de arquivo amplamente reconhecidos, como .pdf, .docx ou .xlsx, ao enviar documentos. Isso garante a máxima compatibilidade com o software do destinatário.

Dica: Mailtrap não tem limitações para tipos de arquivos anexos.

  1. Alerta ao destinatário: Se você estiver enviando um arquivo particularmente grande ou vários anexos, é uma boa prática notificar o destinatário no corpo do email. Isso lhes dá um aviso e garante que eles verifiquem todos os anexos.
  1. Verificar se há malware: Sempre certifique-se de que os arquivos que você está anexando estão livres de malware ou vírus. Isso não só protege o destinatário, mas também sua reputação.
  1. Limitar o número: Evite enviar muitos anexos em um único email. Se você tiver vários arquivos, considere combiná-los em um único arquivo comprimido ou compartilhar um link de armazenamento em nuvem onde o destinatário possa acessá-los.
  1. Testar antes de enviar: Especialmente ao trabalhar com emails importantes ou um novo sistema, envie um email de teste para si mesmo ou um colega primeiro. Verifique se os anexos chegam corretamente e podem ser abertos sem problemas.

Nota: Mais adiante no artigo, você encontrará um tutorial sobre como testar emails com Mailtrap e verificar a compatibilidade móvel, HTML e CSS, e obter uma pontuação de spam.

Enviar emails HTML com imagem incorporada

Quando você envia emails de marketing, newsletters ou qualquer comunicação que exija atenção do usuário, as imagens desempenham um papel indispensável. Elas adicionam apelo estético e podem transmitir ideias complexas rapidamente.

Lembre-se de que as imagens ainda são consideradas anexos, mesmo se fizerem parte do corpo do email. Existem três maneiras, ou três métodos, para incorporar a imagem:

  1. Anexos CID (que são incorporados com um objeto MIME)
  2. Imagens Base64 (que são a incorporação inline)
  3. Imagens em link

Nesta seção, exploraremos os anexos CID e as imagens Base64. Em seguida, apenas abordaremos brevemente a vinculação de imagens de um recurso externo.

Anexos CID

O script abaixo apresenta uma mensagem MIME multipart, contendo o componente MIMEImage. Aqui está o script completo.

# importar todos os componentes necessários
import smtplib
from email.mime.text import MIMEText
from email.mime.image import MIMEImage
from email.mime.multipart import MIMEMultipart

port = 587
smtp_server = "live.smtp.mailtrap.io"
login = "1a2b3c4d5e6f7g" # cole seu login gerado pelo Mailtrap
password = "1a2b3c4d5e6f7g" # cole sua senha gerada pelo Mailtrap

sender_email = "mailtrap@exemplo.com"
receiver_email = "novo@exemplo.com"
message = MIMEMultipart("alternative")
message["Subject"] = "Teste de imagem CID"
message["From"] = sender_email
message["To"] = receiver_email

# escrever a parte HTML
html = """\
<html>
<body>
  <img src="cid:Mailtrapimage">
</body>
</html>
"""

part = MIMEText(html, "html")
message.attach(part)

# Assumimos que o ficheiro está no diretório a partir do qual executa o seu script Python
fp = open('mailtrap.jpg', 'rb')
image = MIMEImage(fp.read())
fp.close()

# Especifique o ID de acordo com a img src na parte HTML
image.add_header('Content-ID', '<Mailtrapimage>')
message.attach(image)

# envie seu email
with smtplib.SMTP("live.smtp.mailtrap.io", 587) as server:
    server.login(login, password)
    server.sendmail(
        sender_email, receiver_email, message.as_string()
    )
print('Enviado')

Verifique a divisão do código, focaremos apenas nos componentes MIME e imagens incorporadas.

  1. Importando os módulos
from email.mime.image import MIMEImage

A classe MIMEImage cria o objeto de mensagem MIME específico para os anexos de imagem.

  1. O email HTML com a imagem incorporada
# escreva a parte HTML
html = """\
<html>
<body>
  <img src="cid:Mailtrapimage">
</body>
</html>
"""

Esta seção define o conteúdo HTML do email. A tag <img> apresenta o valor do atributo src como cid:Mailtrapimage. “cid” significa Content ID e é uma maneira de referenciar anexos embutidos dentro do email. Neste caso, a imagem com o ID de conteúdo Mailtrapimage será exibida onde a tag <img> aparece no conteúdo HTML.

  1. Anexando o HTML à mensagem:
part = MIMEText(html, "html")
message.attach(part)

O snippet constrói um objeto MIMEText a partir da string HTML e o anexa à mensagem de email principal.

  1. Incorporando a imagem
# Assumimos que o ficheiro está no diretório a partir do qual executa o seu script Python
fp = open('mailtrap.jpg', 'rb')
image = MIMEImage(fp.read())
fp.close()

# Especifique o ID de acordo com img src na parte HTML
image.add_header('Content-ID', '<Mailtrapimage>')
message.attach(image)

Aqui, o script faz o seguinte:

  • Ele abre o arquivo de imagem mailtrap.jpg no modo de leitura binária ('rb').
  • Um objeto MIMEImage chamado image é criado a partir do conteúdo binário da imagem.
  • O cabeçalho Content ID é adicionado ao objeto image. Este Content ID (<Mailtrapimage>) corresponde ao cid usado no conteúdo HTML. Esta associação permite que o cliente de email entenda onde exibir a imagem incorporada.
  • Finalmente, o objeto image é anexado à mensagem de email principal.

Método do módulo Base64

O script refatorado abaixo demonstra uma maneira alternativa de incorporar imagens em emails com codificação Base64. Este método envolve incorporar diretamente a string codificada em Base64 de uma imagem dentro do conteúdo HTML do email.

Mais importante, o email se torna autossuficiente, sem a necessidade de referências externas de imagem ou IDs de conteúdo (como no método anterior). É uma maneira eficaz de garantir que as imagens sejam exibidas na maioria dos clientes de email sem depender de servidores externos.

No entanto, isso pode aumentar o tamanho do email, especialmente para imagens maiores. Com a codificação Base64, você pode esperar um aumento de tamanho de dados de até 33%.

# importar os componentes necessários primeiro
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
import base64

port = 587
smtp_server = "live.smtp.mailtrap.io"
login = "1a2b3c4d5e6f7g" # cole seu login gerado pelo Mailtrap
password = "1a2b3c4d5e6f7g" # cole sua senha gerada pelo Mailtrap

sender_email = "mailtrap@exemplo.com"
receiver_email = "novo@exemplo.com"
message = MIMEMultipart("alternative")
message["Subject"] = "inline embedding"
message["From"] = sender_email
message["To"] = receiver_email

# Assumimos que o ficheiro está no diretório a partir do qual executa o seu script Python
encoded = base64.b64encode(open("mailtrap.jpg", "rb").read()).decode()

html = f"""\
<html>
<body>
  <img src="data:image/jpg;base64,{encoded}">
</body>
</html>
"""

part = MIMEText(html, "html")
message.attach(part)

# send your email
with smtplib.SMTP("live.smtp.mailtrap.io", 587) as server:
    server.login(login, password)
    server.sendmail(
        sender_email, receiver_email, message.as_string()
    )
print('Enviado')

Verifique a divisão do código, novamente focaremos apenas na incorporação de imagens:

  1. Importando o módulo base64
import base64

A linha importa o módulo base64, que fornece funções para codificar e decodificar dados usando o esquema de codificação Base64.

  1. Codificação
# Assumimos que o ficheiro está no diretório a partir do qual executa o seu script Python
encoded = base64.b64encode(open("mailtrap.jpg", "rb").read()).decode()

Aqui, as seguintes ações ocorrem:

  • O script abre o arquivo de imagem mailtrap.jpg no modo de leitura binária ('rb').
  • O conteúdo do arquivo de imagem é lido e então codificado usando base64.b64encode(). Esta função retorna um objeto semelhante a bytes.
  • O método .decode() é aplicado para converter o objeto semelhante a bytes em uma representação de string codificada em UTF-8 da imagem codificada em Base64. Esta representação de string é armazenada na variável encoded.
  1. Incorporando a imagem codificada no HTML
html = f"""\
<html>
<body>
  <img src="data:image/jpg;base64,{encoded}">
</body>
</html>
"""

A string codificada em Base64 basicamente é incorporada diretamente no HTML e aqui está como:

  • O atributo src da tag <img> é definido como uma URL de dados. Esta URL começa com o prefixo data:image/jpg;base64, seguido pela string codificada em Base64 da imagem (representada por {encoded} na f-string).
  • URLs de dados permitem que você incorpore dados diretamente em documentos da web, evitando referências externas de imagem. É especialmente útil para imagens menores, garantindo que sejam exibidas mesmo se o destinatário estiver offline ou se o cliente de email bloquear carregamentos externos.

Incorporando uma imagem de um servidor remoto

Se sua imagem estiver hospedada em um servidor remoto, geralmente é recomendado vinculá-la diretamente:

<img src="https://seuservidor.com/path_to_imagem.jpg">

No entanto, isso significa que o cliente de email deve buscar a imagem do servidor, o que pode ou não acontecer com base nas configurações do cliente. Honestamente, aplicativos mais seguros normalmente bloqueariam a solicitação.

De qualquer forma, sempre certifique-se de ter permissão para vincular diretamente a uma imagem em um servidor remoto antes de usar este método.

Formatos de imagem suportados

Embora existam muitos formatos de imagem, os formatos mais comumente suportados nos clientes de email são JPEG e PNG. Ambos são bem suportados e têm capacidades de compressão.

  • JPEG (.jpeg): Melhor para fotografias ou imagens com gradientes.
  • PNG (.png): Ideal para imagens com transparência, logotipos ou texto.

Dica sobre HEIC: O formato de imagem da Apple oferece grandes vantagens de compressão. No entanto, não é amplamente suportado por todos os clientes de email. Pode ser melhor converter imagens HEIC para JPEG ou PNG antes de embuti-las em emails.

Limites de tamanho de imagem do Mailtrap

Se você estiver usando o Mailtrap Email Sending via API, pode aproveitar os Templates de Email do Mailtrap e fazer o upload das imagens que deseja incorporar diretamente em nossa plataforma.

Os templates do Mailtrap usam a sintaxe Hanlebars, então é possível adicionar operadores lógicos para automatizar e personalizar os templates. Quanto às limitações de imagem, suportamos o seguinte:

  • Formatos: JPG, PNG, GIF
  • Tamanho máximo do arquivo: 2 MB

Dicas de otimização de tamanho de imagem

Incorporar imagens pode tornar seus emails bastante “pesados”, levando a tempos de carregamento lentos e possíveis problemas de entrega. Aqui estão algumas dicas para evitar isso:

  1. Redimensionar imagens: Certifique-se de que as dimensões de sua imagem não sejam maiores do que precisam ser.
  2. Comprimir Imagens: Use ferramentas como TinyPNG ou Compressor.io para reduzir o tamanho do arquivo sem comprometer a qualidade.
  3. Evitar incorporar imagens grandes: Se uma imagem for muito grande, considere vinculá-la em vez de incorporar. Ou você pode enviá-la como um anexo comprimido.

Snippet Python para compressão de imagem (usando a biblioteca Pillow)

Agora, o melhor método poderia ser permanecer no ambiente Python e aproveitar a biblioteca Pillow para otimizar o tamanho da imagem. Aqui está como fazer isso:

Primeiro, instale a biblioteca necessária:

pip install Pillow

Agora, você pode usar o seguinte snippet para comprimir imagens:

from PIL import Image

def compress_image(image_path, output_path, quality=85):
    with Image.open(image_path) as img:
        img.save(output_path, "JPEG", optimize=True, quality=quality)

compress_image("path_to_image.jpg", "compressed_image.jpg")

Ajuste o parâmetro quality conforme necessário. Valores mais baixos resultarão em maior compressão, mas podem diminuir a qualidade da imagem.

Sem dúvida, as imagens podem aumentar imensamente o impacto dos seus emails. Apenas certifique-se de usar os formatos corretos, otimizar adequadamente e respeitar permissões ao obter de servidores externos.

Limites de tamanho de email do Mailtrap

Anteriormente, mencionamos que o tamanho máximo de uma imagem incorporada em um template de email do Mailtrap é 2 MB. Aqui discutimos o tamanho do email inteiro.

O tamanho máximo de um email inteiro, incluindo todos os anexos, é 10 MB (10240 KB) em todos os planos, Plano Free incluído. Mediante solicitação, os usuários podem obter o limite estendido para até 30 MB (30720 KB).

Como diretriz geral, por favor, certifique-se de que o tamanho total do seu email, incluindo todos os anexos, não ultrapasse o limite definido. Exceder esse limite pode resultar em seu email não sendo enviado ou entregue como esperado.

Enviar emails HTML usando API

As APIs de Email (Interfaces de Programação de Aplicações) oferecem uma maneira mais escalável, eficiente e, muitas vezes, mais simples de enviar emails, em comparação com as configurações tradicionais de SMTP.

Para este tutorial, exploraremos o Mailtrap Python SDK, pois ele oferece uma interface simplificada para enviar, receber e testar emails, tudo enquanto interage com a API do Mailtrap.

Mailtrap-python no GitHub é o repositório oficial do SDK Python do Mailtrap, e a Documentação da API do Mailtrap fornece detalhes aprofundados sobre como aproveitar todo o poder desta ferramenta.

Para começar, você precisará primeiro instalar o SDK.

pip install mailtrap

Agora, aqui está um exemplo básico para enviar um email com uso mínimo de recursos.

import mailtrap as mt

# criar objeto de mail
mail = mt.Mail(
    sender=mt.Address(email="mailtrap@exemplo.com", name="Teste Mailtrap"),
    to=[mt.Address(email="seu@email.com")],
    subject="Você é incrível!",
    text="Parabéns por enviar email de teste com o Mailtrap!",
)

# criar cliente e enviar
client = mt.MailtrapClient(token="sua-chave-api")
client.send(mail)

Lembre-se de substituir "sua-chave-api" pelo seu token de API real do Mailtrap. E você pode encontrar o exemplo completo de uso em nossa página do GitHub.

Se você quiser usar templates com o Mailtrap, veja como criar o objeto de email e enviar.

import mailtrap as mt

# criar objeto de mail
mail = mt.MailFromTemplate(
    sender=mt.Address(email="mailtrap@exemplo.com", name="Teste Mailtrap"),
    to=[mt.Address(email="seu@email.com")],
    template_uuid="2f45b0aa-bbed-432f-95e4-e145e1965ba2",
    template_variables={"user_name": "John Doe"},
)

# criar cliente e enviar
client = mt.MailtrapClient(token="sua-chave-api")
client.send(mail)

A beleza do SDK Python do Mailtrap é que ele permite uma infinidade de personalizações e configurações. Você pode adicionar anexos, utilizar CC/BCC e obter o seguinte:

  1. Simplicidade: Usando o SDK Python do Mailtrap, você pode evitar configurar configurações de SMTP e reduzir o código boilerplate que normalmente é necessário ao enviar emails.
  2. Testabilidade: Mailtrap oferece um ambiente seguro para testar e visualizar seus emails antes de enviá-los para usuários reais, evitando possíveis erros.
  3. Escalabilidade: Se você está construindo aplicações que requerem o envio de um grande volume de emails, usar uma API é frequentemente uma solução melhor do que SMTP devido à sua capacidade inerente de lidar com solicitações em massa.

Dicas:

  • Armazenar credenciais com segurança: Nunca codifique seu token de API ou credenciais. Use variáveis de ambiente ou ferramentas de gerenciamento de segredos.
  • Tratamento de erros: Sempre incorpore o tratamento de erros ao trabalhar com APIs para gerenciar graciosamente quaisquer problemas imprevistos.
  • Monitorar uso: Fique de olho no uso da sua API para garantir que você não esteja atingindo limites de taxa ou excedendo sua cota permitida. A documentação do Mailtrap fornece informações detalhadas sobre limites e cotas.

Testar e enviar emails HTML em ambiente de staging

Enviar emails em HTML sem o devido teste pode levar a problemas de formatação, links quebrados e uma experiência ruim para o usuário. Esta seção destaca a importância dos testes de email e fornece estratégias para testes completos.

  • Consistência: Certifique-se de que seu email apareça consistentemente em diferentes clientes de email (Gmail, Outlook, Apple Mail, etc.) e dispositivos (desktop, móvel).
  • Responsividade móvel: Uma parte significativa das aberturas de email ocorre em dispositivos móveis. Teste para garantir que seus emails sejam compatíveis com dispositivos móveis e sejam exibidos corretamente em várias telas.
  • Links e imagens quebrados: Teste para evitar links e imagens quebrados, para evitar que os usuários encontrem conteúdo ausente ou inacessível.
  • Evasão de spam: Emails formatados corretamente são menos propensos a serem marcados como spam. Testar ajuda a manter uma boa reputação de remetente.
  • Experiência do usuário: Em última análise, testar garante uma experiência positiva para o usuário e pode melhorar as taxas de cliques e o engajamento.

O Mailtrap Email Testing fornece uma solução abrangente para testar emails em HTML. Ele permite que você:

  • Pré-visualize emails em vários clientes de email.
  • Veja como os emails são renderizados em dispositivos móveis.
  • Verifique links e imagens para evitar elementos quebrados.
  • Garanta a compatibilidade com clientes de email.
  • Valide pontuações de spam para melhorar a entregabilidade.

O Mailtrap oferece duas opções para testar seus emails: uma integração simples com SMTP (fornecemos acesso a um SMTP falso) ou você pode automatizar completamente os fluxos de teste com a API correspondente.

As seções a seguir assumem que você já é um usuário do Mailtrap Email Testing. Se não, você pode se inscrever aqui.

Nota importante: Você não precisa adicionar e verificar um domínio para usar o Mailtrap Email Testing.

SMTP

  1. Selecione Email Testing e você verá que já criamos uma caixa de entrada de teste vazia para você, rotulada My Inbox.
  1. Clique na caixa de entrada e selecione Python smtplib na guia Integrations. Também oferecemos snippets de código prontos para Django e Flask-Mail.


Benefício – usando a biblioteca, você não precisa copiar e colar suas credenciais.

  1. Execute o código e seu email de teste deve aparecer em My Inbox em pouco tempo.

Notas importantes:

  • Você pode renomear sua caixa de entrada clicando no ícone de lápis em Action.
  • Por motivos de segurança, mantemos suas credenciais SMTP/POP3 ocultas. E sugerimos que você faça o mesmo. Clicar em Show Credentials as revela.
  • Por padrão, nossos scripts exemplares usam a porta 2525. Mas, dependendo do seu sistema e ambiente, a porta pode estar bloqueada por um firewall. Se for o caso, mude para a porta 587.

API

A API de teste do Mailtrap pode retornar chamadas como objetos JSON e usa o protocolo REST. Além disso, é compatível com a maioria das linguagens de programação.

Pedidos HTTP suportados:

  • POST – criar um recurso
  • PATCH – atualizar um recurso
  • GET – obter um recurso ou lista de recursos
  • DELETE – excluir um recurso

E aqui está como começar:

  1. No Mailtrap, selecione Settings, depois API Tokens
  2. Pegue seu token de API e proceda para enviar requisições HTTP
  3. Use um dos seguintes métodos para enviar o pedido autenticado:
  • Enviar um cabeçalho HTTP Api-Token: {api_token}, onde {api_token} é seu token de API.
  • Enviar um cabeçalho HTTP Authorization: Bearer #{token}, onde #{token} é seu token de API.

Recursos úteis:

  1. API – Testar envio de emails com exemplos Python/Python 3
  2. Ou nosso tutorial no YouTube sobre testes em Python

O ouroboros digital

Esperamos que sua jornada pelo panorama de emails em HTML com Python tenha sido esclarecedora. Exploramos vários métodos, desde bibliotecas nativas do Python até a simplicidade do SDK Python do Mailtrap.

E, agora, você deve já dominar SMTP, gerenciamento de múltiplos destinatários, incorporação de imagens e anexos. Além disso, também destacamos o coração do sucesso do email: testes abrangentes.

As chaves para a entrega bem-sucedida estão em garantir que os emails sejam renderizados de forma consistente, abraçar a responsividade móvel e dançar graciosamente entre os clientes de email.

Com essa sabedoria em seu arsenal, você está pronto não apenas para enviar emails, mas para tecer narrativas envolventes que ressoam profundamente com seus destinatários.

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.