mirror of
https://github.com/HamzaSha1/zod-backend.git
synced 2025-08-25 21:59:40 +00:00
79 lines
2.8 KiB
TypeScript
79 lines
2.8 KiB
TypeScript
import { Injectable } from '@nestjs/common';
|
|
import { EventEmitter2, OnEvent } from '@nestjs/event-emitter';
|
|
import { PageOptionsRequestDto } from '~/core/dtos';
|
|
import { DeviceService } from '~/user/services';
|
|
import { OTP_BODY, OTP_TITLE } from '../../otp/constants';
|
|
import { OtpType } from '../../otp/enums';
|
|
import { ISendOtp } from '../../otp/interfaces';
|
|
import { Notification } from '../entities';
|
|
import { EventType, NotificationChannel, NotificationScope } from '../enums';
|
|
import { NotificationsRepository } from '../repositories';
|
|
import { FirebaseService } from './firebase.service';
|
|
import { TwilioService } from './twilio.service';
|
|
|
|
@Injectable()
|
|
export class NotificationsService {
|
|
constructor(
|
|
private readonly firebaseService: FirebaseService,
|
|
private readonly notificationRepository: NotificationsRepository,
|
|
private readonly twilioService: TwilioService,
|
|
private readonly eventEmitter: EventEmitter2,
|
|
private readonly deviceService: DeviceService,
|
|
) {}
|
|
|
|
async sendPushNotification(userId: string, title: string, body: string) {
|
|
// Get the device tokens for the user
|
|
|
|
const tokens = await this.deviceService.getTokens(userId);
|
|
|
|
if (!tokens.length) {
|
|
return;
|
|
}
|
|
// Send the notification
|
|
return this.firebaseService.sendNotification(tokens, title, body);
|
|
}
|
|
|
|
async sendSMS(to: string, body: string) {
|
|
await this.twilioService.sendSMS(to, body);
|
|
}
|
|
|
|
async getNotifications(userId: string, pageOptionsDto: PageOptionsRequestDto) {
|
|
const [[notifications, count], unreadCount] = await Promise.all([
|
|
this.notificationRepository.getNotifications(userId, pageOptionsDto),
|
|
this.notificationRepository.getUnreadNotificationsCount(userId),
|
|
]);
|
|
|
|
return { notifications, count, unreadCount };
|
|
}
|
|
|
|
createNotification(notification: Partial<Notification>) {
|
|
return this.notificationRepository.createNotification(notification);
|
|
}
|
|
|
|
markAsRead(userId: string) {
|
|
return this.notificationRepository.markAsRead(userId);
|
|
}
|
|
|
|
async sendOtpNotification(sendOtpRequest: ISendOtp, otp: string) {
|
|
const notification = await this.createNotification({
|
|
recipient: sendOtpRequest.recipient,
|
|
title: OTP_TITLE,
|
|
message: OTP_BODY.replace('{otp}', otp),
|
|
scope: NotificationScope.OTP,
|
|
channel: sendOtpRequest.otpType === OtpType.EMAIL ? NotificationChannel.EMAIL : NotificationChannel.SMS,
|
|
});
|
|
|
|
return this.eventEmitter.emit(EventType.NOTIFICATION_CREATED, notification);
|
|
}
|
|
|
|
@OnEvent(EventType.NOTIFICATION_CREATED)
|
|
handleNotificationCreatedEvent(notification: Notification) {
|
|
switch (notification.channel) {
|
|
case NotificationChannel.SMS:
|
|
return this.sendSMS(notification.recipient!, notification.message);
|
|
case NotificationChannel.PUSH:
|
|
return this.sendPushNotification(notification.userId, notification.title, notification.message);
|
|
}
|
|
}
|
|
}
|