E-mails Transacionais

Publicado em

08/03/2025

Enviando E-mails Transacionais no SaaS Boilerplate

O SaaS Boilerplate inclui um sistema de e-mails transacionais completo e flexível, projetado para ser facilmente personalizável e independente de provedores específicos.

Visão Geral

O sistema de e-mails transacionais do SaaS Boilerplate foi desenvolvido com os seguintes princípios:

  1. Arquitetura de adaptadores: Troque facilmente entre diferentes provedores de e-mail
  2. Templates React: Crie e-mails bonitos e responsivos usando componentes React
  3. Tipagem forte: Evite erros em tempo de execução com validação de dados via Zod
  4. Facilidade de teste: Teste seus e-mails localmente sem enviar mensagens reais

Configuração Inicial

1. Configuração do Provedor

O sistema usa uma arquitetura de adaptadores que permite trocar facilmente entre diferentes provedores de e-mail:

// Em src/core/providers/mail.ts
import { MailProvider } from "@/saas-boilerplate/providers/mail/mail.provider";
import { AppConfig } from "@/configs/app.config";
import { getAdapter } from "@/saas-boilerplate/providers/mail";
import { welcomeEmailTemplate } from "@/content/mails/welcome.email";
import { organizationInviteTemplate } from "@/content/mails/organization-invite";
import { planUpgradeEmailTemplate } from "@/content/mails/billing-plan-upgrade";
import { quotaExceededEmailTemplate } from "@/content/mails/billing-plan-quota-exceed";
import { downgradeEmailTemplate } from "@/content/mails/billing-plan-downgrade";
import { otpCodeEmailTemplate } from "@/content/mails/otp-code";

export const mail = MailProvider.initialize({
  secret: AppConfig.providers.mail.secret,
  from: AppConfig.providers.mail.from,
  adapter: getAdapter(AppConfig.providers.mail.provider),
  templates: {
    welcome: welcomeEmailTemplate,
    'organization-invite': organizationInviteTemplate,
    'billing-plan-upgrade': planUpgradeEmailTemplate,
    'billing-plan-quota-exceed': quotaExceededEmailTemplate,
    'billing-plan-downgrade': downgradeEmailTemplate,
    'otp-code': otpCodeEmailTemplate,
  }
})

2. Configuração de Variáveis de Ambiente

Configure as variáveis de ambiente para o provedor de e-mail que você deseja usar:

# .env
# Para SMTP
MAIL_PROVIDER=smtp
MAIL_SECRET=smtp://username:password@smtp.example.com:587

# OU para Resend
MAIL_PROVIDER=resend
MAIL_SECRET=re_123456789

Templates de E-mail

Criando um Template

Os templates de e-mail são criados usando React Email, permitindo que você use componentes React para criar e-mails bonitos e responsivos:

// Em src/content/mails/welcome.email.tsx
import * as ReactEmail from '@react-email/components'
import { z } from 'zod'

import { Footer } from './components/footer'
import { Url } from '@/saas-boilerplate/utils'
import { AppConfig } from '@/configs/app.config'
import { MailProvider } from '@/saas-boilerplate/providers/mail'

/**
 * Schema definition for the welcome email template
 */
const schema = z.object({
  name: z.string().nullable().optional(),
  email: z.string().email()
})

/**
 * Email template for welcoming new users to the platform
 */
export const welcomeEmailTemplate = MailProvider.template({
  subject: `Bem-vindo ao ${AppConfig.name}!`,
  schema: schema,
  render: ({ name, email }) => {
    return (
      <ReactEmail.Html>
        <ReactEmail.Head />
        <ReactEmail.Preview>Bem-vindo ao {AppConfig.name}</ReactEmail.Preview>
        <ReactEmail.Tailwind>
          <ReactEmail.Body className="mx-auto my-auto bg-white font-sans">
            <ReactEmail.Container className="mx-auto my-10 max-w-[500px] rounded-md border border-solid border-gray-200 px-10 py-5">
              <ReactEmail.Section className="mt-8">
                <ReactEmail.Img
                  src={AppConfig.brand.logos.icon.light}
                  width="40"
                  height="40"
                  alt={AppConfig.name}
                  className="my-0"
                />
              </ReactEmail.Section>
              <ReactEmail.Heading className="mx-0 my-7 p-0 text-left text-xl font-semibold text-black">
                Bem-vindo ao {AppConfig.name}
              </ReactEmail.Heading>
              <ReactEmail.Text className="text-sm leading-6 text-black">
                Obrigado por se cadastrar{name && `, ${name}`}!
              </ReactEmail.Text>
              {/* Mais conteúdo do e-mail... */}
              
              <Footer email={email} marketing />
            </ReactEmail.Container>
          </ReactEmail.Body>
        </ReactEmail.Tailwind>
      </ReactEmail.Html>
    )
  }
})

Cada template inclui:

  1. Schema de validação: Define os dados necessários para renderizar o template
  2. Assunto do e-mail: Pode incluir variáveis dinâmicas
  3. Função de renderização: Retorna o JSX que será convertido em HTML

Templates Incluídos

O SaaS Boilerplate inclui templates prontos para uso em todos os momentos críticos da jornada do usuário:

  • Boas-vindas: Enviado quando um usuário se cadastra
  • Convite para Organização: Para convidar novos membros para uma equipe
  • Código OTP: Para autenticação de dois fatores
  • Upgrade de Plano: Notifica sobre mudanças de plano
  • Limite Excedido: Avisa quando um limite de uso foi atingido
  • Downgrade de Plano: Informa sobre rebaixamento de plano

Enviando E-mails

Envio Básico

Para enviar um e-mail usando um template:

import { mail } from "@/core/providers/mail";

// Enviar um e-mail de boas-vindas
await mail.send({
  template: 'welcome',
  to: 'usuario@exemplo.com.br',
  data: {
    name: 'João Silva',
    email: 'usuario@exemplo.com.br'
  }
});

Agendamento de E-mails

Você também pode agendar e-mails para serem enviados no futuro:

import { mail } from "@/core/providers/mail";

// Data para 3 dias no futuro
const dataFutura = new Date();
dataFutura.setDate(dataFutura.getDate() + 3);

// Agendar um e-mail para ser enviado em 3 dias
await mail.schedule({
  template: 'dica-semanal',
  to: 'usuario@exemplo.com.br',
  data: {
    name: 'João Silva',
    email: 'usuario@exemplo.com.br',
    dicas: [
      { titulo: 'Como criar seu primeiro projeto', link: '/docs/primeiros-passos' },
      { titulo: 'Integrando com APIs externas', link: '/docs/integrações' }
    ]
  }
}, dataFutura);

Provedores de E-mail

Adaptadores Incluídos

O sistema inclui adaptadores para os seguintes provedores:

SMTP

// Em src/saas-boilerplate/providers/mail/adapters/smtp.adapter.ts
import nodemailer from 'nodemailer';
import { IMailAdapter, MailAdapterSendParams } from '../interfaces/adapter.interface';

export const smtpAdapter: IMailAdapter = {
  send: async (options: MailAdapterSendParams) => {
    const { to, subject, html, text, from, scheduledAt } = options;
    
    const transporter = nodemailer.createTransport(options.secret);
    
    const mailOptions = {
      from: from,
      to,
      subject,
      html,
      text,
      date: scheduledAt
    };
    
    await transporter.sendMail(mailOptions);
  }
};

Resend

// Em src/saas-boilerplate/providers/mail/adapters/resend.adapter.ts
import { Resend } from 'resend';
import { IMailAdapter, MailAdapterSendParams } from '../interfaces/adapter.interface';

export const resendAdapter: IMailAdapter = {
  send: async (options: MailAdapterSendParams) => {
    const { to, subject, html, text, from, secret, scheduledAt } = options;
    
    const resend = new Resend(secret);
    
    await resend.emails.create({
      to,      
      from,
      subject,
      html,
      text,
      scheduledAt: scheduledAt?.toISOString()
    });
  }
};

Criando um Novo Adaptador

Para adicionar suporte a um novo provedor de e-mail, crie um novo adaptador:

// Em src/saas-boilerplate/providers/mail/adapters/meu-provedor.adapter.ts
import { IMailAdapter, MailAdapterSendParams } from '../interfaces/adapter.interface';

export const meuProvedorAdapter: IMailAdapter = {
  send: async (options: MailAdapterSendParams) => {
    const { to, subject, html, text, from, secret, scheduledAt } = options;
    
    // Implementação específica do provedor
    // ...
  }
};

Personalização

Branding

Para personalizar o branding dos e-mails, edite as configurações em src/configs/app.config.ts:

export const AppConfig = { 
  name: 'Meu SaaS',
  brand: {    
    logos: {      
      icon: {        
        dark: '/assets/logo-icon-light.svg',        
        light: '/assets/logo-icon-dark.svg',
      },      
      full: {        
        dark: '/assets/logo-dark-light.svg',        
        light: '/assets/logo-dark-dark.svg',
      },
    },
  },  
  creator: {    
    name: 'Seu Nome',
    // ...
  },
  // ...
}

Componentes Reutilizáveis

Crie componentes reutilizáveis para manter a consistência entre seus templates:

// Em src/content/mails/components/button.tsx
import * as ReactEmail from '@react-email/components'

export const Button = ({ 
  href, 
  children 
}: { 
  href: string; 
  children: React.ReactNode 
}) => {
  return (
    <ReactEmail.Button
      href={href}
      className="rounded bg-blue-600 px-4 py-2 font-semibold text-white"
    >
      {children}
    </ReactEmail.Button>
  );
};

Testes

Teste Local com MailHog

Para testar seus e-mails localmente sem enviá-los para destinatários reais, use o MailHog:

  1. Instale o MailHog usando Docker:
docker run -d -p 1025:1025 -p 8025:8025 mailhog/mailhog
  1. Configure o adaptador SMTP para usar o MailHog:
MAIL_PROVIDER=smtp
MAIL_SECRET=smtp://localhost:1025
  1. Acesse a interface do MailHog em http://localhost:8025 para ver os e-mails enviados.

Pré-visualização de Templates

Para visualizar seus templates sem enviar e-mails:

// Em src/app/mail-preview/page.tsx
import { welcomeEmailTemplate } from '@/content/mails/welcome.email';

export default function MailPreviewPage() {
  return (
    <div>
      {welcomeEmailTemplate.render({
        name: 'Usuário de Teste',
        email: 'teste@exemplo.com.br'
      })}
    </div>
  );
}

Considerações de Segurança

  • Nunca inclua informações sensíveis em e-mails transacionais
  • Valide os endereços de e-mail antes de enviar mensagens
  • Use SPF, DKIM e DMARC para melhorar a entregabilidade e segurança
  • Implemente rate limiting para evitar abuso do sistema de e-mail

Melhores Práticas

  1. Mantenha os e-mails simples e diretos: Foque em uma única ação por e-mail
  2. Otimize para dispositivos móveis: A maioria dos e-mails é lida em smartphones
  3. Teste em diferentes clientes de e-mail: Outlook, Gmail, Apple Mail, etc.
  4. Personalize o conteúdo: Use o nome do usuário e outras informações relevantes
  5. Inclua texto alternativo: Para clientes de e-mail que não suportam HTML

Próximos Passos

  1. Personalize os templates existentes para corresponder à sua marca
  2. Crie novos templates para pontos específicos da jornada do usuário
  3. Configure o provedor de e-mail de sua preferência
  4. Implemente testes A/B para otimizar suas taxas de abertura e clique

Com este sistema implementado, você pode oferecer uma experiência de comunicação profissional e consistente para seus usuários em todos os pontos de contato.

SaaS Boilerplate

Acelere seu desenvolvimento

Construa aplicações SaaS completas em minutos com nosso boilerplate moderno. Autenticação, pagamentos, gerenciamento de usuários e muito mais!

Conheça o SaaS Boilerplate

Você também pode gostar