From fe88c685e03b12607ac5ff3a3262ac2a2b992b2f Mon Sep 17 00:00:00 2001 From: n08i40k Date: Fri, 1 Nov 2024 02:00:33 +0400 Subject: [PATCH] =?UTF-8?q?=D0=92=D0=BE=D0=B7=D0=BC=D0=BE=D0=B6=D0=BD?= =?UTF-8?q?=D1=8B=D0=B9=20=D1=84=D0=B8=D0=BA=D1=81=20=D0=BD=D0=B5=D0=B2?= =?UTF-8?q?=D0=BE=D0=B7=D0=BC=D0=BE=D0=B6=D0=BD=D0=BE=D1=81=D1=82=D0=B8=20?= =?UTF-8?q?=D0=BE=D1=82=D0=BF=D1=80=D0=B0=D0=B2=D0=B8=D1=82=D1=8C=20=D1=83?= =?UTF-8?q?=D0=B2=D0=B5=D0=B4=D0=BE=D0=BC=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Добавлена возможность отправки сообщений вручную. --- package.json | 5 +- .../firebase-admin.controller.ts | 16 +++++++ src/firebase-admin/firebase-admin.service.ts | 48 ++++++++++++++----- .../schedule-parser/v2-schedule-parser.ts | 5 -- 4 files changed, 54 insertions(+), 20 deletions(-) diff --git a/package.json b/package.json index 9365734..541263a 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "license": "UNLICENSED", "scripts": { "build": "nest build", - "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"", + "format": "prettier --write \"src/**/*.ts\"", "start": "nest start", "start:dev": "nest start --watch", "start:debug": "nest start --debug --watch", @@ -17,7 +17,8 @@ "test:watch": "jest --watch", "test:cov": "jest --coverage", "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand", - "test:e2e": "jest --config ./test/jest-e2e.json" + "test:e2e": "jest --config ./test/jest-e2e.json", + "precommit": "npm run format && npm run lint" }, "dependencies": { "@nestjs/cache-manager": "^2.2.2", diff --git a/src/firebase-admin/firebase-admin.controller.ts b/src/firebase-admin/firebase-admin.controller.ts index 4d73329..5837f9e 100644 --- a/src/firebase-admin/firebase-admin.controller.ts +++ b/src/firebase-admin/firebase-admin.controller.ts @@ -23,6 +23,12 @@ import { ApiResponse, ApiTags, } from "@nestjs/swagger"; +import { AuthRoles } from "../auth/auth-role.decorator"; +import { UserRole } from "../users/user-role.enum"; +import { + TokenMessage, + TopicMessage, +} from "firebase-admin/lib/messaging/messaging-api"; @ApiTags("v1/fcm") @ApiBearerAuth() @@ -33,6 +39,16 @@ export class FirebaseAdminController { constructor(private readonly firebaseAdminService: FirebaseAdminService) {} + @ApiOperation({ summary: "Отправка уведомления" }) + @ApiResponse({ status: HttpStatus.OK }) + @Post("post") + @HttpCode(HttpStatus.OK) + @ResultDto(null) + @AuthRoles([UserRole.ADMIN]) + async post(@Body() message: TopicMessage | TokenMessage) { + await this.firebaseAdminService.send(message); + } + @ApiOperation({ summary: "Установка FCM токена пользователем" }) @ApiResponse({ status: HttpStatus.OK, diff --git a/src/firebase-admin/firebase-admin.service.ts b/src/firebase-admin/firebase-admin.service.ts index 387d390..f7f0acf 100644 --- a/src/firebase-admin/firebase-admin.service.ts +++ b/src/firebase-admin/firebase-admin.service.ts @@ -13,6 +13,9 @@ import { firebaseConstants } from "../contants"; import { UsersService } from "../users/users.service"; import { User } from "../users/entity/user.entity"; +import { TokenMessage } from "firebase-admin/lib/messaging/messaging-api"; +import { FcmUser } from "../users/entity/fcm-user.entity"; +import { plainToInstance } from "class-transformer"; @Injectable() export class FirebaseAdminService implements OnModuleInit { @@ -37,7 +40,22 @@ export class FirebaseAdminService implements OnModuleInit { const topicMessage = message as TopicMessage; topicMessage.topic = topic; - await this.messaging.send(topicMessage); + await this.send(topicMessage); + } + + async send(message: TopicMessage | TokenMessage): Promise { + await this.messaging.send(message); + } + + private getFcmOrDefault(user: User, token: string): FcmUser { + if (!user.fcm) { + return plainToInstance(FcmUser, { + token: token, + topics: [], + } as FcmUser); + } + + return user.fcm; } async updateToken( @@ -45,8 +63,8 @@ export class FirebaseAdminService implements OnModuleInit { token: string, ): Promise<{ userDto: User; isNew: boolean }> { const isNew = user.fcm === null; + const fcm = this.getFcmOrDefault(user, token); - const fcm = !isNew ? user.fcm : { token: token, topics: [] }; if (!isNew) { if (fcm.token === token) return { userDto: user, isNew: false }; @@ -65,18 +83,20 @@ export class FirebaseAdminService implements OnModuleInit { } async unsubscribe(user: User, topics: Set): Promise { + if (!user.fcm) throw new Error("User does not have fcm data!"); + const fcm = user.fcm; - const currentTopics = new Set(fcm.topics); + const newTopics = new Set(); for (const topic of topics) { if (!fcm.topics.includes(topic)) continue; await this.messaging.unsubscribeFromTopic(fcm.token, topic); - currentTopics.delete(topic); + newTopics.add(topic); } - if (currentTopics.size === fcm.topics.length) return user; + if (newTopics.size === fcm.topics.length) return user; - fcm.topics = Array.from(currentTopics); + fcm.topics = Array.from(newTopics); return await this.usersService.update({ where: { id: user.id }, @@ -89,20 +109,22 @@ export class FirebaseAdminService implements OnModuleInit { topics: Set, force: boolean = false, ): Promise { - const newTopics = new Set([...this.defaultTopics, ...topics]); + const additionalTopics = new Set([...this.defaultTopics, ...topics]); const fcm = user.fcm; - const currentTopics = new Set(fcm.topics); + const newTopics = new Set(fcm.topics); - for (const topic of newTopics) { - if (fcm.topics.includes(topic) && !force) continue; + for (const topic of additionalTopics) { + if (force) + await this.messaging.unsubscribeFromTopic(fcm.token, topic); + else if (fcm.topics.includes(topic)) continue; + else newTopics.add(topic); await this.messaging.subscribeToTopic(fcm.token, topic); - currentTopics.add(topic); } - if (currentTopics.size === fcm.topics.length) return user; + if (newTopics.size === fcm.topics.length) return user; - fcm.topics = Array.from(currentTopics); + fcm.topics = Array.from(newTopics); return await this.usersService.update({ where: { id: user.id }, diff --git a/src/schedule/internal/schedule-parser/v2-schedule-parser.ts b/src/schedule/internal/schedule-parser/v2-schedule-parser.ts index dc97789..8aa1221 100644 --- a/src/schedule/internal/schedule-parser/v2-schedule-parser.ts +++ b/src/schedule/internal/schedule-parser/v2-schedule-parser.ts @@ -514,11 +514,6 @@ export class V2ScheduleParser { ): Array { const row = time.xlsxRange.s.r; - if (typeof column !== "number") { - console.log(typeof column); - console.log(column); - } - // name const rawName = trimAll( V2ScheduleParser.getCellData(workSheet, row, column)?.replaceAll(