@chelseaapps/notification documentation

import { InjectQueue } from '@nestjs/bull';
import { Queue } from 'bull';
import { Injectable, Inject, Logger } from '@nestjs/common';
import { NOTIFICATION_OPTIONS } from './constants';
import { INotificationUser, NotificationOptions } from './interfaces';
import { INotification, NotificationMethod } from './interfaces/notification.interface';
import { ISMSPayload } from './sms/sms.interface';
import { IEmailPayload } from './email/email.interface';

interface INotificationService {
    send(notification: INotification): Promise<void>;
}

@Injectable()
export class NotificationService implements INotificationService {
    private readonly logger = new Logger(NotificationService.name);

    constructor(
        @Inject(NOTIFICATION_OPTIONS)
        private _NotificationOptions: NotificationOptions,
        @InjectQueue('email') private emailQueue: Queue,
        @InjectQueue('sms') private smsQueue: Queue,
    ) {}

    /**
     * Send a notification to a set of users
     * @param notification Notification object
     */
    async send(notification: INotification): Promise<void> {
        if (notification.methods.length === 0) throw new Error('No notification methods specified');

        let to: INotificationUser[] = [];
        to = to.concat(notification.to);

        if (to.length === 0) return;

        this.logger.debug(`Notification recieved [${notification.methods}]]`);

        // Send email
        if (notification.methods.includes(NotificationMethod.Email)) {
            if (
                !this.isTextGiven(notification.subject) ||
                (!this.isTextGiven(notification.body) && !this.isTextGiven(notification.emailBody))
            ) {
                throw new Error('No notification subject given');
            }

            const emailAddresses = to.map((user) => user.email);

            // Format queue payload
            const payload: IEmailPayload = {
                to: emailAddresses,
                subject: notification.subject!,
                body: notification.emailBody ?? notification.body ?? '',
                from: notification.from ?? this._NotificationOptions.email.from,
            };

            // Add to queue to be sent
            await this.emailQueue.add(payload);
        }
        if (notification.methods.includes(NotificationMethod.Push)) {
            // Send push notification
        }
        if (notification.methods.includes(NotificationMethod.SMS)) {
            // Send text notification
            if (!this.isTextGiven(notification.body) && !this.isTextGiven(notification.smsBody)) {
                throw new Error('No notification body given');
            }

            const mobileNumbers = to.map((user) => user.phone);

            // Format queue payload
            const payload: ISMSPayload = {
                to: mobileNumbers,
                message: notification.smsBody ?? notification.body ?? '',
            };

            // Add to queue to be sent
            await this.smsQueue.add(payload);
        }
    }

    private isTextGiven(text?: string | null): boolean {
        return !!(text && text.trim().length > 0);
    }
}

Was this helpful?