Email SDKs injected into domain modules
Injecting Nodemailer or a provider SDK into BillingModule or AuthModule couples domain logic to delivery infrastructure.
NestJS integration
Create an injectable EmailService that wraps the else.events API. Any NestJS module fires typed domain events — no email library in your providers tree.
Injecting Nodemailer or a provider SDK into BillingModule or AuthModule couples domain logic to delivery infrastructure.
Inline templates or template file paths scattered across providers make copy changes require code reviews.
Multiple providers.send() call sites mean you cannot quickly answer "which emails did this user receive?".
Moving from one email library to another requires updating every NestJS provider that injects it.
A single EmailService with a sendEvent() method. Inject it anywhere. The HTTP call to else.events is the entire implementation.
Define a PaymentFailedEvent DTO. Your billing service stays type-safe — no template names, no magic strings.
Change the delivery provider in else.events config. No changes to your NestJS module graph.
else.events is built by a team that uses NestJS. The event-driven model maps directly to NestJS domain events and CQRS patterns.
// NestJS — injectable EmailService
// email/email.service.ts
@Injectable()
export class EmailService {
async sendEvent(type: string, user: { email: string; name: string }, data: Record<string, unknown>) {
await fetch('https://app.else.events/api/events', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.ELSE_EVENTS_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ type, user, data }),
});
}
}
// billing/billing.service.ts
@Injectable()
export class BillingService {
constructor(private readonly email: EmailService) {}
async handlePaymentFailure(invoice: Invoice) {
await this.email.sendEvent('invoice.payment_failed',
{ email: invoice.user.email, name: invoice.user.name },
{ plan: invoice.plan, amount: invoice.amount, currency: invoice.currency,
update_payment_url: `https://app.example.com/billing` },
);
}
} BillingService knows nothing about email templates. EmailService is the only module that talks to else.events. Provider changes affect exactly one file.
One injectable service. Typed events. Templates managed outside your repository.