@groundbrick/email-service
v1.1.4
Published
Serviço de Email plugável com suporte a múltiplos provedores (GatewayAPI, SMTP, etc)
Maintainers
Readme
@groundbrick/email-service
Serviço de email plugável com suporte a múltiplos provedores (GatewayAPI, SMTP, etc.) para TypeScript/Node.js.
Características
- 📧 Múltiplos Providers: GatewayAPI, Sweego, Mock, Redirect
- 🔄 Múltiplas Instâncias: Diferente do sms-service, permite múltiplas configurações
- 🎯 Webhooks: Suporte completo para webhooks de entrega
- 📝 Templates: Variáveis dinâmicas em HTML/texto/subject
- 📊 Tracking: Rastreamento de aberturas e cliques (GatewayAPI)
- 📎 Anexos: Suporte a anexos com base64
- 🔒 Type-Safe: 100% TypeScript com tipos completos
- 🧪 Testável: Mock e Redirect providers para desenvolvimento
Instalação
npm install @groundbrick/email-service
# ou
pnpm add @groundbrick/email-serviceUso Básico
GatewayAPI Provider (Produção)
import { EmailService } from '@groundbrick/email-service';
const emailService = new EmailService({
provider: 'gatewayapi',
config: {
token: process.env.GATEWAYAPI_EMAIL_TOKEN!,
defaultFrom: {
address: '[email protected]',
name: 'My App'
},
webhookSecret: process.env.GATEWAYAPI_WEBHOOK_SECRET // opcional
}
});
// Enviar email simples
const result = await emailService.send({
to: { address: '[email protected]', name: 'John Doe' },
subject: 'Welcome!',
html: '<h1>Hello!</h1><p>Welcome to our app.</p>',
text: 'Hello! Welcome to our app.'
});
console.log(result.messageId); // "123456"Sweego Provider (Produção)
import { EmailService } from '@groundbrick/email-service';
const sweegoEmailService = new EmailService({
provider: 'sweego',
config: {
apiKey: process.env.SWEEGO_API_KEY!, // ou defina accessToken para usar Bearer
defaultFrom: {
address: '[email protected]',
name: 'My App'
},
clientId: process.env.SWEEGO_CLIENT_ID, // opcional, repassa para o cabeçalho client-id
webhookSecret: process.env.SWEEGO_WEBHOOK_SECRET // opcional, Base64 para validar webhooks
}
});
await sweegoEmailService.send({
to: { address: '[email protected]', name: 'John Doe' },
subject: 'Welcome!',
html: '<h1>Hello!</h1><p>Welcome to our app.</p>',
metadata: {
sweego: {
campaignId: 'welcome-2025',
campaignTags: ['welcome'],
dryRun: false
}
}
});Use a chave metadata.sweego para acessar recursos específicos da API da Sweego
(campanhas, headers customizados, list-unsubscribe, variáveis por destinatário, etc.).
Veja a seção Sweego para a lista completa dos campos suportados.
Mock Provider (Testes)
const emailService = new EmailService({
provider: 'mock',
config: {
defaultFrom: { address: '[email protected]' },
simulateDelay: 100, // ms
simulateFailures: false // ou true para 10% de falhas
}
});
const result = await emailService.send({...});
// Acessar emails enviados (apenas Mock)
import { MockEmailProvider } from '@groundbrick/email-service';
const mock = emailService['provider'] as MockEmailProvider;
const sentEmails = mock.getSentEmails();Redirect Provider (Desenvolvimento)
Redireciona TODOS os emails para um endereço específico:
const emailService = new EmailService({
provider: 'redirect',
config: {
redirectTo: '[email protected]',
defaultFrom: { address: '[email protected]' },
addOriginalToSubject: true // adiciona destinatários originais no subject
}
});
// Este email será redirecionado para [email protected]
await emailService.send({
to: { address: '[email protected]' },
subject: 'Order Confirmation',
html: '<p>Your order is confirmed!</p>'
});
// Subject real: "[REDIRECTED] Order Confirmation (Original: [email protected])"Funcionalidades Avançadas
Múltiplos Destinatários (CC, BCC)
await emailService.send({
to: [
{ address: '[email protected]', name: 'User 1' },
{ address: '[email protected]' }
],
cc: [{ address: '[email protected]' }],
bcc: [{ address: '[email protected]' }],
subject: 'Meeting Tomorrow',
html: '<p>Don\'t forget our meeting!</p>'
});Anexos
await emailService.send({
to: { address: '[email protected]' },
subject: 'Invoice #1234',
html: '<p>Your invoice is attached.</p>',
attachments: [
{
filename: 'invoice.pdf',
content: pdfBuffer, // Buffer ou string
contentType: 'application/pdf'
}
]
});Templates com Variáveis
await emailService.send({
to: { address: '[email protected]' },
subject: 'Hello %firstname!',
html: '<p>Hi %firstname %lastname, your code is %code.</p>',
template: {
variables: {
firstname: 'John',
lastname: 'Doe',
code: '123456'
}
}
});Tracking de Opens/Clicks (GatewayAPI)
await emailService.send({
to: { address: '[email protected]' },
subject: 'Newsletter',
html: '<p>Check out our <a href="https://example.com">website</a>!</p>',
tracking: {
opens: true,
clicks: true
}
});Metadados específicos do Sweego
Quando estiver usando o provider sweego, utilize metadata.sweego para ativar
opções exclusivas da API:
await sweegoEmailService.send({
to: { address: '[email protected]' },
subject: 'Welcome',
html: '<p>Hello!</p>',
metadata: {
sweego: {
campaignId: 'welcome-2025',
campaignTags: ['welcome', 'prod'],
campaignType: 'transac',
headers: { 'x-custom-header': 'value' },
listUnsub: { method: 'one-click', value: 'mailto:[email protected],https://example.com/unsub' },
dryRun: false,
expires: '2025-12-31T23:59:59Z',
clientId: 'my-client',
variables: { name: 'John' }
}
}
});Campos suportados em metadata.sweego:
campaignId,campaignTagsecampaignTypeheaders(até 5 cabeçalhos customizados)listUnsub({ method?: 'mailto' | 'one-click'; value: string })dryRuneexpiresvariablesouperRecipientVariables(array de objetos na mesma ordem dos destinatários)clientId,channeleprovider(casos multi-provedor na mesma conta)
Delivery Reports
const result = await emailService.send({...});
// Consultar status depois
const report = await emailService.getDeliveryReport(result.messageId!);
console.log(report?.status); // 'delivered', 'bounced', 'failed', etc.Webhooks
// Middleware para manter o raw body (necessário para Sweego)
const rawJson = express.json({
verify: (req, _res, buf) => {
req.rawBody = buf.toString('utf8');
}
});
app.post('/api/webhooks/email', rawJson, (req, res) => {
const signature = req.headers['authorization'] || '';
const validation = emailService.validateWebhook(req.body, signature, {
headers: req.headers as Record<string, string | string[]>,
rawBody: req.rawBody // Sweego precisa do corpo original para validar o HMAC
});
if (validation.isValid && validation.payload) {
const report = validation.payload;
console.log(`Email ${report.messageId} status: ${report.status}`);
}
res.sendStatus(200);
});💡 Sweego: defina
webhookSecret(string em Base64) no config e garanta que as headerswebhook-id,webhook-timestampewebhook-signaturesejam repassadas paravalidateWebhookatravés do parâmetroheaders.
Configuração por Ambiente
const emailService = new EmailService({
provider: process.env.NODE_ENV === 'production' ? 'gatewayapi' : 'redirect',
config: process.env.NODE_ENV === 'production'
? {
token: process.env.GATEWAYAPI_EMAIL_TOKEN!,
defaultFrom: { address: '[email protected]', name: 'MyApp' }
}
: {
redirectTo: process.env.DEV_EMAIL || '[email protected]',
defaultFrom: { address: '[email protected]', name: 'MyApp [DEV]' }
}
});API Reference
EmailService
class EmailService {
constructor(config: EmailConfig)
send(message: EmailMessage): Promise<EmailResult>
getDeliveryReport(messageId: string): Promise<DeliveryReport | null>
validateWebhook(
payload: any,
signature?: string,
options?: WebhookValidationOptions
): WebhookValidationResult
}interface WebhookValidationOptions {
headers?: Record<string, string | string[] | undefined>;
rawBody?: string;
}EmailMessage
interface EmailMessage {
to: EmailAddress | EmailAddress[]
from?: EmailAddress
cc?: EmailAddress[]
bcc?: EmailAddress[]
replyTo?: EmailAddress
subject: string
text?: string
html?: string
attachments?: EmailAttachment[]
template?: EmailTemplate
tracking?: EmailTracking
metadata?: Record<string, any>
}EmailStatus
enum EmailStatus {
QUEUED = 'queued',
SENT = 'sent',
DELIVERED = 'delivered',
BOUNCED = 'bounced',
FAILED = 'failed',
DEFERRED = 'deferred',
BLOCKED = 'blocked'
}GatewayAPI
Para usar o GatewayAPI:
- Obtenha um token em GatewayAPI
- Configure webhook (opcional) para receber notificações de entrega
- Use o token no config:
const emailService = new EmailService({
provider: 'gatewayapi',
config: {
token: 'your-token-here',
baseUrl: 'https://gatewayapi.com', // opcional
webhookSecret: 'your-webhook-secret', // opcional, para validação JWT
defaultFrom: { address: '[email protected]' }
}
});Limites GatewayAPI
- Anexos: Máximo 5MB total
- Rate limits: Conforme seu plano
Sweego
- Crie um API Key ou OAuth Client em app.sweego.io
- Configure e verifique um subdomínio dedicado para envio
- Copie o segredo do webhook (menu Webhooks) e salve a versão Base64 no
webhookSecret
const emailService = new EmailService({
provider: 'sweego',
config: {
apiKey: process.env.SWEEGO_API_KEY!, // ou use accessToken
clientId: process.env.SWEEGO_CLIENT_ID,
defaultFrom: { address: '[email protected]', name: 'My App' },
webhookSecret: process.env.SWEEGO_WEBHOOK_SECRET
}
});Opções suportadas
apiKeyouaccessToken(Bearer)clientIdpara definir o cabeçalhoclient-idbaseUrl,channeleproviderSlug(casos de sandbox)webhookSecret(Base64) para validarwebhook-id/webhook-timestamp/webhook-signature
Use metadata.sweego para configurar campanhas, headers, dry-run, variáveis e
list-unsubscribe. Documentação oficial: envio por API e
assinatura de webhook.
Migração do Service-Base
Veja MIGRATION.md para guia completo de migração do antigo @groundbrick/service-base.
Licença
MIT
