@nestbolt/notifications
Configuration
Configure @nestbolt/notifications with forRoot() and forRootAsync() -- database channel, mail transport, default sender, and custom channels.
The NotificationModule supports two configuration methods: forRoot() for static configuration and forRootAsync() for dynamic configuration using dependency injection. Both register the module globally, so you only need to import it once in your root module.
Static Configuration (forRoot)
Use forRoot() when your configuration values are known at compile time:
import { Module } from "@nestjs/common";
import { NotificationModule } from "@nestbolt/notifications";
@Module({
imports: [
NotificationModule.forRoot({
channels: {
database: true,
mail: {
transport: {
host: "smtp.example.com",
port: 587,
secure: false,
auth: {
user: "user@example.com",
pass: "password",
},
},
defaults: {
from: "noreply@example.com",
},
},
},
}),
],
})
export class AppModule {}Async Configuration (forRootAsync)
Use forRootAsync() when configuration values come from environment variables, a config service, or any other async source:
import { Module } from "@nestjs/common";
import { ConfigModule, ConfigService } from "@nestjs/config";
import { NotificationModule } from "@nestbolt/notifications";
@Module({
imports: [
ConfigModule.forRoot(),
NotificationModule.forRootAsync({
imports: [ConfigModule],
inject: [ConfigService],
useFactory: (config: ConfigService) => ({
channels: {
database: true,
mail: {
transport: {
host: config.get<string>("SMTP_HOST"),
port: config.get<number>("SMTP_PORT"),
secure: config.get<boolean>("SMTP_SECURE", false),
auth: {
user: config.get<string>("SMTP_USER"),
pass: config.get<string>("SMTP_PASS"),
},
},
defaults: {
from: config.get<string>("MAIL_FROM", "noreply@example.com"),
},
},
},
}),
}),
],
})
export class AppModule {}The forRootAsync() method accepts the following options:
| Option | Type | Description |
|---|---|---|
imports | any[] | Modules to import (e.g., ConfigModule). |
inject | any[] | Providers to inject into useFactory. |
useFactory | (...args) => NotificationModuleOptions | Factory function that returns the module options. |
customChannels | Record<string, Type<NotificationChannel>> | Custom channel classes to register (see below). |
The useFactory function can also return a Promise<NotificationModuleOptions> for async initialization.
NotificationModuleOptions
The options object passed to forRoot() or returned from useFactory has the following shape:
interface NotificationModuleOptions {
channels?: {
database?: boolean;
mail?: MailChannelOptions;
custom?: Record<string, Type<NotificationChannel>>;
};
}channels.database
| Type | Default | Description |
|---|---|---|
boolean | true | Enable or disable the database channel. |
The database channel is enabled by default. It stores notification payloads in the notifications table via TypeORM. Set it to false to disable it entirely:
NotificationModule.forRoot({
channels: {
database: false, // Disable database notifications
mail: { /* ... */ },
},
});channels.mail
| Type | Default | Description |
|---|---|---|
MailChannelOptions | undefined | Mail channel configuration. |
If not provided, the mail channel is not registered. Attempting to send a notification via the "mail" channel without configuring it will throw a ChannelNotFoundException.
The MailChannelOptions interface:
interface MailChannelOptions {
transport: {
host: string;
port: number;
secure?: boolean;
auth?: {
user: string;
pass: string;
};
};
defaults?: {
from?: string;
};
}transport
The transport object is passed directly to nodemailer.createTransport(). It supports any transport configuration that nodemailer accepts.
| Property | Type | Description |
|---|---|---|
host | string | SMTP server hostname. |
port | number | SMTP server port (typically 25, 465, or 587). |
secure | boolean | Use TLS. Set true for port 465, false for STARTTLS on 587. |
auth | object | Authentication credentials. |
auth.user | string | SMTP username. |
auth.pass | string | SMTP password. |
defaults
| Property | Type | Description |
|---|---|---|
from | string | Default sender address used when a notification does not specify one via MailMessage.from(). |
channels.custom
| Type | Default | Description |
|---|---|---|
Record<string, Type<NotificationChannel>> | undefined | A map of channel names to channel classes. |
Register custom channel implementations. Each key is the channel name (used in via()), and each value is the class (not an instance) of a provider implementing NotificationChannel.
NotificationModule.forRoot({
channels: {
database: true,
custom: {
slack: SlackChannel,
sms: TwilioSmsChannel,
webhook: WebhookChannel,
},
},
});See Custom Channels for details on implementing custom channels.
Registering Custom Channels with forRootAsync
When using forRootAsync(), custom channels are registered via the top-level customChannels option rather than inside useFactory. This is because custom channel classes need to be registered as NestJS providers before the factory runs:
import { SlackChannel } from "./channels/slack.channel";
NotificationModule.forRootAsync({
imports: [ConfigModule],
inject: [ConfigService],
useFactory: (config: ConfigService) => ({
channels: {
database: true,
mail: {
transport: {
host: config.get("SMTP_HOST"),
port: config.get("SMTP_PORT"),
auth: {
user: config.get("SMTP_USER"),
pass: config.get("SMTP_PASS"),
},
},
},
},
}),
customChannels: {
slack: SlackChannel,
},
});Database-Only Configuration
The simplest possible configuration enables only the database channel:
NotificationModule.forRoot({
channels: {
database: true,
},
});Since database: true is the default, you can also call forRoot() with no arguments:
NotificationModule.forRoot();Mail-Only Configuration
If you only need email notifications and do not want database storage:
NotificationModule.forRoot({
channels: {
database: false,
mail: {
transport: {
host: "smtp.example.com",
port: 587,
auth: { user: "user", pass: "pass" },
},
defaults: { from: "noreply@example.com" },
},
},
});Global Registration
Both forRoot() and forRootAsync() register the module as global. This means NotificationService and other exported providers are available in every module of your application without needing to re-import NotificationModule.
The following are exported from the module and available for injection:
| Provider | Description |
|---|---|
NotificationService | The main service for sending and querying notifications. |
ChannelManager | The internal channel registry (rarely needed directly). |
NOTIFICATION_OPTIONS | The raw options object (injection token). |
Quick Start
Get up and running with @nestbolt/notifications in three steps -- register the module, create a notification, and send it.
Creating Notifications
Learn how to create notification classes by extending the Notification base class, defining delivery channels, and implementing channel-specific methods.