Skip to main content

Event System

React to email lifecycle events using @nestjs/event-emitter.

Setup

Install the event emitter package:

pnpm add @nestjs/event-emitter

Register it in your app module:

import { EventEmitterModule } from '@nestjs/event-emitter';

@Module({
imports: [
EventEmitterModule.forRoot(),
MailerModule.forRoot({ ... }),
],
})
export class AppModule {}

Available Events

EventDescription
mailer.before_sendEmitted before an email is sent
mailer.after_sendEmitted after successful send
mailer.send_errorEmitted when send fails
mailer.queuedEmitted when email is added to queue
mailer.queue.completedEmitted when queued email is sent
mailer.queue.failedEmitted when queued email fails

Listening to Events

Use the @OnEvent() decorator:

import { OnEvent } from '@nestjs/event-emitter';
import { MailerEvent, MailerEventPayload } from '@nestjs-modules/mailer';

@Injectable()
export class EmailEventListener {
@OnEvent(MailerEvent.AFTER_SEND)
handleEmailSent(payload: MailerEventPayload) {
console.log('Email sent to:', payload.mailOptions.to);
console.log('Message ID:', payload.result?.messageId);
}

@OnEvent(MailerEvent.SEND_ERROR)
handleEmailError(payload: MailerEventPayload) {
console.error('Email failed:', payload.error?.message);
// Log to monitoring, retry, etc.
}
}

Use Cases

Logging

@OnEvent(MailerEvent.AFTER_SEND)
async logEmail(payload: MailerEventPayload) {
await this.emailLogService.create({
to: payload.mailOptions.to,
subject: payload.mailOptions.subject,
template: payload.mailOptions.template,
sentAt: payload.timestamp,
messageId: payload.result?.messageId,
});
}

Metrics

@OnEvent(MailerEvent.AFTER_SEND)
trackSuccess() {
this.metricsService.increment('emails.sent');
}

@OnEvent(MailerEvent.SEND_ERROR)
trackFailure() {
this.metricsService.increment('emails.failed');
}
info

The event system is optional. If @nestjs/event-emitter is not installed, events are silently skipped with zero overhead.