Skip to content

030. Infraestrutura de emails

Filipe Deschamps edited this page Jan 25, 2022 · 3 revisions

25/01/22

Isso era algo que pessoalmente eu estava louco para fazer, que é uma infraestrutura local e simples para envio de email e que pode ser usada em testes automatizados. No passado já trabalhei em code bases que simulavam o envio de um email para verificar se, por exemplo, uma informação como um token de confirmação de email estava sendo de fato enviada... mas o que não estava sendo enviado era um email de verdade.

E minha vontade era se conectar de verdade em algo como um servidor SMTP, fazer o sistema enviar o email de verdade (sem saber que está enviando para um servidor controlado por nós), e de alguma forma capturar esse email e verificar essas informações e o PR #159 e PR #160 são os primeiros passos nessa direção.

Servidor SMTP

Primeiro passo foi então procurar um servidor SMTP que pudesse ser levantado localmente e encontrei esses dois:

MailCatcher

O MailCatcher parece ser uma solução mais antiga, mas muito mais popular do que o MailSlurper. E como é para ser uma solução simples e transparente, trocar isso mais para frente não deveria ser um problema, pois basta ter suporte a SMTP para envio dos emails, e uma forma de buscar esses emails do servidor, seja se conectando no banco dele ou de preferência uma API REST (e que ambos citados ali em cima fornecem).

Docker

Outra coisa boa é que existe uma imagem oficial para Docker do MailCatcher: https://hub.docker.com/r/sj26/mailcatcher então foi questão de adicionar ele no nosso docker-compose dos serviços e que ficaria disponível para uso.

  mailcatcher:
    container_name: mailcatcher
    image: sj26/mailcatcher
    expose:
      - 1025
      - 1080
    ports:
      - 1025:1025
      - 1080:1080

Envio dos emails

Em seguida, criei um componente email que utiliza variáveis de ambiente pra saber qual host e porta se conectar e começar a enviar emails usando o nodemailer. Por conta dessas variávies de ambiente, agora é só questão de lá na Vercel configurar as credenciais de produção do serviço de disparo de email final que utilizarmos (ou se esse serviço só suporta REST, fazer uma condicional bem simples para o transporter.

Recuperação dos emails enviados

Essa parte é importante para os testes automatizados, dado que o componente de email não sabe o que está acontecendo ao enviar os emails, ele só envia como um email de verdade. Então usando o endpoint do MailCatcher, eu consigo recuperar os emails enviados e também limpar a base dos emails a cada novo início de teste.

Mas um problema é que a lógica de deleteAllEmails() para limpar a base, e getLastEmail() para capturar o último email enviado e fazer os assertions, eu coloquei tudo dentro do orchestrator dos testes. Ele já está ficando meio monstrinho, quartinho da bagunça sabe, e só tende a piorar... mas ainda não coloquei energia para visualizar como organizar melhor.

Alguns próximos passos possíveis:

  • Criar uma abstração que use o componente de email, mas entregue para ele o template do email (body em html, por exemplo), tenha pré-definido o from, subject e coisas assim.
  • Usar essa abtração acima para fazer confirmação de email e habilitação da conta.
  • Voltar a trabalhar na ecriptação da senha.
  • Trabalhar nas sessions.