mirror of
https://github.com/n08i40k/schedule-parser-next.git
synced 2025-12-06 09:47:46 +03:00
Возможный фикс невозможности отправить уведомление.
Добавлена возможность отправки сообщений вручную.
This commit is contained in:
@@ -7,7 +7,7 @@
|
|||||||
"license": "UNLICENSED",
|
"license": "UNLICENSED",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "nest build",
|
"build": "nest build",
|
||||||
"format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
|
"format": "prettier --write \"src/**/*.ts\"",
|
||||||
"start": "nest start",
|
"start": "nest start",
|
||||||
"start:dev": "nest start --watch",
|
"start:dev": "nest start --watch",
|
||||||
"start:debug": "nest start --debug --watch",
|
"start:debug": "nest start --debug --watch",
|
||||||
@@ -17,7 +17,8 @@
|
|||||||
"test:watch": "jest --watch",
|
"test:watch": "jest --watch",
|
||||||
"test:cov": "jest --coverage",
|
"test:cov": "jest --coverage",
|
||||||
"test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
|
"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": {
|
"dependencies": {
|
||||||
"@nestjs/cache-manager": "^2.2.2",
|
"@nestjs/cache-manager": "^2.2.2",
|
||||||
|
|||||||
@@ -23,6 +23,12 @@ import {
|
|||||||
ApiResponse,
|
ApiResponse,
|
||||||
ApiTags,
|
ApiTags,
|
||||||
} from "@nestjs/swagger";
|
} 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")
|
@ApiTags("v1/fcm")
|
||||||
@ApiBearerAuth()
|
@ApiBearerAuth()
|
||||||
@@ -33,6 +39,16 @@ export class FirebaseAdminController {
|
|||||||
|
|
||||||
constructor(private readonly firebaseAdminService: FirebaseAdminService) {}
|
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 токена пользователем" })
|
@ApiOperation({ summary: "Установка FCM токена пользователем" })
|
||||||
@ApiResponse({
|
@ApiResponse({
|
||||||
status: HttpStatus.OK,
|
status: HttpStatus.OK,
|
||||||
|
|||||||
@@ -13,6 +13,9 @@ import { firebaseConstants } from "../contants";
|
|||||||
import { UsersService } from "../users/users.service";
|
import { UsersService } from "../users/users.service";
|
||||||
|
|
||||||
import { User } from "../users/entity/user.entity";
|
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()
|
@Injectable()
|
||||||
export class FirebaseAdminService implements OnModuleInit {
|
export class FirebaseAdminService implements OnModuleInit {
|
||||||
@@ -37,7 +40,22 @@ export class FirebaseAdminService implements OnModuleInit {
|
|||||||
const topicMessage = message as TopicMessage;
|
const topicMessage = message as TopicMessage;
|
||||||
topicMessage.topic = topic;
|
topicMessage.topic = topic;
|
||||||
|
|
||||||
await this.messaging.send(topicMessage);
|
await this.send(topicMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
async send(message: TopicMessage | TokenMessage): Promise<void> {
|
||||||
|
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(
|
async updateToken(
|
||||||
@@ -45,8 +63,8 @@ export class FirebaseAdminService implements OnModuleInit {
|
|||||||
token: string,
|
token: string,
|
||||||
): Promise<{ userDto: User; isNew: boolean }> {
|
): Promise<{ userDto: User; isNew: boolean }> {
|
||||||
const isNew = user.fcm === null;
|
const isNew = user.fcm === null;
|
||||||
|
const fcm = this.getFcmOrDefault(user, token);
|
||||||
|
|
||||||
const fcm = !isNew ? user.fcm : { token: token, topics: [] };
|
|
||||||
if (!isNew) {
|
if (!isNew) {
|
||||||
if (fcm.token === token) return { userDto: user, isNew: false };
|
if (fcm.token === token) return { userDto: user, isNew: false };
|
||||||
|
|
||||||
@@ -65,18 +83,20 @@ export class FirebaseAdminService implements OnModuleInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async unsubscribe(user: User, topics: Set<string>): Promise<User> {
|
async unsubscribe(user: User, topics: Set<string>): Promise<User> {
|
||||||
|
if (!user.fcm) throw new Error("User does not have fcm data!");
|
||||||
|
|
||||||
const fcm = user.fcm;
|
const fcm = user.fcm;
|
||||||
const currentTopics = new Set(fcm.topics);
|
const newTopics = new Set<string>();
|
||||||
|
|
||||||
for (const topic of topics) {
|
for (const topic of topics) {
|
||||||
if (!fcm.topics.includes(topic)) continue;
|
if (!fcm.topics.includes(topic)) continue;
|
||||||
|
|
||||||
await this.messaging.unsubscribeFromTopic(fcm.token, topic);
|
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({
|
return await this.usersService.update({
|
||||||
where: { id: user.id },
|
where: { id: user.id },
|
||||||
@@ -89,20 +109,22 @@ export class FirebaseAdminService implements OnModuleInit {
|
|||||||
topics: Set<string>,
|
topics: Set<string>,
|
||||||
force: boolean = false,
|
force: boolean = false,
|
||||||
): Promise<User> {
|
): Promise<User> {
|
||||||
const newTopics = new Set([...this.defaultTopics, ...topics]);
|
const additionalTopics = new Set([...this.defaultTopics, ...topics]);
|
||||||
|
|
||||||
const fcm = user.fcm;
|
const fcm = user.fcm;
|
||||||
const currentTopics = new Set(fcm.topics);
|
const newTopics = new Set(fcm.topics);
|
||||||
|
|
||||||
for (const topic of newTopics) {
|
for (const topic of additionalTopics) {
|
||||||
if (fcm.topics.includes(topic) && !force) continue;
|
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);
|
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({
|
return await this.usersService.update({
|
||||||
where: { id: user.id },
|
where: { id: user.id },
|
||||||
|
|||||||
@@ -514,11 +514,6 @@ export class V2ScheduleParser {
|
|||||||
): Array<V2LessonDto> {
|
): Array<V2LessonDto> {
|
||||||
const row = time.xlsxRange.s.r;
|
const row = time.xlsxRange.s.r;
|
||||||
|
|
||||||
if (typeof column !== "number") {
|
|
||||||
console.log(typeof column);
|
|
||||||
console.log(column);
|
|
||||||
}
|
|
||||||
|
|
||||||
// name
|
// name
|
||||||
const rawName = trimAll(
|
const rawName = trimAll(
|
||||||
V2ScheduleParser.getCellData(workSheet, row, column)?.replaceAll(
|
V2ScheduleParser.getCellData(workSheet, row, column)?.replaceAll(
|
||||||
|
|||||||
Reference in New Issue
Block a user