add notifications
This commit is contained in:
parent
23caed10b6
commit
35df6780ec
@ -72,27 +72,30 @@ model SocialLink {
|
||||
}
|
||||
|
||||
model User {
|
||||
id String @id @default(uuid())
|
||||
email String @unique
|
||||
password String
|
||||
name String @unique
|
||||
displayName String @map("display_name")
|
||||
avatar String?
|
||||
bio String?
|
||||
token Token[]
|
||||
isVerified Boolean @default(false) @map("is_verified")
|
||||
isEmailVerified Boolean @default(false) @map("is_email_verified")
|
||||
isTotpEnabled Boolean @default(false) @map("is_totp_enabled")
|
||||
isDeactivated Boolean @default(false) @map("is_deactivated")
|
||||
deactivatedAt DateTime? @map("deactivated_at")
|
||||
socialLink SocialLink[]
|
||||
totpSecret String? @map("totp_secret")
|
||||
stream Stream?
|
||||
chatMessages ChatMessage[]
|
||||
followers Follow[] @relation(name: "followers")
|
||||
followings Follow[] @relation(name: "followings")
|
||||
createdAt DateTime @default(now()) @map("created_at")
|
||||
updatedAt DateTime @updatedAt @map("updated_at")
|
||||
id String @id @default(uuid())
|
||||
email String @unique
|
||||
password String
|
||||
name String @unique
|
||||
displayName String @map("display_name")
|
||||
avatar String?
|
||||
bio String?
|
||||
token Token[]
|
||||
isVerified Boolean @default(false) @map("is_verified")
|
||||
isEmailVerified Boolean @default(false) @map("is_email_verified")
|
||||
isTotpEnabled Boolean @default(false) @map("is_totp_enabled")
|
||||
isDeactivated Boolean @default(false) @map("is_deactivated")
|
||||
deactivatedAt DateTime? @map("deactivated_at")
|
||||
socialLink SocialLink[]
|
||||
totpSecret String? @map("totp_secret")
|
||||
stream Stream?
|
||||
chatMessages ChatMessage[]
|
||||
followers Follow[] @relation(name: "followers")
|
||||
followings Follow[] @relation(name: "followings")
|
||||
notifications Notification[]
|
||||
notificationSettings NotificationSettings?
|
||||
telegramId String? @default("telegram_id")
|
||||
createdAt DateTime @default(now()) @map("created_at")
|
||||
updatedAt DateTime @updatedAt @map("updated_at")
|
||||
|
||||
@@map("users")
|
||||
}
|
||||
@ -123,10 +126,46 @@ model Token {
|
||||
@@map("tokens")
|
||||
}
|
||||
|
||||
model Notification {
|
||||
id String @id @default(uuid())
|
||||
text String
|
||||
type NotificationType
|
||||
isRead Boolean @default(false) @map("is_read")
|
||||
user User? @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
userId String? @map("user_id")
|
||||
createdAt DateTime @default(now()) @map("created_at")
|
||||
updatedAt DateTime @updatedAt @map("updated_at")
|
||||
|
||||
@@map("notifications")
|
||||
}
|
||||
|
||||
model NotificationSettings {
|
||||
id String @id @default(uuid())
|
||||
siteNotifications Boolean @default(true) @map("site_notifications")
|
||||
telegramNotifications Boolean @default(true) @map("telegram_notifications")
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
userId String @unique @map("user_id")
|
||||
createdAt DateTime @default(now()) @map("created_at")
|
||||
updatedAt DateTime @updatedAt @map("updated_at")
|
||||
|
||||
@@map("notification_settings")
|
||||
}
|
||||
|
||||
enum NotificationType {
|
||||
STREAM_START
|
||||
NEW_FOLLOWER
|
||||
NEW_SPONSORSHIP
|
||||
ENABLE_TWO_FACTOR
|
||||
VERIFIED_CHANNEL
|
||||
|
||||
@@map("notification_types")
|
||||
}
|
||||
|
||||
enum TokenType {
|
||||
EMAIL_VERIFY
|
||||
PASSWORD_RESET
|
||||
DEACTIVATE_ACCOUNT
|
||||
TELEGRAM_AUTH
|
||||
|
||||
@@map("token_types")
|
||||
}
|
||||
|
||||
@ -15,6 +15,7 @@ import { FollowModule } from '@/src/module/follow/follow.module'
|
||||
import { LiveKitModule } from '@/src/module/libs/livekit/livekit.module'
|
||||
import { MailModule } from '@/src/module/libs/mail/mail.module'
|
||||
import { StorageModule } from '@/src/module/libs/storage/storage.module'
|
||||
import { NotificationModule } from '@/src/module/notification/notification.module'
|
||||
import { IngressModule } from '@/src/module/stream/ingress/ingress.module'
|
||||
import { StreamModule } from '@/src/module/stream/stream.module'
|
||||
import { WebhookModule } from '@/src/module/webhook/webhook.module'
|
||||
@ -62,6 +63,7 @@ import { RedisModule } from './redis/redis.module'
|
||||
ChatModule,
|
||||
FollowModule,
|
||||
ChannelModule,
|
||||
NotificationModule,
|
||||
],
|
||||
})
|
||||
export class CoreModule {}
|
||||
|
||||
@ -28,6 +28,16 @@ input ChangeEmailInput {
|
||||
email: String!
|
||||
}
|
||||
|
||||
input ChangeNotificationSettingsInput {
|
||||
siteNotifications: Boolean!
|
||||
telegramNotifications: Boolean!
|
||||
}
|
||||
|
||||
type ChangeNotificationsSettingsResponse {
|
||||
notificationSettings: NotificationSettingsModel!
|
||||
telegramAuthToken: String
|
||||
}
|
||||
|
||||
input ChangePasswordInput {
|
||||
newPassword: String!
|
||||
oldPassword: String!
|
||||
@ -122,6 +132,7 @@ input LoginInput {
|
||||
type Mutation {
|
||||
changeChatSettings(data: ChangeChatSettingsInput!): StreamModel!
|
||||
changeEmail(data: ChangeEmailInput!): UserModel!
|
||||
changeNotificationSettigs(data: ChangeNotificationSettingsInput!): ChangeNotificationsSettingsResponse!
|
||||
changePassword(data: ChangePasswordInput!): UserModel!
|
||||
changeProfileAvatar(avatar: Upload!): Boolean!
|
||||
changeProfileInfo(data: ChangeProfileInfoInput!): UserModel!
|
||||
@ -157,6 +168,35 @@ input NewPasswordInput {
|
||||
token: String!
|
||||
}
|
||||
|
||||
type NotificationModel {
|
||||
createdAt: DateTime!
|
||||
id: String!
|
||||
isRead: Boolean!
|
||||
text: String!
|
||||
type: NotificationType!
|
||||
updatedAt: DateTime!
|
||||
user: UserModel!
|
||||
userId: String!
|
||||
}
|
||||
|
||||
type NotificationSettingsModel {
|
||||
createdAt: DateTime!
|
||||
id: String!
|
||||
siteNotifications: Boolean!
|
||||
telegramNotifications: Boolean!
|
||||
updatedAt: DateTime!
|
||||
user: UserModel!
|
||||
userId: String!
|
||||
}
|
||||
|
||||
enum NotificationType {
|
||||
ENABLE_TWO_FACTOR
|
||||
NEW_FOLLOWER
|
||||
NEW_SPONSORSHIP
|
||||
STREAM_START
|
||||
VERIFIED_CHANNEL
|
||||
}
|
||||
|
||||
type Query {
|
||||
findAllCategories: [CategoryModel!]!
|
||||
findAllStreams(filters: FilterInput!): [StreamModel!]!
|
||||
@ -167,12 +207,14 @@ type Query {
|
||||
findMessagesByStream(streamId: String!): [ChatMessageModel!]!
|
||||
findMyFollowers: [FollowModel!]!
|
||||
findMyFollowings: [FollowModel!]!
|
||||
findNotificationByUser: [NotificationModel!]!
|
||||
findProfile: UserModel!
|
||||
findRandomCategories: [CategoryModel!]!
|
||||
findRandomStreams: [StreamModel!]!
|
||||
findRecommendedChannels: [UserModel!]!
|
||||
findSessionsByUser: [SessionModel!]!
|
||||
findSocialLinks: [SocialLinkModel!]!
|
||||
findUnreadNotificationsCount: Float!
|
||||
generateTotpSecret: TotpModel!
|
||||
}
|
||||
|
||||
@ -265,9 +307,12 @@ type UserModel {
|
||||
isTotpEnabled: Boolean!
|
||||
isVerified: Boolean!
|
||||
name: String!
|
||||
notification: [NotificationModel!]!
|
||||
notificationSettings: NotificationSettingsModel!
|
||||
password: String!
|
||||
socialLink: [SocialLinkModel!]!
|
||||
stream: StreamModel!
|
||||
telegramId: String
|
||||
totpSecret: String
|
||||
updatedAt: DateTime!
|
||||
}
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
import { SocialLinkModel } from '@/src/module/auth/profile/inputs/models/social-link.model'
|
||||
import { FollowModel } from '@/src/module/follow/model/follow.model'
|
||||
import { NotificationSettingsModel } from '@/src/module/notification/models/notification-settings.model'
|
||||
import { NotificationModel } from '@/src/module/notification/models/notification.model'
|
||||
import { StreamModel } from '@/src/module/stream/models/stream.model'
|
||||
import { Field, ID, ObjectType } from '@nestjs/graphql'
|
||||
import { User } from '@prisma/generated'
|
||||
@ -57,6 +59,15 @@ export class UserModel implements User {
|
||||
@Field(() => [FollowModel])
|
||||
followings: FollowModel[]
|
||||
|
||||
@Field(() => String, { nullable: true })
|
||||
telegramId: string
|
||||
|
||||
@Field(() => [NotificationModel])
|
||||
notification: NotificationModel[]
|
||||
|
||||
@Field(() => NotificationSettingsModel)
|
||||
notificationSettings: NotificationSettingsModel
|
||||
|
||||
@Field(() => Date)
|
||||
createdAt: Date
|
||||
|
||||
|
||||
@ -1,8 +1,9 @@
|
||||
import { NotificationService } from '@/src/module/notification/notification.service'
|
||||
import { Module } from '@nestjs/common'
|
||||
import { FollowService } from './follow.service'
|
||||
import { FollowResolver } from './follow.resolver'
|
||||
|
||||
@Module({
|
||||
providers: [FollowResolver, FollowService],
|
||||
providers: [FollowResolver, FollowService, NotificationService],
|
||||
})
|
||||
export class FollowModule {}
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import { PrismaService } from '@/src/core/prisma/prisma.service'
|
||||
import { NotificationService } from '@/src/module/notification/notification.service'
|
||||
import { ConflictException, Injectable, NotFoundException } from '@nestjs/common'
|
||||
import { User } from '@prisma/generated'
|
||||
|
||||
@ -6,6 +7,7 @@ import { User } from '@prisma/generated'
|
||||
export class FollowService {
|
||||
constructor(
|
||||
private readonly prismaService: PrismaService,
|
||||
private readonly notificationService: NotificationService,
|
||||
) {
|
||||
}
|
||||
|
||||
@ -48,16 +50,25 @@ export class FollowService {
|
||||
throw new ConflictException('Подписка уже существует')
|
||||
}
|
||||
|
||||
return this.prismaService.follow.create({
|
||||
const follow = await this.prismaService.follow.create({
|
||||
data: {
|
||||
followerId: user.id,
|
||||
followingId: channel.id,
|
||||
},
|
||||
include: {
|
||||
following: true,
|
||||
following: {
|
||||
include: {
|
||||
notificationSettings: true,
|
||||
},
|
||||
},
|
||||
follower: true,
|
||||
},
|
||||
})
|
||||
|
||||
if (follow.following.notificationSettings?.siteNotifications) {
|
||||
await this.notificationService.createNewFollowing(follow.following.id, follow.follower)
|
||||
}
|
||||
return follow
|
||||
}
|
||||
|
||||
public async unfollow(user: User, channelId: string) {
|
||||
|
||||
@ -0,0 +1,13 @@
|
||||
import { Field, InputType } from '@nestjs/graphql'
|
||||
import { IsBoolean } from 'class-validator'
|
||||
|
||||
@InputType()
|
||||
export class ChangeNotificationSettingsInput {
|
||||
@Field(() => Boolean)
|
||||
@IsBoolean()
|
||||
public siteNotifications: boolean
|
||||
|
||||
@Field(() => Boolean)
|
||||
@IsBoolean()
|
||||
public telegramNotifications: boolean
|
||||
}
|
||||
@ -0,0 +1,37 @@
|
||||
import { UserModel } from '@/src/module/auth/account/models/user.model'
|
||||
import { Field, ObjectType } from '@nestjs/graphql'
|
||||
|
||||
import type { NotificationSettings } from '@/prisma/generated'
|
||||
|
||||
@ObjectType()
|
||||
export class NotificationSettingsModel implements NotificationSettings {
|
||||
@Field(() => String)
|
||||
public id: string
|
||||
|
||||
@Field(() => Boolean)
|
||||
public siteNotifications: boolean
|
||||
|
||||
@Field(() => Boolean)
|
||||
public telegramNotifications: boolean
|
||||
|
||||
@Field(() => UserModel)
|
||||
public user: UserModel
|
||||
|
||||
@Field(() => String)
|
||||
public userId: string
|
||||
|
||||
@Field(() => Date)
|
||||
public createdAt: Date
|
||||
|
||||
@Field(() => Date)
|
||||
public updatedAt: Date
|
||||
}
|
||||
|
||||
@ObjectType()
|
||||
export class ChangeNotificationsSettingsResponse {
|
||||
@Field(() => NotificationSettingsModel)
|
||||
public notificationSettings: NotificationSettingsModel
|
||||
|
||||
@Field(() => String, { nullable: true })
|
||||
public telegramAuthToken?: string
|
||||
}
|
||||
36
backend/src/module/notification/models/notification.model.ts
Normal file
36
backend/src/module/notification/models/notification.model.ts
Normal file
@ -0,0 +1,36 @@
|
||||
import { Field, ObjectType, registerEnumType } from '@nestjs/graphql'
|
||||
|
||||
import { type Notification, NotificationType } from '@/prisma/generated'
|
||||
|
||||
import { UserModel } from '../../auth/account/models/user.model'
|
||||
|
||||
registerEnumType(NotificationType, {
|
||||
name: 'NotificationType',
|
||||
})
|
||||
|
||||
@ObjectType()
|
||||
export class NotificationModel implements Notification {
|
||||
@Field(() => String)
|
||||
public id: string
|
||||
|
||||
@Field(() => String)
|
||||
public text: string
|
||||
|
||||
@Field(() => NotificationType)
|
||||
public type: NotificationType
|
||||
|
||||
@Field(() => Boolean)
|
||||
public isRead: boolean
|
||||
|
||||
@Field(() => UserModel)
|
||||
public user: UserModel
|
||||
|
||||
@Field(() => String)
|
||||
public userId: string
|
||||
|
||||
@Field(() => Date)
|
||||
public createdAt: Date
|
||||
|
||||
@Field(() => Date)
|
||||
public updatedAt: Date
|
||||
}
|
||||
8
backend/src/module/notification/notification.module.ts
Normal file
8
backend/src/module/notification/notification.module.ts
Normal file
@ -0,0 +1,8 @@
|
||||
import { Module } from '@nestjs/common'
|
||||
import { NotificationService } from './notification.service'
|
||||
import { NotificationResolver } from './notification.resolver'
|
||||
|
||||
@Module({
|
||||
providers: [NotificationResolver, NotificationService],
|
||||
})
|
||||
export class NotificationModule {}
|
||||
34
backend/src/module/notification/notification.resolver.ts
Normal file
34
backend/src/module/notification/notification.resolver.ts
Normal file
@ -0,0 +1,34 @@
|
||||
import { ChangeNotificationSettingsInput } from '@/src/module/notification/inputs/change-notification-settings.input'
|
||||
import { ChangeNotificationsSettingsResponse } from '@/src/module/notification/models/notification-settings.model'
|
||||
import { Authorization } from '@/src/shared/decorators/auth.decorator'
|
||||
import { Authorized } from '@/src/shared/decorators/authorized.decorator'
|
||||
import { Args, Mutation, Query, Resolver } from '@nestjs/graphql'
|
||||
import { User } from '@prisma/generated'
|
||||
import { NotificationService } from './notification.service'
|
||||
import { NotificationModel } from './models/notification.model'
|
||||
|
||||
@Resolver('Notification')
|
||||
export class NotificationResolver {
|
||||
constructor(private readonly notificationService: NotificationService) {}
|
||||
|
||||
@Authorization()
|
||||
@Query(() => Number, { name: 'findUnreadNotificationsCount' })
|
||||
public findUnreadCount(@Authorized() user: User) {
|
||||
return this.notificationService.findUnreadCount(user)
|
||||
}
|
||||
|
||||
@Authorization()
|
||||
@Query(() => [NotificationModel], { name: 'findNotificationByUser' })
|
||||
public findByUser(@Authorized() user: User) {
|
||||
return this.notificationService.findByUser(user)
|
||||
}
|
||||
|
||||
@Authorization()
|
||||
@Mutation(() => ChangeNotificationsSettingsResponse, { name: 'changeNotificationSettigs' })
|
||||
public async changeSettings(
|
||||
@Authorized() user: User,
|
||||
@Args('data') input: ChangeNotificationSettingsInput,
|
||||
) {
|
||||
return this.notificationService.changeSettings(user, input)
|
||||
}
|
||||
}
|
||||
131
backend/src/module/notification/notification.service.ts
Normal file
131
backend/src/module/notification/notification.service.ts
Normal file
@ -0,0 +1,131 @@
|
||||
import { PrismaService } from '@/src/core/prisma/prisma.service'
|
||||
import { ChangeNotificationSettingsInput } from '@/src/module/notification/inputs/change-notification-settings.input'
|
||||
import { generateToken } from '@/src/shared/util/generate-token.util'
|
||||
import { Injectable } from '@nestjs/common'
|
||||
import { $Enums, User } from '@prisma/generated'
|
||||
import TokenType = $Enums.TokenType
|
||||
import NotificationType = $Enums.NotificationType
|
||||
|
||||
@Injectable()
|
||||
export class NotificationService {
|
||||
constructor(
|
||||
private readonly prismaService: PrismaService,
|
||||
) {
|
||||
}
|
||||
|
||||
public async findUnreadCount(user: User) {
|
||||
return this.prismaService.notification.count({
|
||||
where: {
|
||||
isRead: false,
|
||||
userId: user.id,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
public async findByUser(user: User) {
|
||||
await this.prismaService.notification.updateMany({
|
||||
where: {
|
||||
isRead: false,
|
||||
userId: user.id,
|
||||
},
|
||||
data: { isRead: true },
|
||||
})
|
||||
|
||||
return this.prismaService.notification.findMany({
|
||||
where: { userId: user.id },
|
||||
orderBy: { createdAt: 'desc' },
|
||||
})
|
||||
}
|
||||
|
||||
public async changeSettings(user: User, input: ChangeNotificationSettingsInput) {
|
||||
const { siteNotifications, telegramNotifications } = input
|
||||
|
||||
const notificationSetting = await this.prismaService.notificationSettings.upsert({
|
||||
where: { userId: user.id },
|
||||
create: {
|
||||
siteNotifications,
|
||||
telegramNotifications,
|
||||
userId: user.id,
|
||||
},
|
||||
update: { siteNotifications, telegramNotifications },
|
||||
include: { user: true },
|
||||
})
|
||||
|
||||
if (notificationSetting.telegramNotifications && !notificationSetting.user.telegramId) {
|
||||
const telegramAuthToken = await generateToken(
|
||||
this.prismaService,
|
||||
user,
|
||||
TokenType.TELEGRAM_AUTH,
|
||||
)
|
||||
|
||||
return {
|
||||
notificationSetting,
|
||||
token: telegramAuthToken.token,
|
||||
}
|
||||
}
|
||||
|
||||
if (!notificationSetting.telegramNotifications && notificationSetting.user.telegramId) {
|
||||
await this.prismaService.user.update({
|
||||
where: { id: user.id },
|
||||
data: { telegramId: null },
|
||||
})
|
||||
|
||||
return { notificationSetting }
|
||||
}
|
||||
|
||||
return { notificationSetting }
|
||||
}
|
||||
|
||||
public async createStreamStart(userId: string, channel: User) {
|
||||
return this.prismaService.notification.create({
|
||||
data: {
|
||||
text: `<b className='font-medium'>Не пропустите!</b>
|
||||
<p>Присоединяйтесь к стриму на канале <a href='/${channel.name}' className='font-semibold'>${channel.displayName}</a>.</p>`,
|
||||
type: NotificationType.STREAM_START,
|
||||
user: {
|
||||
connect: {
|
||||
id: userId,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
public async createNewFollowing(userId: string, follower: User) {
|
||||
return this.prismaService.notification.create({
|
||||
data: {
|
||||
text: `<b className='font-medium'>У вас новый подписчик!</b>
|
||||
<p>Это пользователь <a href='/${follower.name}' className='font-semibold'>${follower.displayName}</a>.</p>`,
|
||||
type: NotificationType.NEW_FOLLOWER,
|
||||
user: {
|
||||
connect: {
|
||||
id: userId,
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
public async createEnableTwoFactor(userId: string) {
|
||||
return this.prismaService.notification.create({
|
||||
data: {
|
||||
text: `<b className='font-medium'>Обеспечьте свою безопасность!</b>
|
||||
<p>Включите двухфакторную аутентификацию в настройках вашего аккаунта, чтобы повысить уровень защиты.</p>`,
|
||||
type: NotificationType.ENABLE_TWO_FACTOR,
|
||||
userId,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
public async createVerifyChannel(userId: string) {
|
||||
return this.prismaService.notification.create({
|
||||
data: {
|
||||
text: `<b className='font-medium'>Поздравляем!</b>
|
||||
<p>Ваш канал верифицирован, и теперь рядом с вашим каналом будет галочка.</p>`,
|
||||
type: NotificationType.VERIFIED_CHANNEL,
|
||||
userId,
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -1,3 +1,4 @@
|
||||
import { NotificationService } from '@/src/module/notification/notification.service';
|
||||
import { RawBodyMiddleware } from '@/src/shared/middlewares/raw-body.middleware'
|
||||
import { MiddlewareConsumer, Module, RequestMethod } from '@nestjs/common'
|
||||
import { WebhookController } from './webhook.controller'
|
||||
@ -5,7 +6,7 @@ import { WebhookService } from './webhook.service'
|
||||
|
||||
@Module({
|
||||
controllers: [WebhookController],
|
||||
providers: [WebhookService],
|
||||
providers: [WebhookService, NotificationService],
|
||||
})
|
||||
export class WebhookModule {
|
||||
public configure(consumer: MiddlewareConsumer) {
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import { PrismaService } from '@/src/core/prisma/prisma.service'
|
||||
import { LiveKitService } from '@/src/module/libs/livekit/livekit.service'
|
||||
import { NotificationService } from '@/src/module/notification/notification.service'
|
||||
import { Injectable } from '@nestjs/common'
|
||||
|
||||
@Injectable()
|
||||
@ -7,6 +8,7 @@ export class WebhookService {
|
||||
constructor(
|
||||
private prismaService: PrismaService,
|
||||
private liveKitService: LiveKitService,
|
||||
private readonly notificationService: NotificationService,
|
||||
) {
|
||||
}
|
||||
|
||||
@ -14,17 +16,43 @@ export class WebhookService {
|
||||
const event = this.liveKitService.webhook.receive(body, authorization, true)
|
||||
|
||||
if (event.event === 'ingress_started' && event.ingressInfo?.ingressId) {
|
||||
await this.prismaService.stream.update({
|
||||
const stream = await this.prismaService.stream.update({
|
||||
where: { ingressId: event.ingressInfo.ingressId },
|
||||
data: { isLive: true },
|
||||
include: { user: true },
|
||||
})
|
||||
|
||||
const followers = await this.prismaService.follow.findMany({
|
||||
where: {
|
||||
followingId: stream.user!.id,
|
||||
follower: { isDeactivated: false },
|
||||
},
|
||||
include: {
|
||||
follower: {
|
||||
include: {
|
||||
notificationSettings: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
for (const follow of followers) {
|
||||
const follower = follow.follower
|
||||
if (follower.notificationSettings?.siteNotifications) {
|
||||
await this.notificationService.createStreamStart(follower.id, stream.user!)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (event.event === 'ingress_ended' && event.ingressInfo?.ingressId) {
|
||||
await this.prismaService.stream.update({
|
||||
const stream = await this.prismaService.stream.update({
|
||||
where: { ingressId: event.ingressInfo.ingressId },
|
||||
data: { isLive: false },
|
||||
})
|
||||
|
||||
await this.prismaService.chatMessage.deleteMany({
|
||||
where: { streamId: stream.id },
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user