src/notification/notification.service.ts
Properties |
|
Methods |
|
constructor(prisma: PrismaService, temporalProvider: TemporalProvider, emailProvider: EmailProvider)
|
||||||||||||
|
Defined in src/notification/notification.service.ts:23
|
||||||||||||
|
Parameters :
|
| Async create | ||||||||
create(createNotificationDto: CreateNotificationDto)
|
||||||||
|
Defined in src/notification/notification.service.ts:44
|
||||||||
|
Creates a new notification.
Parameters :
Returns :
Promise<Notification>
A Promise that resolves to the created notification. |
| Async createNotification | ||||||
createNotification(notificationParams: literal type)
|
||||||
|
Defined in src/notification/notification.service.ts:55
|
||||||
|
Parameters :
Returns :
unknown
|
| Async delete | ||||||||
delete(id: number)
|
||||||||
|
Defined in src/notification/notification.service.ts:222
|
||||||||
|
Soft deletes a notification by setting its status to 'DELETED'.
Parameters :
Returns :
Promise<Notification>
A Promise that resolves to the soft-deleted notification. |
| Async deliver | ||||||||
deliver(notification: Notification)
|
||||||||
|
Defined in src/notification/notification.service.ts:116
|
||||||||
|
Delivers the given notification.
Parameters :
Returns :
Promise<any>
A Promise that resolves to the channel provider response. |
| Async findAllByUserId | |||||||||||||||
findAllByUserId(userId: string, queryOptions: literal type)
|
|||||||||||||||
|
Defined in src/notification/notification.service.ts:150
|
|||||||||||||||
|
Retrieves notifications for a specific user with pagination.
Parameters :
Returns :
Promise<Notification[]>
A Promise that resolves to an array of notifications for the specified user. |
| Async findMany | ||||||||
findMany(criteria: Prisma.NotificationWhereInput)
|
||||||||
|
Defined in src/notification/notification.service.ts:185
|
||||||||
|
Fetches multiple notifications based on provided criteria.
Parameters :
Returns :
Promise<Notification[]>
Array of notifications matching the criteria. |
| Async getNotification | ||||||||
getNotification(notificationId: number)
|
||||||||
|
Defined in src/notification/notification.service.ts:103
|
||||||||
|
Finds and returns the notification with the specified ID.
Parameters :
Returns :
Promise<Notification>
A Promise that resolves to the found notification object. |
| Async notify | ||||||||
notify(notificationId: number)
|
||||||||
|
Defined in src/notification/notification.service.ts:132
|
||||||||
|
Starts the notification delivery workflow.
Parameters :
Returns :
Promise<any>
Result of temporal workflow runAsync. |
| Async triggerNotification | ||||||||||||||||||||||||||||||
triggerNotification(eventConfig: any, projectId: number, entityId: number, eventType: EventType, entityType: NotificationEntityType, event: any, templateVars: any, userIds: string[], extraData?: any)
|
||||||||||||||||||||||||||||||
|
Defined in src/notification/notification.service.ts:231
|
||||||||||||||||||||||||||||||
|
Parameters :
Returns :
any
|
| Async update | ||||||||||||
update(id: number, updateNotificationDto: UpdateNotificationDto)
|
||||||||||||
|
Defined in src/notification/notification.service.ts:201
|
||||||||||||
|
Updates an existing notification.
Parameters :
Returns :
Promise<Notification>
A Promise that resolves to the updated notification. |
| Public channelProviderMap |
Type : object
|
Default value : {
[NotificationChannel.APP]: null,
[NotificationChannel.EMAIL]: this.emailProvider,
}
|
|
Defined in src/notification/notification.service.ts:32
|
| Private NOTIFICATION_DELIVERY_WORKFLOW |
Type : string
|
Default value : "deliverNotificationWorkflow"
|
|
Defined in src/notification/notification.service.ts:30
|
import { Injectable } from "@nestjs/common";
import { PrismaService } from "../common/prisma/prisma.service";
import { CreateNotificationDto } from "./dto/create-notification.dto";
import { Notification } from "./entities/notification.entity";
import {
NotificationChannel,
NotificationEntityType,
NotificationStatus,
} from "./types/notification.enums";
import { UpdateNotificationDto } from "./dto/update-notification.dto";
import { Prisma } from "@prisma/client";
import { EmailProvider } from "../providers/email/email.provider";
import { TemporalProvider } from "../providers/temporal/temporal.provider";
import {
getNamesFromEmail,
getTextFromTemplate,
getUuidSlug,
} from "../common/helper";
import { EventIdentifiers, EventType } from "../common/events";
import { User } from "../iam";
@Injectable()
export class NotificationService {
constructor(
private prisma: PrismaService,
private readonly temporalProvider: TemporalProvider,
private emailProvider: EmailProvider,
) {}
private NOTIFICATION_DELIVERY_WORKFLOW = "deliverNotificationWorkflow";
public channelProviderMap = {
[NotificationChannel.APP]: null,
[NotificationChannel.EMAIL]: this.emailProvider,
};
/**
* Creates a new notification.
*
* @param {CreateNotificationDto} createNotificationDto - The data transfer object containing the details of the notification to create.
* @returns {Promise<Notification>} A Promise that resolves to the created notification.
* @throws {Error} If there are issues during the notification creation process.
*/
async create(
createNotificationDto: CreateNotificationDto,
): Promise<Notification> {
const notification = await this.prisma.notification.create({
data: {
...createNotificationDto,
},
});
return new Notification(notification);
}
async createNotification(notificationParams: {
event: EventIdentifiers;
channel: NotificationChannel;
eventIdentifierConfig: any;
user: User;
eventType: EventType;
projectId: number;
templateVars: Record<string, any>;
entityId: number;
entityType: NotificationEntityType;
extraData?: Record<string, any>;
}) {
const config =
notificationParams.eventIdentifierConfig[notificationParams.event];
const template = config.channelConfig[notificationParams.channel];
const subject = getTextFromTemplate(
template.subject,
notificationParams.templateVars,
);
const body = getTextFromTemplate(
template.body,
notificationParams.templateVars,
);
const notificationData = {
projectId: notificationParams.projectId,
subject,
body,
severity: config.severity,
channel: notificationParams.channel,
userId: notificationParams.user.id,
entityId: notificationParams.entityId,
entityType: notificationParams.entityType,
eventType: notificationParams.eventType,
eventIdentifier: notificationParams.event,
extraData: notificationParams.extraData,
};
return this.create(notificationData);
}
/**
* Finds and returns the notification with the specified ID.
* @param {number} notificationId - The ID of the notification to find.
* @returns {Promise<Notification>} A Promise that resolves to the found notification object.
* @throws {Error} If there are issues finding the notification.
*/
async getNotification(notificationId: number): Promise<Notification> {
const notification = await this.prisma.notification.findFirst({
where: { id: notificationId },
});
return new Notification(notification);
}
/**
* Delivers the given notification.
* @param {Notification} notification - The notification to deliver.
* @returns {Promise<any>} A Promise that resolves to the channel provider response.
* @throws {Error} If there are issues delivering the notification.
*/
async deliver(notification: Notification): Promise<any> {
const channelProvider = this.channelProviderMap[notification.channel];
return channelProvider.deliver({
to: notification.userId,
from: notification.notifier ?? undefined,
subject: notification.subject,
body: notification.body,
});
}
/**
* Starts the notification delivery workflow.
* @param {number} notificationId - The ID of the notification to deliver.
* @returns {Promise<any>} Result of temporal workflow runAsync.
* @throws {Error} If there are issues in starting the workflow.
*/
async notify(notificationId: number): Promise<any> {
return this.temporalProvider.runAsync(
this.NOTIFICATION_DELIVERY_WORKFLOW,
[notificationId],
process.env.DEFAULT_QUEUE_NAME,
`workflow-${this.NOTIFICATION_DELIVERY_WORKFLOW}-${getUuidSlug()}`,
);
}
/**
* Retrieves notifications for a specific user with pagination.
*
* @param {string} userId - The ID of the user to retrieve notifications for.
* @param {number} page - The page number for pagination (default is 1).
* @param {number} limit - The number of notifications per page (default is 10).
* @returns {Promise<Notification[]>} A Promise that resolves to an array of notifications for the specified user.
* @throws {Error} If there are issues during the notification search process.
*/
async findAllByUserId(
userId: string,
queryOptions: {
pageSize?: number;
pageOffset?: number;
startId?: number;
} = {},
): Promise<Notification[]> {
const pageSize = +queryOptions.pageSize || 30;
const pageOffset = +queryOptions.pageOffset || 0;
const findArgs = {
where: {
userId: userId,
channel: { in: [NotificationChannel.APP, NotificationChannel.PING] },
NOT: {
OR: [{ status: { equals: NotificationStatus.DELETED } }],
},
},
take: Math.min(100, pageSize), // Limit the number of messages returned
skip: pageOffset * pageSize, // Offset based on the page number and page size
};
const notifications = await this.prisma.notification.findMany({
orderBy: {
createdAt: "desc",
},
...findArgs,
});
return notifications.map((notification) => new Notification(notification));
}
/**
* Fetches multiple notifications based on provided criteria.
* @param {Prisma.NotificationWhereInput} criteria Criteria to filter notifications.
* @returns {Promise<Notification[]>} Array of notifications matching the criteria.
*/
async findMany(
criteria: Prisma.NotificationWhereInput,
): Promise<Notification[]> {
return this.prisma.notification.findMany({
where: criteria,
});
}
/**
* Updates an existing notification.
*
* @param {number} id - The ID of the notification to update.
* @param {UpdateNotificationDto} updateNotificationDto - The data transfer object containing the updated details of the notification.
* @returns {Promise<Notification>} A Promise that resolves to the updated notification.
* @throws {Error} If there are issues during the notification update process.
*/
async update(
id: number,
updateNotificationDto: UpdateNotificationDto,
): Promise<Notification> {
const notification = await this.prisma.notification.update({
where: { id },
data: {
...updateNotificationDto,
},
});
return new Notification(notification);
}
/**
* Soft deletes a notification by setting its status to 'DELETED'.
*
* @param {number} id - The ID of the notification to delete.
* @returns {Promise<Notification>} A Promise that resolves to the soft-deleted notification.
* @throws {Error} If there are issues during the notification deletion process.
*/
async delete(id: number): Promise<Notification> {
const notification = await this.prisma.notification.update({
where: { id },
data: { status: NotificationStatus.DELETED },
});
return new Notification(notification);
}
async triggerNotification(
eventConfig: any,
projectId: number,
entityId: number,
eventType: EventType,
entityType: NotificationEntityType,
event: any,
templateVars: any,
userIds: string[],
extraData?: any,
) {
const config = eventConfig[event].channelConfig;
const severity = eventConfig[event].severity;
const notificationPromises = [];
for (const channel in config) {
userIds.forEach((userId) => {
templateVars["sendToName"] = getNamesFromEmail(userId);
templateVars["sendToEmail"] = userId;
const subject = getTextFromTemplate(
config[channel]["subject"],
templateVars,
);
const body = getTextFromTemplate(config[channel]["body"], templateVars);
const notificationData = {
projectId: projectId,
subject: subject,
body: body,
severity: severity,
channel: NotificationChannel[channel],
userId: userId,
entityId: entityId,
entityType: entityType,
eventType: eventType,
eventIdentifier: event,
extraData: extraData ?? {},
};
notificationPromises.push(this.create(notificationData));
});
}
const notifications = (await Promise.all(notificationPromises))
.flat()
.flat();
notifications.map((notification) => {
if (notification.channel != NotificationChannel.APP) {
this.notify(notification.id);
}
});
}
}