full project: admin panel, backend modules, docs
This commit is contained in:
@@ -0,0 +1,30 @@
|
||||
import { Controller, Post, Body } from '@nestjs/common';
|
||||
import { ApiTags } from '@nestjs/swagger';
|
||||
import { IsString, IsOptional, IsObject } from 'class-validator';
|
||||
import { NotificationsService } from './notifications.service';
|
||||
|
||||
class SendNotificationDto {
|
||||
@IsString()
|
||||
to: string;
|
||||
|
||||
@IsString()
|
||||
title: string;
|
||||
|
||||
@IsString()
|
||||
body: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsObject()
|
||||
data?: Record<string, any>;
|
||||
}
|
||||
|
||||
@ApiTags('Notifications')
|
||||
@Controller('notifications')
|
||||
export class NotificationsController {
|
||||
constructor(private notifications: NotificationsService) {}
|
||||
|
||||
@Post('send')
|
||||
send(@Body() dto: SendNotificationDto) {
|
||||
return this.notifications.send(dto.to, dto.title, dto.body, dto.data);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { NotificationsService } from './notifications.service';
|
||||
import { NotificationsController } from './notifications.controller';
|
||||
|
||||
@Module({
|
||||
providers: [NotificationsService],
|
||||
controllers: [NotificationsController],
|
||||
exports: [NotificationsService],
|
||||
})
|
||||
export class NotificationsModule {}
|
||||
@@ -0,0 +1,40 @@
|
||||
import { Injectable, Logger } from '@nestjs/common';
|
||||
import { ConfigService } from '@nestjs/config';
|
||||
|
||||
@Injectable()
|
||||
export class NotificationsService {
|
||||
private readonly logger = new Logger(NotificationsService.name);
|
||||
private readonly fcmServerKey: string;
|
||||
|
||||
constructor(private config: ConfigService) {
|
||||
this.fcmServerKey = this.config.getOrThrow<string>('FCM_SERVER_KEY');
|
||||
}
|
||||
|
||||
async send(to: string, title: string, body: string, data?: Record<string, any>) {
|
||||
const message = {
|
||||
notification: { title, body },
|
||||
priority: 'high' as const,
|
||||
data: data ?? { click_action: 'FLUTTER_NOTIFICATION_CLICK', id: '1', status: 'done' },
|
||||
to,
|
||||
};
|
||||
|
||||
const response = await fetch('https://fcm.googleapis.com/fcm/send', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json; charset=UTF-8',
|
||||
Authorization: `key=${this.fcmServerKey}`,
|
||||
},
|
||||
body: JSON.stringify(message),
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const text = await response.text();
|
||||
this.logger.error(`FCM error ${response.status}: ${text}`);
|
||||
throw new Error(`FCM request failed: ${response.status}`);
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
this.logger.log(`FCM success: ${JSON.stringify(result)}`);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user