154 lines
4.7 KiB
TypeScript
154 lines
4.7 KiB
TypeScript
import { Injectable, Logger } from '@nestjs/common';
|
|
import { InjectQueue } from '@nestjs/bullmq';
|
|
import { Queue } from 'bullmq';
|
|
import { NotificationQueueNameEnum } from '../constants/queue';
|
|
import {
|
|
InAppNotificationQueueJob,
|
|
PushNotificationQueueJob,
|
|
SmsNotificationQueueJob,
|
|
} from '../interfaces/jobs-queue.interface';
|
|
|
|
@Injectable()
|
|
export class NotificationQueueService {
|
|
private readonly logger = new Logger(NotificationQueueService.name);
|
|
|
|
constructor(
|
|
@InjectQueue(NotificationQueueNameEnum.SMS) private readonly smsQueue: Queue,
|
|
@InjectQueue(NotificationQueueNameEnum.PUSH) private readonly pushQueue: Queue,
|
|
@InjectQueue(NotificationQueueNameEnum.IN_APP) private readonly inAppQueue: Queue,
|
|
) {}
|
|
|
|
async addSmsNotification(job: SmsNotificationQueueJob): Promise<void> {
|
|
try {
|
|
const jobId = `${job.templateId}-${this.generateRandomInt()}-${Date.now()}`;
|
|
|
|
await this.smsQueue.add('sms-notification', job, {
|
|
jobId,
|
|
attempts: 3,
|
|
backoff: {
|
|
type: 'exponential',
|
|
delay: 2000,
|
|
},
|
|
removeOnComplete: {
|
|
age: 24 * 3600, // Keep completed jobs for 24 hours
|
|
count: 1000,
|
|
},
|
|
removeOnFail: {
|
|
age: 7 * 24 * 3600, // Keep failed jobs for 7 days
|
|
},
|
|
});
|
|
|
|
this.logger.log(`SMS notification job added to queue: ${jobId}`);
|
|
} catch (error) {
|
|
this.logger.error(`Failed to add SMS notification to queue:`, error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
async addPushNotification(job: PushNotificationQueueJob): Promise<void> {
|
|
try {
|
|
const jobId = `${job.title}-${this.generateRandomInt()}-${Date.now()}`;
|
|
|
|
await this.pushQueue.add('push-notification', job, {
|
|
jobId,
|
|
attempts: 3,
|
|
backoff: {
|
|
type: 'exponential',
|
|
delay: 2000,
|
|
},
|
|
removeOnComplete: {
|
|
age: 24 * 3600, // Keep completed jobs for 24 hours
|
|
count: 1000,
|
|
},
|
|
removeOnFail: {
|
|
age: 7 * 24 * 3600, // Keep failed jobs for 7 days
|
|
},
|
|
});
|
|
|
|
this.logger.log(`Push notification job added to queue: ${jobId}`);
|
|
} catch (error) {
|
|
this.logger.error(`Failed to add push notification to queue:`, error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
async addBulkSmsNotifications(jobs: SmsNotificationQueueJob[]): Promise<void> {
|
|
try {
|
|
const queueJobs = jobs.map(job => ({
|
|
name: 'sms-notification',
|
|
data: job,
|
|
opts: {
|
|
jobId: `${job.templateId}-${this.generateRandomInt()}`,
|
|
attempts: 3,
|
|
backoff: {
|
|
type: 'exponential',
|
|
delay: 2000,
|
|
},
|
|
},
|
|
}));
|
|
|
|
await this.smsQueue.addBulk(queueJobs);
|
|
this.logger.log(`Added ${jobs.length} SMS notification jobs to queue`);
|
|
} catch (error) {
|
|
this.logger.error(`Failed to add bulk notifications to queue:`, error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
async addBulkPushNotifications(jobs: PushNotificationQueueJob[]): Promise<void> {
|
|
try {
|
|
const queueJobs = jobs.map(job => ({
|
|
name: 'push-notification',
|
|
data: job,
|
|
opts: {
|
|
jobId: `${job.title}-${this.generateRandomInt()}-${Date.now()}`,
|
|
attempts: 3,
|
|
backoff: {
|
|
type: 'exponential',
|
|
delay: 2000,
|
|
},
|
|
},
|
|
}));
|
|
|
|
await this.pushQueue.addBulk(queueJobs);
|
|
this.logger.log(`Added ${jobs.length} Push notification jobs to queue`);
|
|
} catch (error) {
|
|
this.logger.error(`Failed to add bulk notifications to queue:`, error);
|
|
throw error;
|
|
}
|
|
}
|
|
async addBulkInAppNotifications(jobs: InAppNotificationQueueJob[]): Promise<void> {
|
|
try {
|
|
this.logger.log(
|
|
`[addBulkInAppNotifications] queueing ${jobs.length} job(s): ${jobs
|
|
.map(j => `admin=${j.recipient.adminId} rest=${j.recipient.restaurantId} notif=${j.notificationId}`)
|
|
.join(' | ')}`,
|
|
);
|
|
|
|
const queueJobs = jobs.map(job => ({
|
|
name: 'in-app-notification',
|
|
data: job,
|
|
opts: {
|
|
jobId: `${job.subject}-${job.notificationId}-${Date.now()}`,
|
|
attempts: 3,
|
|
backoff: {
|
|
type: 'exponential',
|
|
delay: 2000,
|
|
},
|
|
},
|
|
}));
|
|
|
|
const added = await this.inAppQueue.addBulk(queueJobs);
|
|
this.logger.log(
|
|
`[addBulkInAppNotifications] added ${added.length} job(s) to queue "${NotificationQueueNameEnum.IN_APP}": ids=${added.map(j => j.id).join(', ')}`,
|
|
);
|
|
} catch (error) {
|
|
this.logger.error(`[addBulkInAppNotifications] failed to add jobs to queue:`, error);
|
|
throw error;
|
|
}
|
|
}
|
|
private generateRandomInt(): string {
|
|
return Math.random().toString(36).substring(2, 15);
|
|
}
|
|
}
|