Channels
A channel is a transport — mail, database, Slack, and the real-time SSE / WebSocket channels. Import a channel's module and it registers itself; the notification's to<Channel>() method shapes the payload.
A channel is a transport: it takes a notification and delivers it over one medium — an email,
a persisted row, a websocket push, a Slack message. A notification declares a channel by annotating
a payload method with the channel's handle (@Mail(), @Database(), …); the channels are then
inferred, and each channel reads that one to<Channel>() method for its payload.
For the conceptual split between channels (where it goes) and dispatchers (when it goes), see Channels vs. dispatchers.
Built-in channels
| Channel | Package | Handle / decorator | Reads | Notification interface |
|---|---|---|---|---|
mail | @dudousxd/nestjs-notifications-mail | Mail / @Mail() | toMail() | MailNotification |
database | @dudousxd/nestjs-notifications-database | Database / @Database() | toDatabase() | DatabaseNotification |
broadcast | @dudousxd/nestjs-notifications-broadcast | Broadcast / @Broadcast() | toBroadcast() | BroadcastNotification |
slack | @dudousxd/nestjs-notifications-slack | Slack / @Slack() | toSlack() | SlackNotification |
discord | @dudousxd/nestjs-notifications-discord | Discord / @Discord() | toDiscord() | DiscordNotification |
telegram | @dudousxd/nestjs-notifications-telegram | Telegram / @Telegram() | toTelegram() | TelegramNotification |
teams | @dudousxd/nestjs-notifications-teams | Teams / @Teams() | toTeams() | TeamsNotification |
sse | @dudousxd/nestjs-notifications-sse | Sse / @Sse() | toSse() | SseNotification |
webhook | @dudousxd/nestjs-notifications-webhook | Webhook / @Webhook() | toWebhook() | WebhookNotification |
sms | @dudousxd/nestjs-notifications-sms | Sms / @Sms() | toSms() | SmsNotification |
push | @dudousxd/nestjs-notifications-push | Push / @Push() | toPush() | PushNotification |
Each channel ships as its own package, so you only pull in what you send. The handle is both the
method decorator that declares a payload (@Mail()) and a type-safe token you can return from
via() — see Notifications.
Real-time / in-app delivery
sse and broadcast aren't just two more transports — they're how you deliver notifications
live, into your app: the unread badge, the feed that updates without a refresh.
SSE (native NestJS Server-Sent Events) is the lightweight default;
broadcast uses socket.io when you want a WebSocket. Pair either with
the persisted database channel — see the
Real-time & in-app guide.
Registration is just an import
There is no channels array to maintain. Each *ChannelModule.forRoot() provides a ChannelDriver,
and the core finds it through Nest's DiscoveryService at startup. Import the module once in your
root module and the channel is live — usable from any notification via its decorator handle.
import { NotificationsModule } from '@dudousxd/nestjs-notifications-core';
import { MailChannelModule } from '@dudousxd/nestjs-notifications-mail';
import { SlackChannelModule } from '@dudousxd/nestjs-notifications-slack';
@Module({
imports: [
NotificationsModule.forRoot(),
MailChannelModule.forRoot({ from: 'no-reply@example.com' }),
SlackChannelModule.forRoot({ webhookUrl: process.env.SLACK_WEBHOOK_URL }),
],
})
export class AppModule {}Every channel module is global: true by default, so a single registration in the root module
makes it discoverable app-wide. Set global: false to scope it to the importing module.
When a payload method is missing
If via() routes a notification to a channel but the notification doesn't implement that channel's
method, the channel throws a MissingChannelMethodError at send time:
Notification "InvoicePaid" is routed to the "mail" channel but does not implement
toMail(). Implement it to define the channel payload.Implement the channel's notification interface (MailNotification, SlackNotification, …) to turn
that runtime error into a compile-time one.
Routing a channel that no module registered throws a different error —
ChannelNotRegisteredError — which lists the channels that are registered. That usually means
you forgot to import the channel's module.
Build your own
Need a channel that isn't built in? A channel is just a class with a channel name and a
send() method. See Writing a custom channel.
Localization (i18n)
Translate each notification per recipient. Resolve a locale off the notifiable, look strings up in a catalog (or your own translator), and render channel payloads in the recipient's language with localization.t().
Send email notifications. A fluent MailMessage builder, an HTML + text renderer, and a swappable transport — nodemailer SMTP out of the box.