Files
IdP/apps/sso-core/src/infra/notification-publisher.service.ts
2026-06-24 14:45:45 +03:00

77 lines
2.4 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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}`);
}
}
}