77 lines
2.4 KiB
TypeScript
77 lines
2.4 KiB
TypeScript
import { Injectable, Logger, OnModuleDestroy, OnModuleInit } from '@nestjs/common';
|
||
import { ConfigService } from '@nestjs/config';
|
||
import amqp from 'amqplib';
|
||
|
||
export interface RealtimeNotificationPayload {
|
||
userId: string;
|
||
type: string;
|
||
title: string;
|
||
message: string;
|
||
payload?: Record<string, unknown>;
|
||
}
|
||
|
||
@Injectable()
|
||
export class NotificationPublisherService implements OnModuleInit, OnModuleDestroy {
|
||
private readonly logger = new Logger(NotificationPublisherService.name);
|
||
private connection: { createChannel: () => Promise<amqp.Channel>; close: () => Promise<void> } | null = null;
|
||
private channel: amqp.ConfirmChannel | amqp.Channel | null = null;
|
||
private readonly queueName = 'id.notifications';
|
||
|
||
constructor(private readonly config: ConfigService) {}
|
||
|
||
async onModuleInit() {
|
||
await this.connect();
|
||
}
|
||
|
||
async onModuleDestroy() {
|
||
try {
|
||
await this.channel?.close();
|
||
} catch {
|
||
// ignore shutdown errors
|
||
}
|
||
try {
|
||
await this.connection?.close();
|
||
} catch {
|
||
// ignore shutdown errors
|
||
}
|
||
}
|
||
|
||
private async connect() {
|
||
const url = this.config.get<string>('RABBITMQ_URL', 'amqp://lendry:lendry_password@localhost:5672/');
|
||
try {
|
||
this.connection = (await amqp.connect(url)) as {
|
||
createChannel: () => Promise<amqp.Channel>;
|
||
close: () => Promise<void>;
|
||
};
|
||
this.channel = await this.connection.createChannel();
|
||
await this.channel.assertQueue(this.queueName, { durable: true });
|
||
this.logger.log('Подключение к RabbitMQ для уведомлений установлено');
|
||
} catch (error) {
|
||
this.logger.warn(`RabbitMQ недоступен, push-уведомления будут только в БД: ${error instanceof Error ? error.message : error}`);
|
||
}
|
||
}
|
||
|
||
async publish(notification: RealtimeNotificationPayload) {
|
||
if (!this.channel) {
|
||
await this.connect();
|
||
}
|
||
if (!this.channel) return;
|
||
|
||
const body = Buffer.from(
|
||
JSON.stringify({
|
||
userId: notification.userId,
|
||
type: notification.type,
|
||
title: notification.title,
|
||
message: notification.message,
|
||
payload: notification.payload ?? {}
|
||
})
|
||
);
|
||
|
||
try {
|
||
this.channel.sendToQueue(this.queueName, body, { persistent: true });
|
||
} catch (error) {
|
||
this.logger.warn(`Не удалось отправить уведомление в RabbitMQ: ${error instanceof Error ? error.message : error}`);
|
||
}
|
||
}
|
||
}
|