npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@groundbrick/email-service

v1.1.4

Published

Serviço de Email plugável com suporte a múltiplos provedores (GatewayAPI, SMTP, etc)

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-service

Uso 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, campaignTags e campaignType
  • headers (até 5 cabeçalhos customizados)
  • listUnsub ({ method?: 'mailto' | 'one-click'; value: string })
  • dryRun e expires
  • variables ou perRecipientVariables (array de objetos na mesma ordem dos destinatários)
  • clientId, channel e provider (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 headers webhook-id, webhook-timestamp e webhook-signature sejam repassadas para validateWebhook através do parâmetro headers.

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:

  1. Obtenha um token em GatewayAPI
  2. Configure webhook (opcional) para receber notificações de entrega
  3. 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

  1. Crie um API Key ou OAuth Client em app.sweego.io
  2. Configure e verifique um subdomínio dedicado para envio
  3. 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

  • apiKey ou accessToken (Bearer)
  • clientId para definir o cabeçalho client-id
  • baseUrl, channel e providerSlug (casos de sandbox)
  • webhookSecret (Base64) para validar webhook-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