Skip to content

platform-mailing

Multi-strategy email delivery system with pluggable transports (SMTP, Postmark, Resend, SendGrid, Mailgun, Log), template engines (file-based, blob-based), and email verification support. Each external provider SDK is an optional peer dependency — install only the one you need.

Package: @breadstone/archipel-platform-mailing

Architecture


Quick Start

typescript
import { Module } from '@nestjs/common';
import { MailModule } from '@breadstone/archipel-platform-mailing';

@Module({
  imports: [MailModule],
})
export class AppModule {}

The module auto-selects delivery and template strategies based on environment variables.


Environment Variables

Core

VariableDescriptionValuesRequired
MAIL_SENDER_EMAILDefault "from" addressnoreply@example.comYes
MAIL_DELIVERY_STRATEGYTransport strategy'smtp' / 'postmark' / 'resend' / 'sendgrid' / 'mailgun' / 'log'Yes
MAIL_TEMPLATE_STRATEGYTemplate source'file' / 'blob'Yes
MAIL_TEMPLATE_ENGINE_FORMATTemplate format'html' / 'txt'Yes

SMTP (built-in)

VariableDescriptionDefaultRequired
MAIL_SMTP_HOSTSMTP server hostlocalhostIf SMTP
MAIL_SMTP_PORTSMTP server port587If SMTP
MAIL_SMTP_SECUREUse TLSfalseNo
MAIL_SMTP_USERAuth usernameIf SMTP
MAIL_SMTP_PASSWORDAuth passwordIf SMTP

Delivery Providers

Postmark

Subpath: @breadstone/archipel-platform-mailing/postmarkSDK: postmark ≥ 4.0.0

VariableDescriptionRequired
MAIL_POSTMARK_API_KEYPostmark API keyYes
typescript
import { PostmarkDeliveryStrategy, POSTMARK_CONFIG_ENTRIES } from '@breadstone/archipel-platform-mailing/postmark';

Resend

Subpath: @breadstone/archipel-platform-mailing/resendSDK: resend ≥ 4.0.0

VariableDescriptionRequired
MAIL_RESEND_API_KEYResend API keyYes
typescript
import { ResendDeliveryStrategy, RESEND_CONFIG_ENTRIES } from '@breadstone/archipel-platform-mailing/resend';

SendGrid

Subpath: @breadstone/archipel-platform-mailing/sendgridSDK: @sendgrid/mail ≥ 8.0.0

VariableDescriptionRequired
MAIL_SENDGRID_API_KEYSendGrid API keyYes
typescript
import { SendGridDeliveryStrategy, SENDGRID_CONFIG_ENTRIES } from '@breadstone/archipel-platform-mailing/sendgrid';

Mailgun

Subpath: @breadstone/archipel-platform-mailing/mailgunSDK: mailgun.js ≥ 10.0.0

VariableDescriptionRequired
MAIL_MAILGUN_API_KEYMailgun API keyYes
MAIL_MAILGUN_DOMAINMailgun domain (e.g. mg.example.com)Yes
typescript
import { MailgunDeliveryStrategy, MAILGUN_CONFIG_ENTRIES } from '@breadstone/archipel-platform-mailing/mailgun';

Log (built-in)

Logs emails to the console. No SDK or env vars required — useful for development and testing.

Switching Providers

Change a single environment variable — no code change needed:

bash
# Switch from SMTP to Resend
MAIL_DELIVERY_STRATEGY=resend
MAIL_RESEND_API_KEY=re_xxxxxxxxxxxx

DeliveryStrategyBase

All providers extend this abstract contract:

typescript
abstract class DeliveryStrategyBase {
  abstract send(from: string, to: string, subject: string, content: string, isHtml: boolean): Promise<void>;
}

MailService

Core service for sending emails.

Send Plain Email

typescript
import { MailService } from '@breadstone/archipel-platform-mailing';

@Injectable()
export class NotificationService {
  constructor(private readonly _mail: MailService) {}

  public async sendWelcome(userEmail: string, userName: string): Promise<void> {
    await this._mail.send(
      { to: userEmail, subject: `Welcome, ${userName}!` },
      `<h1>Welcome</h1><p>Hey ${userName}, we're glad you're here.</p>`,
      true, // isHtml
    );
  }
}

Send Templated Email

typescript
await this._mail.sendTemplate(
  { to: userEmail, subject: 'Your Order Confirmation' },
  {
    templateName: 'order-confirmation',
    templateParams: {
      orderNumber: 'ORD-12345',
      total: '€39.97',
    },
  },
);

Custom Sender

typescript
await this._mail.send(
  {
    from: 'support@example.com', // overrides MAIL_SENDER_EMAIL
    to: 'customer@example.com',
    subject: 'Support Ticket #4567',
  },
  'Your ticket has been received.',
  false, // plain text
);

Template Strategies

File-Based Templates

Load templates from the filesystem:

typescript
// Set MAIL_TEMPLATE_STRATEGY=file
// Templates stored as files: assets/templates/welcome.html

Blob-Based Templates

Load templates from blob storage (e.g., Vercel Blob):

typescript
// Set MAIL_TEMPLATE_STRATEGY=blob
// Templates stored in blob storage: templates/welcome.html

MailVerificationService

Email address verification flow:

typescript
import { MailVerificationService } from '@breadstone/archipel-platform-mailing';

@Injectable()
export class RegistrationService {
  constructor(private readonly _mailVerification: MailVerificationService) {}

  public async sendVerification(email: string): Promise<void> {
    await this._mailVerification.sendVerificationEmail(email);
  }
}

Health Check

typescript
import { MailHealthIndicator } from '@breadstone/archipel-platform-mailing';

// Registered with HealthOrchestrator automatically
// Checks mail delivery readiness

Real-World Example: Transactional Email Pipeline

typescript
@Injectable()
export class OrderEmailService {
  constructor(
    private readonly _mail: MailService,
    private readonly _analytics: AnalyticsService,
  ) {}

  public async sendOrderConfirmation(order: IOrder): Promise<void> {
    try {
      await this._mail.sendTemplate(
        {
          to: order.customerEmail,
          subject: `Order ${order.number} Confirmed`,
        },
        {
          templateName: 'order-confirmation',
          templateParams: {
            customerName: order.customerName,
            orderNumber: order.number,
            total: `€${order.total.toFixed(2)}`,
            deliveryDate: order.estimatedDelivery.toLocaleDateString('de-DE'),
          },
        },
      );
    } catch (error) {
      this._analytics.captureException(error, {
        tags: { module: 'mailing', orderId: order.id },
      });
    }
  }
}

Exports Summary

Core (@breadstone/archipel-platform-mailing)

ExportTypeDescription
MailModuleNestJS ModuleGlobal mail module
MailServiceServiceSend emails (plain + templated)
MailVerificationServiceServiceEmail verification
MailTemplateEngineServiceTemplate variable substitution
DeliveryStrategyBaseAbstract classBase for delivery strategies
SmtpDeliveryStrategyStrategySMTP transport (built-in)
LogDeliveryStrategyStrategyLog-only (built-in)
ResendDeliveryStrategyStrategyResend API
SendGridDeliveryStrategyStrategySendGrid API
MailgunDeliveryStrategyStrategyMailgun API
FileTemplateFetchStrategyStrategyFile-based templates
BlobTemplateFetchStrategyStrategyBlob-stored templates
MailHealthIndicatorHealthMail readiness check

Provider subpaths

SubpathExports
/postmarkPostmarkDeliveryStrategy, POSTMARK_API_KEY, POSTMARK_CONFIG_ENTRIES
/resendResendDeliveryStrategy, RESEND_API_KEY, RESEND_CONFIG_ENTRIES
/sendgridSendGridDeliveryStrategy, SENDGRID_API_KEY, SENDGRID_CONFIG_ENTRIES
/mailgunMailgunDeliveryStrategy, MAILGUN_API_KEY, MAILGUN_DOMAIN, MAILGUN_CONFIG_ENTRIES

Released under the MIT License.