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
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
| Variable | Description | Values | Required |
|---|---|---|---|
MAIL_SENDER_EMAIL | Default "from" address | noreply@example.com | Yes |
MAIL_DELIVERY_STRATEGY | Transport strategy | 'smtp' / 'postmark' / 'resend' / 'sendgrid' / 'mailgun' / 'log' | Yes |
MAIL_TEMPLATE_STRATEGY | Template source | 'file' / 'blob' | Yes |
MAIL_TEMPLATE_ENGINE_FORMAT | Template format | 'html' / 'txt' | Yes |
SMTP (built-in)
| Variable | Description | Default | Required |
|---|---|---|---|
MAIL_SMTP_HOST | SMTP server host | localhost | If SMTP |
MAIL_SMTP_PORT | SMTP server port | 587 | If SMTP |
MAIL_SMTP_SECURE | Use TLS | false | No |
MAIL_SMTP_USER | Auth username | — | If SMTP |
MAIL_SMTP_PASSWORD | Auth password | — | If SMTP |
Delivery Providers
Postmark
Subpath: @breadstone/archipel-platform-mailing/postmarkSDK: postmark ≥ 4.0.0
| Variable | Description | Required |
|---|---|---|
MAIL_POSTMARK_API_KEY | Postmark API key | Yes |
import { PostmarkDeliveryStrategy, POSTMARK_CONFIG_ENTRIES } from '@breadstone/archipel-platform-mailing/postmark';Resend
Subpath: @breadstone/archipel-platform-mailing/resendSDK: resend ≥ 4.0.0
| Variable | Description | Required |
|---|---|---|
MAIL_RESEND_API_KEY | Resend API key | Yes |
import { ResendDeliveryStrategy, RESEND_CONFIG_ENTRIES } from '@breadstone/archipel-platform-mailing/resend';SendGrid
Subpath: @breadstone/archipel-platform-mailing/sendgridSDK: @sendgrid/mail ≥ 8.0.0
| Variable | Description | Required |
|---|---|---|
MAIL_SENDGRID_API_KEY | SendGrid API key | Yes |
import { SendGridDeliveryStrategy, SENDGRID_CONFIG_ENTRIES } from '@breadstone/archipel-platform-mailing/sendgrid';Mailgun
Subpath: @breadstone/archipel-platform-mailing/mailgunSDK: mailgun.js ≥ 10.0.0
| Variable | Description | Required |
|---|---|---|
MAIL_MAILGUN_API_KEY | Mailgun API key | Yes |
MAIL_MAILGUN_DOMAIN | Mailgun domain (e.g. mg.example.com) | Yes |
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:
# Switch from SMTP to Resend
MAIL_DELIVERY_STRATEGY=resend
MAIL_RESEND_API_KEY=re_xxxxxxxxxxxxDeliveryStrategyBase
All providers extend this abstract contract:
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
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
await this._mail.sendTemplate(
{ to: userEmail, subject: 'Your Order Confirmation' },
{
templateName: 'order-confirmation',
templateParams: {
orderNumber: 'ORD-12345',
total: '€39.97',
},
},
);Custom Sender
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:
// Set MAIL_TEMPLATE_STRATEGY=file
// Templates stored as files: assets/templates/welcome.htmlBlob-Based Templates
Load templates from blob storage (e.g., Vercel Blob):
// Set MAIL_TEMPLATE_STRATEGY=blob
// Templates stored in blob storage: templates/welcome.htmlMailVerificationService
Email address verification flow:
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
import { MailHealthIndicator } from '@breadstone/archipel-platform-mailing';
// Registered with HealthOrchestrator automatically
// Checks mail delivery readinessReal-World Example: Transactional Email Pipeline
@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)
| Export | Type | Description |
|---|---|---|
MailModule | NestJS Module | Global mail module |
MailService | Service | Send emails (plain + templated) |
MailVerificationService | Service | Email verification |
MailTemplateEngine | Service | Template variable substitution |
DeliveryStrategyBase | Abstract class | Base for delivery strategies |
SmtpDeliveryStrategy | Strategy | SMTP transport (built-in) |
LogDeliveryStrategy | Strategy | Log-only (built-in) |
ResendDeliveryStrategy | Strategy | Resend API |
SendGridDeliveryStrategy | Strategy | SendGrid API |
MailgunDeliveryStrategy | Strategy | Mailgun API |
FileTemplateFetchStrategy | Strategy | File-based templates |
BlobTemplateFetchStrategy | Strategy | Blob-stored templates |
MailHealthIndicator | Health | Mail readiness check |
Provider subpaths
| Subpath | Exports |
|---|---|
/postmark | PostmarkDeliveryStrategy, POSTMARK_API_KEY, POSTMARK_CONFIG_ENTRIES |
/resend | ResendDeliveryStrategy, RESEND_API_KEY, RESEND_CONFIG_ENTRIES |
/sendgrid | SendGridDeliveryStrategy, SENDGRID_API_KEY, SENDGRID_CONFIG_ENTRIES |
/mailgun | MailgunDeliveryStrategy, MAILGUN_API_KEY, MAILGUN_DOMAIN, MAILGUN_CONFIG_ENTRIES |