Dev Life
Criando fluxos de trabalho de e-mail transacional para notificações de carrinho abandonado com a API do Mailgun
Em aplicativos modernos de comércio eletrônico, os e-mails transacionais vão além de confirmações de pedidos e atualizações de envio. Eles também respondem ao comportamento do usuário; por exemplo, se um usuário adiciona itens ao seu carrinho, mas não conclui a compra, você pode enviar um lembrete, comumente conhecido como uma notificação de “carrinho abandonado”. Isso não apenas incentiva a conclusão, mas também fornece um ponto de contato útil caso o usuário encontre algum problema durante o checkout.
Neste tutorial, você aprenderá como enviar um e-mail de carrinho abandonado aos usuários usando as APIs do Mailgun.
Implementando fluxos de trabalho de e-mail transacional para notificações de carrinho abandonado
Para implementar fluxos de trabalho de e-mail transacional para notificações de carrinho abandonado, você criará uma interface de usuário simples para simular um carrinho de compras e um Flask backend para rastrear carrinhos abandonados e acionar e-mails transacionais.
Antes de começar, certifique-se de ter o seguinte:
- Uma conta do Mailgun para enviar e-mails por meio da API do Mailgun; se você não tiver uma conta, siga o guia de início rápido para configurar uma gratuitamente
- Python 3.8 ou superior instalado em sua máquina
- Alguma familiaridade com HTML e JavaScript para entender o código da interface de usuário
Configurando uma conta do Mailgun
Primeiro, faça login em sua conta do Mailgun e anote seu domínio de envio no painel do Mailgun. Se você estiver em um plano gratuito, verá um domínio sandbox, que será usado tanto no endpoint da API quanto no endereço de e-mail "from" ao enviar e-mails. O domínio sandbox segue este formato: sandbox.mailgun.org:
Nota: Se você quiser enviar e-mails de seu próprio domínio personalizado, precisará de um plano pago do Mailgun. O plano gratuito oferece suporte apenas ao domínio sandbox e limita o envio a cinco destinatários autorizados.
Se você quiser enviar e-mails de seu próprio domínio personalizado, precisará de um plano pago do Mailgun. O plano gratuito oferece suporte apenas ao domínio sandbox e limita o envio a cinco destinatários autorizados.
Em seguida, você precisa gerar uma chave de API na página de Segurança da API. Você pode encontrar essa opção no menu suspenso sob o seu nome no canto superior direito do painel do Mailgun:
Você usará essa chave de API em seu aplicativo Flask para enviar notificações de carrinho abandonado por meio da API do Mailgun.
Configurando um novo projeto Python
Para configurar um novo projeto, abra um terminal no diretório do projeto de sua preferência e execute os seguintes comandos para buscar o código necessário – tanto a interface de usuário quanto o backend – em sua máquina:
git clone https://github.com/manishh/gifts-giveaways.git cd gifts-giveaways/python/mailgun-abandoned-cart-notifications
Em seguida, dentro do diretório mailgun-abandoned-cart-notifications, renomeie .env.example para .env e atualize-o com suas credenciais da API do Mailgun:# Substitua por seu domínio e chave de API do Mailgun reais MAILGUN_API_KEY="SUA-CHAVE-DE-API" MAILGUN_DOMAIN="SEU-DOMINIO-MAILGUN"
Antes de prosseguir, é recomendável que você crie e ative um novo ambiente virtual para isolar seu projeto e evitar conflitos de dependência.
Uma vez que seu ambiente virtual esteja ativo, instale as dependências necessárias:pip install -r requirements.txt
Isso instala todos os pacotes necessários, incluindo o Flask, a estrutura web leve que executa o backend.
Após a conclusão da instalação, inicie o aplicativo Flask com este comando:python app.py
A interface de usuário do aplicativo estará disponível em http://localhost:5000/.
Criando a interface de carrinho abandonado
A captura de tela abaixo mostra uma interface de usuário simples de comércio eletrônico para simular cenários de carrinho abandonado. Na parte superior, o cabeçalho exibe o título, junto com um perfil de usuário (mostrando o nome e e-mail) e um ícone de carrinho de compras indicando o número de itens no carrinho. Há quatro cartões de produtos exibindo imagens, nomes, preços e descrições, e os usuários podem selecionar quantidades antes de adicionar itens com o botão Add to Cart (Adicionar ao carrinho). No canto inferior esquerdo, um painel de configurações permite configurar o tempo limite de carrinho abandonado (em segundos) e redefinir o carrinho, se necessário. Na vida real, o tempo limite seria em horas e deveria ser rastreado pelo backend.
Você pode usar essa interface para acionar um evento quando um usuário deixa itens em seu carrinho sem concluir a compra:
Você pode encontrar o código para essa interface de carrinho de compras em templates/shopping_cart.html. Este arquivo tem duas seções importantes: a configuração da interface de usuário e uma função para enviar os dados de carrinho abandonado para o backend.
Para a configuração da interface de usuário, localize e edite USER_NAME e USER_EMAIL dentro da tag para enviar os dados corretos para seu backend. Estes dois parâmetros representam o usuário conectado no seu aplicativo de comércio eletrônico:
// Configuração: Substitua estes valores pelos seus próprios const USER_NAME = "John Smith"; const USER_EMAIL = "john.smith@example.com"; // E-mail verificado para a conta sandbox do Mailgun const BACKEND_URL = 'http://localhost:5000/abandoned-cart'; // Atualize para o seu endpoint da API do Flask, se necessário let ABANDONED_CART_TIMEOUT = 60; // Tempo limite padrão em segundos
Nota: Se você estiver usando o plano gratuito do Mailgun, certifique-se de que USER_EMAIL seja um dos endereços verificados em sua conta do Mailgun. Você pode deixar os dois parâmetros restantes inalterados.
A seguinte função em JavaScript, sendToBackend(data), lida com o processo de enviar detalhes do carrinho abandonado – como informações do usuário, itens no carrinho e o valor total – para o backend com o objetivo de acionar uma notificação:
// Enviar dados para o backend function sendToBackend(data) { console.log('Enviando dados do carrinho abandonado para o backend...'); fetch(BACKEND_URL, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(data) }) .then(response => { // Verificar se o status da resposta é 200 (OK) if (response.status === 200) { return response.json(); } else { // Lançar um erro se o status não for 200 throw new Error(`Erro HTTP! Status: ${response.status}`); } }) .then(result => { console.log('Resposta do backend:', result); alert('Notificação de carrinho abandonado enviada com sucesso!'); resetCart(); }) .catch(error => { console.error('Erro ao enviar notificação de carrinho abandonado:', error); alert('Erro ao enviar notificação de carrinho abandonado. Verifique o console para obter detalhes.'); }); }
Essa função primeiro faz uma solicitação HTTP POST para BACKEND_URL usando a chamada fetch, convertendo os dados do carrinho em um payload JSON.
Se o servidor responder com sucesso (HTTP 200), a resposta será processada e registrada no console, e um alerta confirmará que a notificação de carrinho abandonado foi enviada. O carrinho é então redefinido.
Se a solicitação falhar – devido a problemas de rede ou a um problema no lado do servidor (como erros HTTP 5XX) – a função capturará o erro, fará o registro no console e alertará o usuário de que algo deu errado. Dessa forma, a função garante que as tentativas bem-sucedidas e com falha de notificar o backend sejam tratadas de forma elegante, mantendo o usuário informado durante todo o processo.
O restante do código em shopping_cart.html lida com a estilização CSS para um layout limpo e visualmente atraente, lógica JavaScript para calcular o valor total do carrinho e gerenciamento de temporizador para simular o abandono do carrinho.
Processando notificações de carrinho abandonado no backend
Quando a interface de usuário posta dados de carrinho abandonado para BACKEND_URL, o aplicativo Flask (app.py) os processa usando a seguinte função:@app.route('/abandoned-cart', methods=['POST']) def abandoned_cart(): """ Endpoint para receber os dados do carrinho abandonado incluindo as informações do usuário. Envia uma notificação por e-mail para o usuário em questão. """ try: # Obter dados do carrinho da solicitação cart_data = request.json # Extrair informações do usuário user_info = cart_data.get('user', {}) user_email = user_info.get('email', 'unknown') # Registrar os dados recebidos logger.info(f"Carrinho abandonado recebido de {user_email} em {datetime.datetime.now()}, Total de itens: {len(cart_data.get('items', []))}") # Enviar e-mail sobre o carrinho abandonado html_message = _generate_abandoned_cart_email(cart_data) _send_email(f"{user_info.get('name', user_email)} ", "Seu carrinho está aguardando...", html_message) # Retornar resposta de sucesso return jsonify({ "status": "success", "message": f"Notificação de carrinho abandonado enviada para: {user_info.get('email')}", "timestamp": datetime.datetime.now().isoformat(), }), 200 except Exception as e: logger.error(f"Erro ao processar carrinho abandonado: {str(e)}") return jsonify({"status": "error", "message": str(e)}), 500
Este endpoint da API (/abandoned-cart) escuta solicitações POST quando um usuário abandona o carrinho. Ele extrai os detalhes do carrinho a partir do payload JSON da solicitação, recupera o nome e o e-mail do usuário, e registra o evento junto com o carimbo de data/hora e o número de itens.
Em seguida, ele gera um e-mail usando _generate_abandoned_cart_email(cart_data), que converte os detalhes do carrinho em um modelo de e-mail em HTML organizado. O e-mail é então enviado para o user_email por meio de _send_email(), usando o assunto “Seu carrinho está aguardando…” para lembrar o usuário de sua compra pendente.
Se for bem-sucedida, a função retorna uma resposta JSON confirmando que o e-mail foi enviado. Se ocorrer um erro, como um problema com a solicitação ou serviço de e-mail, ele registrará o erro e retornará uma resposta HTTP 500 Internal Server Error, que a interface de usuário poderá usar para informar o usuário sobre o status da notificação.
Projetando o modelo de e-mail
Os e-mails de lembrete de carrinho abandonado não devem ser apenas informativos, mas também visualmente atraentes. Um e-mail em HTML bem projetado com imagens apresenta os detalhes do carrinho claramente e aumenta as chances de o usuário retornar para concluir a compra. A função _generate_abandoned_cart_email(...) cuida disso:
Olá {first_name}, Notamos que você deixou alguns itens em seu carrinho {abandonment_time}. Não se preocupe, nós os salvamos para você! {item_description} Quantidade: {item_quantity} ${item_price:.2f} Se você tiver alguma dúvida sobre o seu pedido, não hesite em entrar em contato com a nossa equipe de atendimento ao cliente. Obrigado por comprar conosco! Olá, Você tem itens aguardando no seu carrinho. Clique abaixo para concluir a sua compra!def _generate_abandoned_cart_email(cart_data: Dict[str, Any]) -> str: """ Gera um e-mail em HTML para um carrinho abandonado usando os dados do carrinho fornecidos. Args: cart_data: Dicionário contendo as informações do carrinho, incluindo detalhes e itens do usuário Returns: String HTML para o e-mail """ try: # Extrair os dados com tratamento de erros user_name = cart_data.get('user', {}).get('name', 'Cliente Valioso') first_name = user_name.split()[0] if ' ' in user_name else user_name items = cart_data.get('items', []) total_value = cart_data.get('totalValue', 0) # Formatar carimbo de data/hora, se disponível timestamp_str = cart_data.get('timestamp', '') timezone_offset = cart_data.get('timezoneOffset', 0) # Representar o fuso horário do usuário if timestamp_str: try: timestamp = datetime.datetime.fromisoformat(timestamp_str.replace('Z', '+00:00')) - datetime.timedelta(minutes=timezone_offset) abandonment_time = f"em {timestamp.strftime('%d de %B às %I:%M %p')}" except (ValueError, TypeError): abandonment_time = 'recentemente' else: abandonment_time = 'recentemente' # Gerar o conteúdo HTML com CSS mínimo combinado html = f""" /* Estilização CSS aqui */ Seu carrinho está aguardando!
Itens do seu carrinho:
""" # Adicionar cada item ao e-mail for item in items: item_name = item.get('name', 'Produto') item_price = item.get('price', 0) item_quantity = item.get('quantity', 1) item_image = item.get('image', '') item_description = item.get('description', '') # Formatar tag de imagem com fallback image_tag = f'' if item_image else item_name[0].upper() html += f"""
{item_name}
Seu Carrinho Está Aguardando!
Essa função constrói um e-mail em HTML lembrando um usuário sobre o seu carrinho abandonado. Ela primeiro extrai os detalhes principais a partir dos dados fornecidos, incluindo o nome do usuário, os itens do carrinho e o preço total. Se um carimbo de data/hora estiver disponível, ele o converterá para o fuso horário do usuário (uma vez que os fusos horários do servidor e do cliente seriam diferentes) e o formatará em uma string de data e hora amigável (como “em 25 de março às 15h49”). Caso contrário, o padrão será “recentemente.”
O e-mail informa ao usuário que o carrinho foi salvo e lista os itens deixados para trás, incluindo o nome do produto, a quantidade, o preço, a descrição e uma imagem. O valor total do carrinho é exibido em destaque, seguido por um botão Conclua Sua Compra para incentivar o usuário a retornar e finalizar a compra.
Se ocorrer um erro, como dados ausentes ou problemas de formatação, a função voltará a usar um e-mail simples com uma mensagem básica e o link de compra. Isso garante que, mesmo que a versão detalhada falhe, os usuários ainda recebam um lembrete para concluir a sua transação.
Navegue até Send > Sending > Templates (Enviar > Enviando > Modelos) na sua conta do Mailgun para criar os seus próprios modelos de e-mail:
Implementando a funcionalidade de envio de e-mail com a API do Mailgun
Uma vez que o conteúdo do e-mail é gerado, ele precisa ser entregue de forma confiável. A função _send_email(...) lida com o envio de notificações de carrinho abandonado usando a API do Mailgun:
def _send_email(to_address: str, subject: str, html_message: str): """ Envia um único e-mail para o endereço de e-mail fornecido usando a API do Mailgun. :param to_address: :param subject: :param message: """ api_key = os.getenv("MAILGUN_API_KEY") # Obter a chave de API do arquivo `.env` resp = requests.post(MAILGUN_API_URL, auth=("api", api_key), data={"from": FROM_EMAIL_ADDRESS, "to": to_address, "subject": subject, "html": html_message}) if resp.status_code == 200: # Sucesso logging.info(f"E-mail enviado com sucesso para '{to_address}' via API do Mailgun.") else: # Erro raise RuntimeError(f"Não foi possível enviar o e-mail, motivo: {resp.text}")
Essa função lê MAILGUN_API_KEY e, em seguida, envia um e-mail via API do Mailgun usando uma solicitação HTTP POST. A solicitação inclui detalhes essenciais do e-mail, incluindo endereço do remetente, endereço do destinatário, assunto e conteúdo em HTML gerado pela função _generate_abandoned_cart_email(...).
Se a solicitação for bem-sucedida (resp.status_code == 200), ela registrará uma mensagem de sucesso. Caso contrário, ela gerará uma exceção com os detalhes da resposta.
É importante entender que _send_email(...) deliberadamente não lida com erros, deixando isso para a função de chamada (abandoned_cart(), que atende ao endpoint /abandoned-cart), para que ela possa capturar as exceções e retornar uma resposta HTTP apropriada. Se o e-mail for enviado com sucesso, abandoned_cart() retornará uma resposta HTTP 200 confirmando que a notificação foi enviada. Se ocorrer um erro, como uma chave de API inválida ou falha de rede, ela retornará uma resposta HTTP 500, garantindo que a interface de usuário seja informada sobre o problema.
Testando o fluxo de trabalho
Agora que você explorou todos os componentes principais, é hora de testar o fluxo de trabalho de e-mail de carrinho abandonado de ponta a ponta.
Primeiro, certifique-se de que o seu servidor Flask esteja em execução e que a interface de usuário esteja acessível no seu navegador em http://localhost:5000/. Você pode ajustar o tempo limite do carrinho abandonado no painel de configurações no canto inferior esquerdo da página, conforme necessário.
Em seguida, adicione alguns itens ao seu carrinho. Toda vez que você adiciona um item, o temporizador de contagem regressiva do carrinho é redefinido e recomeça. Quando terminar, clique no ícone do carrinho para visualizar o painel deslizante, que exibe os produtos selecionados, os seus preços e o botão Proceed to Checkout (Avançar para o Checkout):
Em vez de prosseguir com o checkout, permita que o temporizador termine a sua contagem regressiva. Assim que a contagem regressiva chegar a zero, um alerta deverá aparecer na interface de usuário confirmando que a notificação de carrinho abandonado foi enviada. A mensagem de alerta deverá dizer:Notificação de carrinho abandonado enviada com sucesso!
Ao mesmo tempo, o terminal do seu aplicativo Flask deverá registrar mensagens como esta:INFO:__main__:Carrinho abandonado recebido de em 2025-03-24 14:02:00.077949, Total de itens: 3 INFO:root:E-mail enviado com sucesso para 'Name ' via API do Mailgun.
Por fim, verifique a sua caixa de entrada em busca do e-mail de carrinho abandonado. Se tudo funcionou corretamente, você deverá receber esta mensagem:
Nota: Se você estiver usando o plano gratuito do Mailgun, o e-mail poderá parar na pasta de spam.
Parabéns! Você implementou e testou com sucesso o fluxo de trabalho de notificação por e-mail de carrinho abandonado usando a API do Mailgun.
Monitorando e gerenciando e-mails
Uma vez que os seus e-mails de carrinho abandonado estejam sendo enviados, é importante monitorar a entrega deles, rastrear o engajamento e lidar com quaisquer falhas de forma eficaz. O Mailgun fornece ferramentas de relatórios integradas para monitorar e-mails enviados, taxas de abertura e falhas.
Para acessar esses insights, navegue até Enviar > Relatórios > Métricas em seu painel do Mailgun:
Aqui, você encontrará um detalhamento gráfico das principais estatísticas de e-mail, como:
Contagem de envios: Número total de tentativas de envio de e-mails
Contagem de entregues: E-mails recebidos com sucesso pelos destinatários
Contagem de abertos: Número de e-mails abertos pelos destinatários (se o rastreamento de aberturas estiver ativado)
Contagem de falhas: E-mails que falharam devido a problemas como endereços inválidos ou filtro de spam
Para uma análise mais profunda, a guia Logs fornece registros detalhados do status de cada e-mail, enquanto a guia Classificação de devolução ajuda a diagnosticar falhas.
Altas taxas de devolução podem impactar negativamente a sua entregabilidade de e-mail. Para reduzir as devoluções, analise regularmente a guia Classificação de devolução no Mailgun, remova e-mails inválidos e use listas de supressão para evitar reenvios a endereços devolvidos.
Conclusão
Neste tutorial, você aprendeu como implementar um fluxo de trabalho de e-mail de carrinho abandonado usando o Mailgun. O processo abrangeu a criação de uma interface de usuário simples para simular um site de comércio eletrônico, o envio de dados do carrinho para o backend, o processamento deles com o Flask, a geração de modelos de e-mail, o envio de notificações por meio da API do Mailgun e o rastreamento das métricas de entrega. E-mails transacionais como esses ajudam a recuperar vendas perdidas e a melhorar o engajamento do cliente.
Você pode encontrar todo o código deste tutorial em este repositório do GitHub.
Agora, você pode colocar esse conhecimento em ação – integre o Mailgun em seus projetos e comece a usar e-mails transacionais para aprimorar a experiência do usuário. Explore modelos de e-mail transacional e experimente a API do Mailgun gratuitamente hoje mesmo!






