Ícone do site Mailtrap

Como Enviar Emails em Python com Gmail SMTP e API

How to send emails in Python with Gmail

Neste tutorial, usando exemplos de código, vamos cobrir como usar diferentes módulos em Python para construir e enviar vários tipos de mensagens de email, revisar métodos de autenticação existentes e muito mais. Como exemplo, usaremos tanto o servidor SMTP do Gmail quanto a API do Gmail.

Se você quiser saber mais sobre outros métodos de envio de emails em Python, confira nosso guia abrangente.

Configurando as bibliotecas Python de smtplib e email

Para enviar um email com Python via Gmail SMTP, você deve usar o módulo smtplib e o módulo email. O smtplib fornece funções para conectar e enviar emails usando um servidor Simple Mail Transfer Protocol (SMTP).

Quanto ao módulo email, ele fornece classes para construir e analisar mensagens de email (To; From; Subject; etc.) e permite codificar e decodificar emails com o padrão MIME (Multipurpose Internet Mail Extensions).

Vamos detalhar os passos necessários. E, na seção seguinte, você pode conferir o código real.

  1. Importe as bibliotecas necessárias: smtplib e MIMEText do módulo email.
  2. Crie a mensagem de email usando o objeto MIMEText e defina os valores desejados nos campos Subject, From e To.
  3. Estabeleça a conexão SMTP com o servidor do Gmail através de uma conexão SSL segura usando a função SMTP_SSL.
  4. Chame o método sendmail do objeto SMTP e especifique os endereços de email do remetente e dos destinatários e a mensagem de email como argumentos.

Com isso fora do caminho, você está pronto para enviar emails via Gmail em Python. Vou cobrir a metodologia, exemplos e outros casos de uso nas seções seguintes.

Enviar emails em Python usando o SMTP do Gmail

Com base no que cobri na seção anterior, aqui está um script simples para enviar emails:

import smtplib
from email.mime.text import MIMEText

subject = "Assunto do Email"
body = "Este é o corpo da mensagem"
sender = "remetente@gmail.com"
recipients = ["destinatario1@gmail.com", "destinatario2@gmail.com"]
password = "senha"

def send_email(subject, body, sender, recipients, password):
    msg = MIMEText(body)
    msg['Subject'] = subject
    msg['From'] = sender
    msg['To'] = ', '.join(recipients)
    with smtplib.SMTP_SSL('smtp.gmail.com', 465) as smtp_server:
       smtp_server.login(sender, password)
       smtp_server.sendmail(sender, recipients, msg.as_string())
    print("Mensagem enviada!")


send_email(subject, body, sender, recipients, password)

Notas Importantes:

Antes de 30 de maio de 2022, era possível conectar-se ao servidor SMTP do Gmail usando sua senha normal do Gmail se a “verificação em duas etapas” estivesse ativada. Para um padrão de segurança mais alto, o Google agora exige que você use uma “Senha de App” (“App Password”).

Esta é uma senha de 16 dígitos gerada na sua conta do Google que permite que aplicativos ou dispositivos menos seguros que não suportam verificação em duas etapas façam login na sua conta do Gmail.

Alternativamente, existe o modo de autenticação OAuth 2.0 do Gmail, mas nesse caso, você precisará usar o método de envio da API do Gmail em seu script Python.

Enviar emails para vários destinatários

Para enviar o email para vários destinatários, vou definir uma lista de endereços de email para permitir o envio para vários destinatários. Além disso, o campo To define os destinatários nos cabeçalhos da mensagem. Ele é convertido de uma lista para uma string separada por vírgulas, que é um formato aceito pela maioria dos cabeçalhos de email.

Aqui está o código:

import smtplib
from email.mime.text import MIMEText

# Defina o assunto e o corpo do email.
subject = "Assunto do Email"
body = "Este é o corpo da mensagem"
# Defina o endereço de email do remetente.
sender = "remetente@gmail.com"
# Lista de destinatários para os quais o email será enviado.
recipients = ["destinatario1@gmail.com", "destinatario2@gmail.com"]
# Senha para a conta de email do remetente.
password = "senha"

def send_email(subject, body, sender, recipients, password):
    # Crie um objeto MIMEText com o corpo do email.
    msg = MIMEText(body)
    # Defina o assunto do email.
    msg['Subject'] = subject
    # Defina o email do remetente.
    msg['From'] = sender
    # Junte a lista de destinatários em uma única string separada por vírgulas.
    msg['To'] = ', '.join(recipients)
   
    # Conecte-se ao servidor SMTP do Gmail usando SSL.
    with smtplib.SMTP_SSL('smtp.gmail.com', 465) as smtp_server:
        # Faça login no servidor SMTP usando as credenciais do remetente.
        smtp_server.login(sender, password)
        # Envie o email. A função sendmail requer o email do remetente, a lista de destinatários e a mensagem de email como uma string.
        smtp_server.sendmail(sender, recipients, msg.as_string())
    # Imprima uma mensagem no console após enviar o email com sucesso.
    print("Mensagem enviada!")

# Chame a função para enviar o email.
send_email(subject, body, sender, recipients, password)

Enviar emails com anexos

Você precisa importar as bibliotecas necessárias. Neste caso, você também precisará de MIMEBase, que permite representar um arquivo de anexo, e encoders, que são usados para codificar o anexo no formato base64.

Aqui está o script completo, incluindo comentários que ajudarão você a entender como enviar um email com anexos:

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

sender_email = "remetente@gmail.com"
sender_password = "password"
recipient_email = "destinatario@gmail.com"
subject = "Oi, a partir de Python"
body = "com anexo"

with open("attachment.txt", "rb") as attachment:
    # Adicione o anexo à mensagem
    part = MIMEBase("application", "octet-stream")
    part.set_payload(attachment.read())
encoders.encode_base64(part)
part.add_header(
    "Content-Disposition",
    f"attachment; filename= 'attachment.txt'",
)

message = MIMEMultipart()
message['Subject'] = subject
message['From'] = sender_email
message['To'] = recipient_email
html_part = MIMEText(body)
message.attach(html_part)
message.attach(part)

with smtplib.SMTP_SSL('smtp.gmail.com', 465) as server:
   server.login(sender_email, sender_password)
   server.sendmail(sender_email, recipient_email, message.as_string())

Enviar emails HTML

Assim como você faria com uma mensagem de email normal, para enviar um email HTML usando o servidor SMTP do Gmail em Python, use a classe MIMEText do pacote email. Depois disso, use o objeto html_message em vez do objeto de texto simples msg e cole o conteúdo HTML no corpo do email.

Here is a full code example: 

import smtplib
from email.mime.text import MIMEText

sender_email = "remetente@gmail.com"
sender_password = "senha"
recipient_email = "destinatario@gmail.com"
subject = "Oi, a partir de Python"
body = """
<html>
  <body>
    <p>Este é um email em <b>HTML</b> enviado a partir de Python usando o servidor SMTP do Gmail.</p>
  </body>
</html>
"""
html_message = MIMEText(body, 'html')
html_message['Subject'] = subject
html_message['From'] = sender_email
html_message['To'] = recipient_email
with smtplib.SMTP_SSL('smtp.gmail.com', 465) as server:
   server.login(sender_email, sender_password)
   server.sendmail(sender_email, recipient_email, html_message.as_string())

Se você quiser enviar um email usando um template HTML em vez de ter o HTML no corpo, você pode usar a classe Template do pacote jinja2, um mecanismo de template rápido, expressivo e extensível.

pip install jinja2

Aqui está o script para todas as etapas necessárias:

import smtplib
from email.mime.text import MIMEText
from jinja2 import Template

sender_email = "remetente@gmail.com"
sender_password = "senha"
recipient_email = "destinatario@gmail.com"
with open('template.html', 'r') as f:
    template = Template(f.read())
context = {
    'subject': 'Oi, a partir de Python',
    'body': 'Este é um email enviado a partir de Python usando o um template HTML e o servidor SMTP do Gmail.'
}
html = template.render(context)
html_message = MIMEText(context['body'], 'html')
html_message['Subject'] = context['subject']
html_message['From'] = sender_email
html_message['To'] = recipient_email
with smtplib.SMTP_SSL('smtp.gmail.com', 465) as server:
   server.login(sender_email, sender_password)
   server.sendmail(sender_email, recipient_email, html_message.as_string())

Se você quiser aprender mais sobre como enviar conteúdo dinâmico do seu aplicativo Python, recomendamos conferir nosso artigo sobre Mail Merge.

Enviar emails em massa

Vou mostrar como enviar emails em massa via Gmail, mas lembre-se de que isso é apenas uma demonstração, não um método que você deve executar em produção.

O Gmail tem políticas bastante rígidas sobre o envio de emails em massa e campanhas, falarei sobre isso em uma seção posterior (clique no link para pular). Além disso, sua capacidade de entrega pode sofrer, especialmente com um domínio novo ou uma classificação de domínio relativamente baixa. Ou se você tentar enviar de um endereço @gmail.com.

Com isso em mente, o script abaixo é adaptado para cenários onde cada destinatário deve receber um email separado e individual, o que é comum em campanhas de marketing personalizadas, notificações, etc.

Basicamente, a mesma mensagem é enviada para várias pessoas sem agrupá-las em um único email. Este método também evita a divulgação da lista de destinatários entre si, preservando a privacidade.

Confira o script abaixo.

import smtplib
from email.mime.text import MIMEText

# Conteúdo do email
subject = "Assunto do Email"
body = "Este é o corpo da mensagem"
sender = "remetente@gmail.com"
recipients = ["destinatario1@gmail.com", "destinatario2@gmail.com", "destinatario3@gmail.com"]  # Lista de destinatários
password = "senha"

def send_bulk_emails(subject, body, sender, recipients, password):
    # Conecte-se ao servidor SMTP do Gmail usando SSL
    with smtplib.SMTP_SSL('smtp.gmail.com', 465) as smtp_server:
        smtp_server.login(sender, password)  # Fazer login no servidor

        # Loop sobre cada destinatário e envio de um email individual
        for recipient in recipients:
            msg = MIMEText(body)  # Crie um objeto MIMEText com o corpo do email
            msg['Subject'] = subject  # Defina o assunto do email
            msg['From'] = sender  # Defina o remetente
            msg['To'] = recipient  # Defina o destinatário atual

            smtp_server.sendmail(sender, recipient, msg.as_string())  # Envie o email
            print(f"Mensagem enviada para {recipient}!")

# Chame a função para enviar emails em massa
send_bulk_emails(subject, body, sender, recipients, password)

Agora, gostaria de dar uma rápida explicação para explorar como tudo funciona:

  1. Na inicialização, o script define o assunto, corpo, endereço de email do remetente, lista de destinatários e senha.
  2. Com send_bulk_emails, o script faz uma conexão segura com o servidor SMTP do Gmail na porta 465 via smtplib.SMTP_SSL. Após estabelecer a conexão, o script faz login no servidor SMTP usando as credenciais do Gmail do remetente.
  3. Então, o script percorre os destinatários, fazendo o seguinte para cada um deles:

A vantagem desse método é que cada mensagem é registrada ou tratada separadamente. Isso ajuda a rastrear o sucesso de cada email enviado de forma mais eficiente, o que é crucial para operações em massa.

Enviar emails em Python usando a API do Gmail

A API do Gmail é uma API RESTful que permite que seu aplicativo envie e receba emails usando os servidores de email do Google. Além disso, ela permite que você recupere e gerencie mensagens e use recursos do Gmail, como etiquetas, threads, etc.

Vamos analisar cada etapa do envio de um email com Python via API do Gmail usando autenticação OAuth2.

  1. Configure um projeto no Google Cloud Platform, clique no menu de hambúrguer e selecione ver todos os produtos. Na seção de gerenciamento, selecione APIs e serviços.
  1. Em seguida, selecione Biblioteca e digite “Gmail API” na barra de pesquisa e clique na carta da API do Gmail.
  1. Finalmente, selecione o botão para habilitar a API do Gmail.
  1. Agora, você precisará baixar o arquivo de segredos do cliente para seu projeto. Comece selecionando Criar Credenciais. Nesta seção, selecione a API do Gmail como sua API preferida e os dados do usuário como o tipo de dados que você acessará.
  1. Para obter o ID do cliente OAuth, selecione seu tipo de aplicativo como Aplicativo Desktop, defina o nome do aplicativo e selecione criar. Em seguida, baixe e armazene as credenciais no seu sistema de arquivos local.

Após baixar o arquivo de segredos, você deve ter o arquivo neste formato:

{
    "installed": {
        "client_id": "463220703866-un8ijck75igunsbh4nhclm74edprhj5p.apps.googleusercontent.com",
        "project_id": "geocaching-366015",
        "auth_uri": "https://accounts.google.com/o/oauth2/auth",
        "token_uri": "https://oauth2.googleapis.com/token",
        "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
        "client_secret": "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",
        "redirect_uris": [
            "http://localhost"
        ]
    }
}

Antes de começar com o código, você precisará instalar as bibliotecas google-auth, google-auth-oauthlib, google-auth-httplib2 e google-api-python-client usando o comando:

pip install google-auth google-auth-oauthlib google-auth-httplib2 google-api-python-client

Depois de instalar com sucesso as bibliotecas, você criará uma variável chamada SCOPES que conterá uma lista de strings que especificam as permissões que um aplicativo tem ao acessar os dados de um usuário.

Neste ponto, crie outra variável chamada flow que usará a classe InstalledAppFlow para criar um fluxo OAuth 2.0 para um aplicativo instalado e especifica os escopos OAuth 2.0 que o aplicativo precisa na variável SCOPES.

O código então inicia o fluxo OAuth 2.0 chamando o método run_local_server e especificando um número de porta, o que inicia um servidor web local para lidar com o fluxo de autorização e retornar as credenciais OAuth 2.0 quando o fluxo estiver completo.

Em seguida, construa o serviço Gmail chamando a função build do módulo googleapiclient.discovery, passando gmail no nome do serviço e v1 na versão como argumentos, e levando em consideração as credenciais que você chamou anteriormente.

Agora, construa a mensagem de email criando um objeto MIMEText e definindo os campos to e subject para os valores desejados. Além disso, codifique a mensagem de email como uma string base64-encoded.

Finalmente, você pode enviar o email chamando o método send do recurso messages e passando o dicionário create_message como o corpo da solicitação.

É assim que o código Python fica quando todos esses passos são colocados juntos:

import base64
from email.mime.text import MIMEText
from google_auth_oauthlib.flow import InstalledAppFlow
from googleapiclient.discovery import build
from requests import HTTPError
SCOPES = [
        "https://www.googleapis.com/auth/gmail.send"
    ]
flow = InstalledAppFlow.from_client_secrets_file(
            'credentials.json', SCOPES)
creds = flow.run_local_server(port=0)
service = build('gmail', 'v1', credentials=creds)
message = MIMEText('Este é o corpo do email')
message['to'] = 'destinatario@gmail.com'
message['subject'] = 'Assunto do Email'
create_message = {'raw': base64.urlsafe_b64encode(message.as_bytes()).decode()}
try:
    message = (service.users().messages().send(userId="me", body=create_message).execute())
    print(F'mensagem enviada para {message} Message Id: {message["id"]}')
except HTTPError as error:
    print(F'Ocorreu um erro: {error}')
    message = None

E é só isso! Com apenas algumas linhas de código, você pode adicionar uma funcionalidade rápida de envio de emails ao aplicativo que está construindo, e claro, não se esqueça de validar os endereços de email coletados dos seus usuários.

Limitações do Gmail SMTP e API

Usar a API ou SMTP do Gmail é uma opção conveniente e confiável para a automação do envio de emails, mas, como mencionado, tem algumas limitações.

Para garantir que um único usuário ou aplicativo não consuma muitos recursos, a API limita o número de emails que você pode enviar diariamente e tem um limite máximo de tamanho de email. Para números precisos sobre essas limitações, consulte a documentação do Google.

A API pode não suportar todas as funcionalidades disponíveis na interface web do Gmail, como a capacidade de agendar emails para serem enviados posteriormente ou usar certos tipos de formatação ou anexos.

Quando você autentica seu aplicativo, deve solicitar os escopos (scopes) OAuth apropriados para acessar os dados de que precisa. O usuário deve então conceder ao seu aplicativo acesso aos seus dados. Sem os escopos OAuth apropriados, suas solicitações para acessar os dados do usuário serão negadas e resultarão em um erro.

A API do Gmail está sujeita a um limite de uso diário, que se aplica a todas as solicitações feitas a partir do seu aplicativo, e limites de taxa por usuário. Cada limite é identificado em termos de unidades de cota, ou uma unidade abstrata de medição representando o uso de recursos do Gmail.

Por exemplo, enviar uma mensagem consome 100 unidades de cota, enquanto a maioria das outras ações, como buscar uma mensagem ou criar um rascunho, consomem muito menos unidades de cota.

O acesso SMTP do Gmail tem limites rigorosos para prevenir abuso e garantir a disponibilidade do serviço. Tipicamente, esses limites são menores do que os da API do Gmail, muitas vezes restringindo os usuários a enviar menos emails por dia.

Assim como a API, o serviço SMTP limita o tamanho dos anexos de email. O tamanho total do email (corpo e anexos) não deve exceder 25 MB.

Se muitas conexões ou tentativas de autenticação forem feitas em um curto período, o Gmail pode fazer throttle da sua conexão, limitando temporariamente sua capacidade de enviar mais emails. Isso faz parte do esforço do Gmail para identificar e prevenir possíveis comportamentos de spam ou abuso através do SMTP.

Existe uma alternativa à infraestrutura de email do Gmail?

A resposta curta é sim.

Existem muitas alternativas para usar o servidor SMTP do Gmail para enviar emails. Você pode usar qualquer outro provedor de email de sua escolha. É importante garantir que a infraestrutura do servidor deles atenda às suas necessidades e requisitos.

Outra opção é usar um provedor de serviço de email de terceiros com uma API que permite enviar emails do seu próprio aplicativo usando os servidores deles. Além disso, antes de implementar a funcionalidade de envio de email no seu aplicativo, é importante testá-la.

É aqui que entra a Plataforma de Email Delivery do Mailtrap.

A plataforma oferece Serviço de API/SMTP de Email, que é usado para entregar emails enquanto lhe dá mais controle sobre sua infraestrutura de email, e Email Sandbox, uma ferramenta que permite testar e depurar esses emails antes que sejam enviados.

Se você quiser usar a API de Email da Mailtrap com seu aplicativo Python, após verificar o nome do seu domínio, vá para a seção Sending Domains e selecione a guia API and SMTP. No menu dropdown, selecione Python e copie e cole o código gerado com suas credenciais no seu script.

Dica: Confira a documentação oficial do GitHub sobre o SDK Python da Mailtrap.

import requests

url = "https://send.api.mailtrap.io/api/send"

payload = "{\"from\":{\"email\":\"mailtrap@mailtrap.club\",\"name\":\"Teste Mailtrap\"},\"to\":[{\"email\":\"exemplo@railsware.com\"}],\"subject\":\"Você é incrível!\",\"text\":\"Parabéns por enviar um email de teste com Mailtrap!\",\"category\":\"Integration Test\"}"
headers = {
  "Authorization": "Bearer 48d3783bde8152*******************",
  "Content-Type": "application/json"
}

response = requests.request("POST", url, headers=headers, data=payload)

print(response.text)

Você também pode selecionar o método SMTP e copiar as configurações relevantes do aplicativo. Apenas certifique-se de escolher o fluxo de envio correto – Transacional ou Bulk, dependendo do tipo de emails que você deseja enviar.

Aqui está um exemplo:

import smtplib
from email.mime.text import MIMEText

# Defina o conteúdo do email e as credenciais
subject = "Assunto do Email"
body = "Este é o corpo do email."
sender_email = "remetente@gmail.com"
receiver_email = "destinatario@gmail.com"
password = "sua_senha"  # Tenha cuidado com senhas no código!

# Crie o objeto MIMEText
message = MIMEText(body)
message['Subject'] = subject
message['From'] = sender_email
message['To'] = receiver_email

# Conecte-se ao servidor SMTP do Gmail
with smtplib.SMTP('live.smtp.mailtrap.io', 587) as server:  # Observe o uso da porta 587 para STARTTLS
    server.ehlo()  # Pode ser chamado opcionalmente (É chamado automaticamente após uma conexão)
    server.starttls()  # Proteja a conexão
    server.ehlo()  # Pode ser chamado opcionalmente (Ele se re-identifica para o servidor após o STARTTLS)
    server.login(sender_email, password)
    server.send_message(message)  # Envie o email

    print("Email enviado com sucesso!")

Notas:

Teste e envio de emails em staging

Testar a eficácia dos seus emails é crucial para garantir que sejam entregues com sucesso e formatados adequadamente.

Um sandbox de email oferece uma variedade de recursos para ajudá-lo a fazer exatamente isso. Capturando o tráfego SMTP, permite que você analise o conteúdo do email quanto à pontuação de spam, valide HTML/CSS, revise dados brutos e muito mais, garantindo que seus emails sejam formatados corretamente e entregues com sucesso.

Aqui, usarei o Email Testing da Mailtrap para mostrar como utilizar um sandbox via SMTP ou API.

SMTP

O Email Testing da Mailtrap pode ser facilmente integrado ao seu aplicativo Python em apenas alguns cliques. Tudo o que você precisa fazer é copiar as credenciais SMTP geradas pelo aplicativo e colá-las no seu código.

Depois, escolha um dos exemplos de código Python disponíveis em Integrações e execute-o para ver o teste em ação. Claro, nosso exemplo de código padrão pode ser adaptado às suas necessidades.

API

Se você deseja automatizar fluxos de teste de QA e ter mais controle sobre o teste, a API do Mailtrap Email Testing é o caminho a seguir.

Aqui, vou mostrar como configurar tudo, claro, assumindo que você já é um usuário. E você pode conferir todos os detalhes na nossa documentação oficial da API.

import http.client
import json

def test_send_email():
    conn = http.client.HTTPSConnection("sandbox.api.mailtrap.io")
   
    payload = {
        "to": [{"email": "john_doe@exemplo.com", "name": "John Doe"}],
        "cc": [{"email": "jane_doe@exemplo.com", "name": "Jane Doe"}],
        "bcc": [{"email": "james_doe@exemplo.com", "name": "Jim Doe"}],
        "from": {"email": "vendas@exemplo.com", "name": "Equipa de Vendas Exemplo"},
        "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.mydomain.com"},
        "subject": "Sua Confirmação de Encomenda Exemplo",
        "text": "Parabéns pela sua encomenda nº 1234",
        "category": "API Test"
    }

    headers = {
        'Content-Type': "application/json",
        'Accept': "application/json",
        'Api-Token': "seu_token_api_aqui"  # Substitua pelo seu token real da API
    }

    # Converta o payload para uma string JSON
    json_payload = json.dumps(payload)

    # Faça a solicitação POST
    conn.request("POST", "/api/send/inbox_id", json_payload, headers)  # Substitua 'inbox_id' pelo seu ID real da caixa de entrada

    # Obtenha a resposta
    response = conn.getresponse()
    data = response.read()

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

if __name__ == "__main__":
    test_send_email()

O script acima se conecta à API do Mailtrap Email Testing via http.client.HTTPSConnection. O conteúdo do email, incluindo assunto, texto, destinatários, etc., é definido como payload JSON. E a solicitação POST é feita com o payload que você definiu.

Pro Tips:

Concluindo

Esperamos que isso ajude você a desenvolver a funcionalidade de envio de email no seu aplicativo! Apenas lembre-se, antes de começar a construí-lo, certifique-se de pesquisar qual framework Python quer usar, pois cada um tem seu próprio conjunto de recursos e benefícios:

Sair da versão mobile