Como Enviar Emails no Flask usando SMTP ou API

On junho 06, 2024
16min read
Piotr Malek Technical Content Writer @ Mailtrap
Ivan Djuric, an author at Mailtrap
Ivan Djuric Technical Content Writer @Mailtrap

Neste tutorial sobre como enviar emails no Flask, vou mostrar como usar a extensão Flask-Mail e enviar emails via SMTP ou API.

Vou também demonstrar como você pode testar suas mensagens de email antes de enviá-las para garantir que elas cheguem às caixas de entrada dos seus destinatários perfeitamente.

Então, vamos diretos ao assunto.

Preparando a configuração do Flask-Mail

Primeiro de tudo, vamos configurar o Flask-Mail, uma extensão do Flask para enviar emails.

Já tem tudo configurado? Para pular para a configuração do SMTP clique aqui, ou para a configuração da API, clique aqui.

Instale Flask e Flask-Mail

Vamos começar instalando a versão mais recente do Flask do Python Package Index (PyPI) executando o seguinte comando:

pip install Flask

Em seguida, vamos instalar o Flask-Mail com:

pip install Flask-Mail

Ou, você também pode executar este comando para baixar a versão mais recente diretamente do código-fonte:

git clone https://github.com/mattupstate/flask-mail.git
cd flask-mail
python setup.py install

Dica:

  • Eu assumo que você está usando a versão mais recente do Python 3, mas se você tiver várias versões do Python instaladas, pode precisar usar python3 em vez de python ou py para os comandos, dependendo da configuração do seu sistema.

Adicione e configure virtualenv ou venv (opcional)

Esta é uma etapa opcional, mas, se você quiser isolar este ambiente, pode usar:

  • venv – O módulo venv integrado do Python está disponível por padrão com Python 3.3+ e é usado como um módulo padrão devido à sua simplicidade e inclusão no Python.
  • virtualenv – Uma ferramenta de terceiros para criar ambientes virtuais no Python, usada principalmente por alguns de seus recursos não disponíveis no venv, como a capacidade de criar ambientes virtuais para versões do Python diferentes da instalada.

Para utilizar o módulo venv integrado do Python, abra o terminal e navegue até a pasta que você usará para este projeto e, com base no sistema operacional que você está usando, digite um destes dois comandos:

python -m venv new_environment (macOS or Linux)
py -m venv new_environment (Windows)

Você deve então substituir novo_ambiente por qualquer nome que você quiser dar ao ambiente e ativá-lo, assim:

source new_environment/bin/activate (macOS ou Linux)
.\new_environment\Scripts\activate (Windows)

Certifique-se de que você tem o prompt de comando ou terminal em execução como administrador nos sistemas (particularmente Windows) para evitar possíveis problemas de permissão.

No entanto, se você quiser usar virtualenv, você deve instalar pip e garantir que ele esteja atualizado. Você pode instalá-lo executando o seguinte comando:

pip install virtualenv

Notas:

  • Se você quiser usar virtualenv, eu recomendo que você instale Flask-mail no mesmo virtualenv que seu aplicativo Flask.
    • Ao fazer isso, você previne conflitos entre diferentes projetos ou instalações do Python em todo o sistema, garantindo que todas as dependências sejam gerenciadas dentro do ambiente isolado.
  • Para evitar que os arquivos do ambiente virtual sejam desnecessariamente carregados para sistemas de controle de versão e manter seus repositórios limpos e leves, você deve excluir o diretório do ambiente (por exemplo, novo_ambiente) do controle de versão, adicionando-o ao arquivo .gitignore.
  • Para sair do ambiente virtual, execute o comando deactivate.

Enviar emails no Flask usando SMTP

Agora que temos nossa configuração pronta, vamos começar a enviar emails via SMTP!

1. Importe as classes necessárias

No Flask-Mail, o envio de email é gerenciado por uma instância da classe Mail e da classe Message, que você precisa importar para o seu arquivo .py com o seguinte código:

from flask import Flask
from flask_mail import Mail, Message

app = Flask(__name__)

mail = Mail(app)

2. Insira as credenciais SMTP

Em seguida, você precisa inserir as credenciais SMTP do seu provedor de email no seu aplicativo Flask. Neste artigo, usarei a plataforma Mailtrap Email Delivery, pois ela me oferece um serviço de SMTP fiável com capacidades robustas de envio.

Para fazer isso, crie uma conta no Mailtrap, faça login e navegue até Sending Domains, onde você pode adicionar e verificar seu domínio em questão de segundos.

Uma vez que seu domínio esteja verificado, o Mailtrap o levará à página com as credenciais SMTP.

Vou usar o Stream Transacional agora e mostrar como usar o Stream Bulk mais adiante no artigo.

Veja como seu código deve ficar com as credenciais SMTP inseridas:

app.config['MAIL_SERVER']= 'live.smtp.mailtrap.io'
app.config['MAIL_PORT'] = 587
app.config['MAIL_USERNAME'] = 'seu_email@endereco.com'
app.config['MAIL_PASSWORD'] = 'sua_senha'
app.config['MAIL_USE_TLS'] = True
app.config['MAIL_USE_SSL'] = False

3. Configure um objeto Message

Por fim, precisamos configurar um objeto Message, mapeado pela regra de URL (‘/’), e inserir os detalhes básicos da nossa mensagem:

@app.route("/")
def index():
    msg = Message(subject='Olá do outro lado!', sender='peter@mailtrap.io', recipients=['paul@mailtrap.io'])
    msg.body = "Oi Paul, estou te enviando este email do meu aplicativo Flask, me avise se funcionar"
    mail.send(msg)
    return "Mensagem enviada!"

E aqui está como o código deve ficar no final:

from flask import Flask
from flask_mail import Mail, Message

app = Flask(__name__)

app.config['MAIL_SERVER']= 'live.smtp.mailtrap.io'
app.config['MAIL_PORT'] = 587
app.config['MAIL_USERNAME'] = 'seu_email@gmail.com'
app.config['MAIL_PASSWORD'] = 'sua_senha'
app.config['MAIL_USE_TLS'] = True
app.config['MAIL_USE_SSL'] = False
mail = Mail(app)


@app.route("/")
def index():
    msg = Message(subject='Olá do outro lado!', sender='peter@mailtrap.io', recipients=['paul@mailtrap.io'])
    msg.body = "Oi Paul, estou te enviando este email do meu aplicativo Flask, me avise se funcionar."
    mail.send(msg)
    return "Mensagem enviada!"

if __name__ == '__main__':
    app.run(debug=True)

Tips:

  • Você pode executar o script no Python Shell, abrir http://localhost:5000/ e verificar se o email chegou na sua caixa de entrada.
  • Se você planeja enviar emails do mesmo endereço, pode especificar o nome de exibição para o remetente, assim:
msg = Message('Olá do outro lado!', sender=('Peter from Mailtrap', 'peter@mailtrap.io'), recipients=['paul@mailtrap.io'])
  • Para evitar riscos de segurança, lembre-se de desativar o modo debug em produção configurando debug=False.
  • Ao mover para um ambiente de produção, recomendo não colocar as credenciais diretamente no código. Em vez disso, sugiro armazená-las em variáveis de ambiente e atualizá-las rapidamente sem reescrever o código, assim:
app.config['MAIL_USERNAME'] = os.environ.get('MAIL_USERNAME')
app.config['MAIL_PASSWORD'] = os.environ.get('MAIL_PASSWORD')

Enviar emails em HTML

Enviar email HTML no Flask é fácil porque você pode usar o atributo html do objeto Message:

msg.body = "Oi Paul, estou te enviando este email do meu aplicativo Flask, me avise se funciona"
msg.html = "<b>Oi Paul</b>, estou te enviando este email do meu <a href='https://google.com'>aplicativo Flask</a>, me avise se funcionar"

Enviar emails para múltiplos destinatários

Enviar emails para múltiplos destinatários no Flask é simples porque você pode adicionar alguém em cc e/ou bcc, definir um endereço reply-to, adicionar cabeçalhos extras e assim por diante.

Confira alguns dos parâmetros que você pode usar:

flask_mail.Message(subject='', recipients=None, body=None, sender=None, cc=None, bcc=None, reply_to=None, date=None, charset=None, extra_headers=None, mail_options=None, rcpt_options=None)

Para fins explicativos, aqui está um exemplo de um trecho de código para enviar email para múltiplos destinatários no Flask:

from flask import Flask
from flask_mail import Mail, Message

app = Flask(__name__)

app.config['MAIL_SERVER']= 'live.smtp.mailtrap.io'
app.config['MAIL_PORT'] = 587
app.config['MAIL_USERNAME'] = 'seu_email@gmail.com'
app.config['MAIL_PASSWORD'] = 'sua_senha'
app.config['MAIL_USE_TLS'] = True
app.config['MAIL_USE_SSL'] = False
mail = Mail(app)

@app.route("/send-email")
def send_email_to_multiple_recipients():
    # Lista de destinatários
    recipients = ["usuario1@exemplo.com", "usuario2@exemplo.com", "usuario3@exemplo.com"]

    # Criando a mensagem
    msg = Message("Email para Múltiplos Destinatários",
                  sender="seu_email@exemplo.com",
                  recipients=recipients)
    msg.body = "Oi Paul, estou te enviando este email do meu aplicativo Flask, me avise se funcionar."
    
    # Enviando o email
    mail.send(msg)
    
    return "Email enviado para múltiplos destinatários!"

if __name__ == "__main__":
    app.run(debug=True)

Enviar emails com anexos

Para adicionar um anexo à sua mensagem, basta carregá-lo com o método open_resource() e usar uma declaração with do Python para adicionar o arquivo ao seu email, assim:

with app.open_resource("fatura.pdf") as fp:  
    msg.attach("fatura.pdf", "application/pdf", fp.read()) 

Não se esqueça de escolher um tipo MIME adequado para cada arquivo e fazer upload de cada arquivo no mesmo diretório do seu script.

No entanto, se o arquivo que você deseja anexar não estiver em um diretório de recursos gerenciado pelo Flask (por exemplo, pasta static), você pode usar a função open() integrada do Python para ler o arquivo.

Aqui está um exemplo:

with open("fatura.pdf", "rb") as fp:
    msg.attach("fatura.pdf", "application/pdf", fp.read())

Enviar emails com uma imagem incorporada

Para incorporar imagens em seus emails, você pode usar o parâmetro content_id do método attach e referenciar o ID do conteúdo no corpo HTML da sua mensagem com a sintaxe cid:content_id.

Por exemplo:

@app.route('/send-email-with-image')
def send_email_with_image():
    msg = Message("Email com Imagem Incorporada",
                  sender="seu_email@exemplo.com",
                  recipients=["destinatario@exemplo.com"])
    
    # O corpo HTML com a imagem incorporada
    msg.html = """
    <html>
        <body>
            <p>Aqui está uma imagem incorporada:</p>
            <img src="cid:image1">
        </body>
    </html>
    """
    
    # Anexar a imagem
    with app.open_resource("imagem.jpg") as fp:
        msg.attach("imagem.jpg", "image/jpeg", fp.read(), headers=[('Content-ID', '<image1>')])
    
    mail.send(msg)
    
    return "Email enviado com uma imagem incorporada!"

Envio assíncrono de emails

Para envio assíncrono de emails no Flask, você pode usar:

  • Threading

O Thread do Python é um método poderoso para multitarefa amplamente usado para tarefas como download de arquivos, manipulação de entrada do usuário e outras operações de E/S. No entanto, também é muito viável para envio assíncrono de emails.

Aqui está um exemplo de trecho de código:

```python
import threading

def send_async_email(app, msg):
with app.app_context():
mail.send(msg)

def send_email(subject, sender, recipients, body):
msg = Message(subject, sender=sender, recipients=recipients)
msg.body = body
thr = threading.Thread(target=send_async_email, args=[app, msg])
thr.start()

```
  • Celery

Simplificando, o Celery é uma ferramenta para distribuir trabalho entre threads e máquinas. 🥬

Quando um email é enviado, um aplicativo Flask chama uma tarefa Celery que assume o processo de conexão ESP, para que seu aplicativo possa responder rapidamente e exibir uma mensagem de agradecimento a um usuário quase instantaneamente.

Para instalar o Celery, execute o seguinte comando:

pip install celery

Observe que o Celery não é mais compatível com Windows, então teremos que configurar a seguinte variável, conforme sugerido no tópico do repositório:

import os
os.environ.setdefault('FORKED_BY_MULTIPROCESSING', '1')

Como o Celery requer algo para armazenar sua fila de tarefas, podemos usar o Redis. Se você não tem certeza se o tem instalado, você pode usá-lo através do Docker com o seguinte comando:

docker run -d -p 6379:6379 redis

Agora precisamos instalar a dependência do Python para usar o Redis:

pip install redis

Em seguida, precisamos configurar uma variável Celery, que cuidará da conexão com o Redis.

Lembre-se de que ela precisa estar disponível no arquivo onde você definirá suas tarefas para executar em segundo plano mais tarde. Por exemplo, você pode mantê-la no mesmo arquivo que já estamos usando para as rotas Flask.

celery = Celery(app.name, broker='redis://localhost:6379/0')

Devemos também adicionar mais uma variável para componentes criptográficos (por exemplo, assinar cookies) para completar nossa configuração:

app.config['SECRET_KEY'] = 'not_a_secret'

Além disso, você pode escolher um destinatário personalizado de um formulário enviado:

@app.route('/', methods=['GET', 'POST'])
def index():
    if request.method == 'GET':
        return render_template('index.html', email=session.get('email', ''))
    email = request.form['email']

    email_data = {
        'subject': 'Olá do outro lado!',
        'to': email,
        'body': 'Oi Paul, estou te enviando este email do meu aplicativo Flask, me avise se funcionar'
    }

    send_async_email.delay(email_data)
    flash(f'Enviando email para {email}')

    return redirect(url_for('index'))

Enviamos este email com o método send_async_email, invocado por delay(). Como último passo, especifique a tarefa em segundo plano que o Celery deve executar:

@celery.task
def send_async_email(email_data):
    msg = Message(email_data['subject'],
                  sender=app.config['MAIL_DEFAULT_SENDER'],
                  recipients=[email_data['to']])
    msg.body = email_data['body']
    with app.app_context():
        mail.send(msg)

Se você fizer uma solicitação imediata, uma tarefa será colocada na fila do Celery para enviar um email. Mas, como ainda não há nada processando essa fila, você precisa executar um processo Celery separado, que pegará as tarefas da fila e as processará.

Para fazer isso, execute o seguinte comando em um terminal separado:

celery -A main.celery worker --loglevel=INFO

Observe que main é o nome do seu arquivo Python, e celery é o nome da sua variável Celery.

Envio de emails em massa

Para enviar emails em massa no Flask, usaremos a declaração with do Python, que mantém as conexões com nosso email ativas até que todas as mensagens tenham sido enviadas, momento em que elas serão fechadas automaticamente.

Para isso, você pode usar o seguinte código:

users = [{"email": "paul@mailtrap.io"}, {"email": "peter@mailtrap.io"}]
with mail.connect() as conn:
    for user in users:
        sender = "teste@mailtrap.io"
        message = "..."
        subject = "Olá do outro lado!"
        msg = Message(recipients=[user["email"]],
                      body=message,
                      subject=subject,
                      sender=sender)

        conn.send(msg)

Você também deve utilizar o Bulk Stream do Mailtrap mencionado anteriormente no artigo, que é otimizado para volumes de envio mais altos.

Simplesmente faça login na sua conta Mailtrap, navegue até a aba SMTP/API Settings e copie as credenciais do Bulk Stream localizadas à direita.

Veja como o código deve ficar quando colocado junto:

from flask import Flask
from flask_mail import Mail, Message

app = Flask(__name__)

# Configuração de exemplo - substitua pelas suas credenciais do Mailtrap Bulk Stream
app.config['MAIL_SERVER'] = 'bulk.smtp.mailtrap.io'
app.config['MAIL_PORT'] = 2525
app.config['MAIL_USE_TLS'] = True
app.config['MAIL_USERNAME'] = 'your_mailtrap_username'
app.config['MAIL_PASSWORD'] = 'your_mailtrap_password'
app.config['MAIL_DEFAULT_SENDER'] = 'test@mailtrap.io'

mail = Mail(app)

# Lista fictícia de usuários
users = [{"email": "paul@mailtrap.io"}, {"email": "peter@mailtrap.io"}]

# Função para enviar emails em massa
def send_bulk_emails():
    with app.app_context():  # Certifique-se de que está dentro de um contexto de aplicativo
        with mail.connect() as conn:
            for user in users:
                message = "..."
                subject = "Olá do outro lado!"
                msg = Message(recipients=[user["email"]],
                              body=message,
                              subject=subject)
                conn.send(msg)

if __name__ == '__main__':
    send_bulk_emails()

E voila, você tem uma configuração para envio de emails em massa!

Dica: Se você quiser especificar o número máximo de emails a serem enviados, use MAIL_MAX_EMAILS na configuração, pois nenhum limite é definido por padrão.

Enviar emails no Flask usando API

Se você prefere automatizar seu processo de envio de emails, você pode usar o cliente oficial Python fornecido pelo Mailtrap Email Sending.

Para integrá-lo, faça login na sua conta Mailtrap e navegue até SettingsAPI Tokens. Lá, você encontrará suas credenciais, que deve copiar junto ao seu domínio de envio verificado.

Em seguida, volte para o seu aplicativo ou projeto Flask e instale a versão 2.0.0 ou superior do pacote:

pip install mailtrap

Uma vez que você tenha o pacote instalado, você pode enviar um email simples com o seguinte trecho de código:

import mailtrap as mt

# criar objeto de email
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 Mailtrap!",
)

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

E não se esqueça de substituir sua-chave-api pela chave de API real fornecida pelo Mailtrap e modificar variáveis como sender (email e nome), to (destinatário), subject e text.

Enviar emails em HTML

Para enviar email HTML, usaremos o parâmetro html dentro do objeto mt.Mail:

html="""
<!doctype html>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  </head>
  <body style="font-family: sans-serif;">
    <div style="display: block; margin: auto; max-width: 600px;" class="main">
      <h1 style="font-size: 18px; font-weight: bold; margin-top: 20px">
        Parabéns por enviar email de teste com Mailtrap!
      </h1>
      <p>Inspecione-o usando as abas que você vê acima e aprenda como este email pode ser melhorado.</p>
      <img alt="Inspecionar com Abas" src="cid:welcome.png" style="width: 100%;">
      <p>Agora envie seu email usando nosso servidor SMTP falso e a integração de sua escolha!</p>
      <p>Boa sorte! Espero que funcione.</p>
    </div>
    <!-- Exemplo de HTML/CSS inválido para email, será detectado pelo Mailtrap: -->
    <style>
      .main { background-color: white; }
      a:hover { border-left-width: 1em; min-height: 2em; }
    </style>
  </body>
</html>
""",

Por razões de compatibilidade e acessibilidade, sugiro que você forneça aos seus destinatários versões HTML e texto simples do seu email sempre que possível. Dessa forma, você garante que os destinatários que usam clientes que não renderizam conteúdo HTML ou que preferem emails em texto simples possam ler sua mensagem.

Para fornecer a versão em texto simples do email junto com o HTML, basta adicionar o parâmetro text:

text="Parabéns por enviar email de teste com Mailtrap!",

Enviar emails para múltiplos destinatários

Para enviar email para múltiplos destinatários, você pode usar os seguintes parâmetros:

to=[mt.Address(email="seu@email.com", name="Seu nome")],
cc=[mt.Address(email="cc@email.com", name="Cópia para")],
bcc=[mt.Address(email="bcc@email.com", name="Destinatário Oculto")],

Explicação dos parâmetros:

  • To – Usado para os principais destinatários do email que você está endereçando diretamente na sua mensagem.
  • CC (Carbon Copy) – Usado para listar destinatários que receberão uma cópia do email e cujos endereços serão visíveis para todos os destinatários da mensagem.
  • BCC (Blind Carbon Copy) – Usado para listar destinatários que também receberão uma cópia do email e cujos endereços não serão visíveis para os outros destinatários.

Enviar emails com anexos

Para enviar email com anexos, usaremos o parâmetro attachments dentro do objeto mt.Mail, assim:

attachments=[
    mt.Attachment(
        content=base64.b64encode(welcome_image),
        filename="welcome.png",
        disposition=mt.Disposition.INLINE,
        mimetype="image/png",
        content_id="welcome.png",
    )
],

Explicação do código:

  • content – O conteúdo codificado em base64 do arquivo que você está anexando. Também usaremos isso para incorporar imagens mais tarde.
  • filename – O nome do arquivo como ele aparecerá no email.
  • disposition – Se definido como mt.Disposition.INLINE, indica que o anexo não será apenas baixado, mas também exibido no corpo do email.
  • mimetype – O tipo MIME do anexo, que ajuda os clientes a entenderem como lidar com o arquivo. Alguns dos tipos MIME comuns para imagens são image.jpeg ou image.png.
  • content_id – Um identificador único para o anexo, usado para referenciá-lo no corpo HTML do email.

Enviar emails com uma imagem incorporada

Enviar emails com imagens incorporadas é semelhante a adicionar anexos porque usaremos o mesmo parâmetro attachments:

attachments=[
    mt.Attachment(
        content=base64.b64encode(welcome_image),
        filename="welcome.png",
        disposition=mt.Disposition.INLINE,
        mimetype="image/png",
        content_id="welcome.png",
    )
],

Mas, teremos que referenciar a imagem incorporada no corpo HTML do email com uma tag <img>, onde o atributo src é definido como cid:welcome.png, que informa ao cliente de email para exibir a imagem incorporada.

Aqui está a linha de código que você pode usar:

<img alt="Inspect with Tabs" src="cid:welcome.png" style="width: 100%;">

Envio de emails em massa

Para envio de emails em massa no Flask, usaremos novamente o Bulk Stream do Mailtrap, que você pode encontrar em Sending DomainsSMTP/API Settings.

Certifique-se de selecionar API e usar o exemplo de código Python localizado em credenciais de API. Colado na sua configuração do Flask, deve ficar algo assim:

import requests

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

payload = "{\"from\":{\"email\":\"mailtrap@mailtrapdemo.com\",\"name\":\"Teste Mailtrap\"},\"to\":[{\"email\":\"demo@mailtrap.io\"}],\"subject\":\"Você é incrível!\",\"text\":\"Parabéns por enviar email de teste com Mailtrap!\",\"category\":\"Teste de Integração\"}"
headers = {
# 
"Authorization": "Bearer ba12312312312312312312312312312c",
  "Content-Type": "application/json"
}


try:
    response = requests.request("POST", url, headers=headers, data=payload)
except requests.exceptions.HTTPError as errh:
    print(f”Erro HTTP: {errh})

print(response.text)

Além disso, você pode definir o payload como um dicionário Python e deixar a biblioteca requests convertê-lo para JSON, e adicionar um tratamento básico de erros, assim:

import requests

url = "https://bulk.api.mailtrap.io/api/send"
payload = {
    "from": {"email": "mailtrap@mailtrapdemo.com", "name": "Teste Mailtrap"},
    "to": [{"email": "demo@mailtrap.io"}],
    "subject": "Você é incrível!",
    "text": "Parabéns por enviar email de teste com Mailtrap!",
    "category": "Teste de Integração"
}
headers = {
    "Authorization": "Bearer seu_token_real_aqui",  # Substitua pelo seu token real do Mailtrap
    "Content-Type": "application/json"
}

response = requests.post(url, headers=headers, json=payload)

if response.status_code == 200:
    print("Email enviado com sucesso!")
else:
    print(f"Falha ao enviar email. Código de status: {response.status_code}, Resposta: {response.text}")

Envio assíncrono de emails

Semelhante ao envio assíncrono de emails via SMTP, usaremos novamente o Celery para fazê-lo através de uma API.

Basta modificar a função send_async_email para fazer uma solicitação HTTP ao endpoint da API em vez de usar o Flask-Mail. Aqui está um exemplo:

from flask import Flask
import requests
from celery import Celery

app = Flask(__name__)
# Configure seu aplicativo Flask aqui, incluindo MAIL_DEFAULT_SENDER e MAIL_API_KEY

celery = Celery(app.name, broker='sua_url_broker')
celery.conf.update(app.config)

@celery.task
def send_async_email(email_data):
    with app.app_context():
        url = "https://bulk.api.mailtrap.io/api/send"
        payload = {
            "from": {"email": app.config['MAIL_DEFAULT_SENDER'], "name": "Nome do Seu App"},
            "to": [{"email": email_data['to']}],
            "subject": email_data['subject'],
            "text": email_data['body'],
            "category": "Sua Categoria"
        }
        headers = {
            "Authorization": f"Bearer {app.config['MAIL_API_KEY']}",
            "Content-Type": "application/json"
        }
        response = requests.post(url, headers=headers, json=payload)
        
        if response.status_code != 200:
            # Registrar erro ou tratá-lo em conformidade
            print(f"Falha ao enviar email: {response.text}")

# Lembre-se de atualizar seu comando do trabalhador Celery de acordo com a estrutura do seu projeto

No entanto, independentemente de você estar enviando emails via SMTP ou API, você precisa executar um trabalhador Celery para processar as tarefas na fila com o seguinte comando:

celery -A main.celery worker --loglevel=INFO

Importante:

  • Substitua current_app.config['MAIL_DEFAULT_SENDER'] e current_app.config['MAIL_API_KEY'] pelo seu email remetente e chave de API reais.
  • Substitua main pelo nome do seu arquivo Python e celery pelo nome da sua variável Celery.

Testar e enviar emails em ambiente de produção

Antes de implantar qualquer funcionalidade de email, testar se seus emails estão realmente sendo enviados sem spammar os usuários é praticamente uma necessidade.

Para fazer isso, você pode bloquear o envio no Flask com duas configurações simples:

  • Defina MAIL_SUPPRESS_SEND da configuração anterior como False.
  • Adicione uma configuração TESTING ao arquivo de configuração e defina como True.

Então, você pode usar o método record_messages para ver o que está sendo enviado do seu aplicativo Flask (certifique-se de ter o pacote blinker instalado). Você verá a lista de instâncias Message em outbox.

with mail.record_messages() as outbox:

    mail.send_message(subject='testando',
                      body='teste',
                      recipients=emails)

    assert len(outbox) == 1
    assert outbox[0].subject == "testando"

No entanto, se você deseja ver os emails que seu aplicativo envia, precisará de uma solução diferente.

Eu pessoalmente recomendo o Mailtrap Email Testing, uma parte da Plataforma de Email Delivery Mailtrap, que oferece um ambiente seguro onde você pode visualizar e testar seus emails antes de enviá-los.

Com o Mailtrap Email Testing, você pode visualizar como seus emails HTML parecem antes de enviá-los para seus destinatários, vê-los em HTML de origem, texto, bruto e mais.

Você também pode usar o recurso HTML Check para analisar o HTML/CSS dos seus emails e identificar facilmente quaisquer linhas de código com falhas. Desta forma, você pode corrigir possíveis erros no código e garantir que seus emails cheguem às caixas de entrada dos destinatários de forma impecável.

Além disso, com o recurso Spam Analysis, você pode verificar sua pontuação de spam, que, se você mantiver abaixo de 5, resolverá efetivamente um número significativo de potenciais problemas de entregabilidade de email quando seu aplicativo for para produção.

Além desses e outros recursos avançados, o Mailtrap Email Testing é super fácil de configurar. Confira!

SMTP

Para começar a testar seus emails, tudo o que você precisa fazer é:

  • Faça login na sua conta Mailtrap.
  • Navegue até Email Testing → Inboxes → SMTP Settings
  • Selecione Flask-Mail na lista de integrações.
  • Cole as configurações fornecidas pelo Mailtrap na sua configuração do Flask, que deve ficar assim:
from flask import Flask
from flask_mail import Mail, Message

app = Flask(__name__)

# Configuração do Mailtrap
app.config['MAIL_SERVER'] = 'sandbox.smtp.mailtrap.io'
app.config['MAIL_PORT'] = 2525
app.config['MAIL_USERNAME'] = 'seu_usuario_mailtrap'
app.config['MAIL_PASSWORD'] = 'sua_senha_mailtrap'
app.config['MAIL_USE_TLS'] = True
app.config['MAIL_USE_SSL'] = False 

# Inicializar Flask-Mail
mail = Mail(app)

@app.route("/send_email")
def send_email():
    msg = Message('Olá', sender='voce@exemplo.com', recipients=['teste@exemplo.com'])
    msg.body = "Este é um email de teste do Flask usando Mailtrap."
    mail.send(msg)
    return "Email enviado!"

if __name__ == "__main__":
    app.run(debug=True)

API

Se você preferir integrar a API do Mailtrap para teste, automação e teste de sequências automatizadas, basta executar o seguinte comando:

pip install mailtrap

E então use o seguinte trecho de código:

import mailtrap as mt

# criar objeto de email
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 Mailtrap!",
)

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

Claro, você deve modificar as variáveis como sender, subject, text e, mais importante, sua-chave-api.

Para mais informações, confira a documentação oficial da API do Mailtrap aqui ou o repositório dedicado no GitHub para Python.

Concluindo

E com isso, chegamos ao final do nosso tutorial sobre Flask!

Mostrei como aproveitar a extensão Flask-Mail e o Mailtrap para que você possa adicionar a funcionalidade de envio de email ao seu aplicativo web de forma tranquila, e não se esqueça de testar suas mensagens!

No entanto, se você deseja explorar outros métodos para enviar emails no Flask, como o smtplib do Python, confira nosso tutorial dedicado aqui. Ou, veja nossos outros artigos relacionados ao Python, como:

Article by Piotr Malek Technical Content Writer @ Mailtrap
Ivan Djuric, an author at Mailtrap
Article by Ivan Djuric Technical Content Writer @Mailtrap

I’m a Technical Content Writer with 5 years of background covering email-related topics in tight collaboration with software engineers and email marketers. I just love to research and share actionable insights with you about email sending, testing, deliverability improvements, and more. Happy to be your guide in the world of emails!