Aviary
Recipes

Telescope integration

Record every notification delivery in the nestjs-telescope dashboard with one watcher. It listens to the events the core already emits — no monkey-patching, no call-site changes.

If you run nestjs-telescope, you can see every notification — sent or failed, with its payload — right in the dashboard. The @dudousxd/nestjs-notifications-telescope package ships a watcher that plugs straight in. It works by listening to the notification.sent / notification.failed events the core already emits, so there's nothing to wire at your call sites.

Install

The package has @dudousxd/nestjs-telescope as a peer dependency — you'll already have it if you're using Telescope.

pnpm add @dudousxd/nestjs-notifications-telescope @dudousxd/nestjs-telescope
npm install @dudousxd/nestjs-notifications-telescope @dudousxd/nestjs-telescope

Register the watcher

Add NotificationsWatcher to Telescope's watchers array:

app.module.ts
import { EventEmitterModule } from '@nestjs/event-emitter';
import { NotificationsModule } from '@dudousxd/nestjs-notifications-core';
import { TelescopeModule } from '@dudousxd/nestjs-telescope';
import { NotificationsWatcher } from '@dudousxd/nestjs-notifications-telescope';

@Module({
  imports: [
    EventEmitterModule.forRoot(), // required — the watcher subscribes to its events
    NotificationsModule.forRoot(),
    TelescopeModule.forRoot({
      watchers: [new NotificationsWatcher()], 
    }),
  ],
})
export class AppModule {}

The watcher subscribes to the core's events through @nestjs/event-emitter. You must have EventEmitterModule.forRoot() in the app — without it the watcher logs a warning and records nothing. (You already need it for NotificationsModule anyway.)

What gets recorded

Every successful or failed channel delivery becomes one Telescope entry of type notification. The entry content captures:

FieldWhat it holds
channelThe channel that delivered (mail, sms, …)
notifiableA label for the recipient — Type#id if it has toNotifiableRef(), else the class name, or null
notificationClassThe notification's notificationName or class name
status'sent' or 'failed'
payloadA structural snapshot of the notification (functions stripped), or null
failureReasonThe error message when status is 'failed', else null

Entries are tagged channel:<name>, notification:<class>, and failed (on failures) so you can filter the dashboard quickly.

One notification routed to three channels produces three entries — one per delivery — because the watcher reacts to per-channel events, not per-send.

Omitting the payload

By default the watcher snapshots the notification's own data as the entry payload. If your notifications carry sensitive fields, turn it off — payload will be recorded as null while everything else still flows:

new NotificationsWatcher({ recordPayload: false });

See also

On this page