add livekit webhooks
This commit is contained in:
parent
bffe2056b1
commit
79f9e5bb24
@ -55,6 +55,7 @@
|
||||
"otpauth": "^9.4.0",
|
||||
"prisma": "^6.10.1",
|
||||
"qrcode": "^1.5.4",
|
||||
"raw-body": "^3.0.0",
|
||||
"react": "^19.1.0",
|
||||
"react-dom": "^19.1.0",
|
||||
"reflect-metadata": "^0.2.2",
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { getGraphQLConfig } from '@/src/core/config/graphql.config'
|
||||
import { getLiveKitConfig } from '@/src/core/config/livekit.config';
|
||||
import { getLiveKitConfig } from '@/src/core/config/livekit.config'
|
||||
import { AccountModule } from '@/src/module/auth/account/account.module'
|
||||
import { DeactivateModule } from '@/src/module/auth/deactivate/deactivate.module'
|
||||
import { PasswordRecoveryModule } from '@/src/module/auth/password-recovery/password-recovery.module'
|
||||
@ -11,8 +11,9 @@ import { CronModule } from '@/src/module/cron/cron.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 { IngressModule } from '@/src/module/stream/ingress/ingress.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'
|
||||
import { IS_DEV } from '@/src/shared/util/is-dev.util'
|
||||
import { ApolloDriver } from '@nestjs/apollo'
|
||||
import { Module } from '@nestjs/common'
|
||||
@ -52,6 +53,7 @@ import { RedisModule } from './redis/redis.module'
|
||||
ProfileModule,
|
||||
StreamModule,
|
||||
IngressModule,
|
||||
WebhookModule,
|
||||
],
|
||||
})
|
||||
export class CoreModule {}
|
||||
|
||||
@ -8,7 +8,7 @@ import RedisStore from 'connect-redis'
|
||||
import * as cookieParser from 'cookie-parser'
|
||||
import { CoreModule } from '@/src/core/core.module'
|
||||
import * as session from 'express-session'
|
||||
import * as graphqlUploadExpress from 'graphql-upload/graphqlUploadExpress.js';
|
||||
import * as graphqlUploadExpress from 'graphql-upload/graphqlUploadExpress.js'
|
||||
|
||||
async function bootstrap() {
|
||||
const app = await NestFactory.create(CoreModule)
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { IngressService } from './ingress.service';
|
||||
import { IngressResolver } from './ingress.resolver';
|
||||
import { Module } from '@nestjs/common'
|
||||
import { IngressService } from './ingress.service'
|
||||
import { IngressResolver } from './ingress.resolver'
|
||||
|
||||
@Module({
|
||||
providers: [IngressResolver, IngressService],
|
||||
|
||||
20
backend/src/module/webhook/webhook.controller.ts
Normal file
20
backend/src/module/webhook/webhook.controller.ts
Normal file
@ -0,0 +1,20 @@
|
||||
import { Controller, HttpCode, HttpStatus, Post, UnauthorizedException, Headers, Body } from '@nestjs/common'
|
||||
import { WebhookService } from './webhook.service'
|
||||
|
||||
@Controller('webhook')
|
||||
export class WebhookController {
|
||||
constructor(private readonly webhookService: WebhookService) {}
|
||||
|
||||
@Post('livekit')
|
||||
@HttpCode(HttpStatus.OK)
|
||||
public receiveWebhookLiveKit(
|
||||
@Body() body: string,
|
||||
@Headers('Authorization') authorization: string,
|
||||
) {
|
||||
if (!authorization) {
|
||||
throw new UnauthorizedException('Отстутсвует авторизация')
|
||||
}
|
||||
|
||||
return this.webhookService.receiveWebhookLiveKit(body, authorization)
|
||||
}
|
||||
}
|
||||
16
backend/src/module/webhook/webhook.module.ts
Normal file
16
backend/src/module/webhook/webhook.module.ts
Normal file
@ -0,0 +1,16 @@
|
||||
import { RawBodyMiddleware } from '@/src/shared/middlewares/raw-body.middleware'
|
||||
import { MiddlewareConsumer, Module, RequestMethod } from '@nestjs/common'
|
||||
import { WebhookController } from './webhook.controller'
|
||||
import { WebhookService } from './webhook.service'
|
||||
|
||||
@Module({
|
||||
controllers: [WebhookController],
|
||||
providers: [WebhookService],
|
||||
})
|
||||
export class WebhookModule {
|
||||
public configure(consumer: MiddlewareConsumer) {
|
||||
consumer
|
||||
.apply(RawBodyMiddleware)
|
||||
.forRoutes({ path: 'webhook/livekit', method: RequestMethod.POST })
|
||||
}
|
||||
}
|
||||
30
backend/src/module/webhook/webhook.service.ts
Normal file
30
backend/src/module/webhook/webhook.service.ts
Normal file
@ -0,0 +1,30 @@
|
||||
import { PrismaService } from '@/src/core/prisma/prisma.service'
|
||||
import { LiveKitService } from '@/src/module/libs/livekit/livekit.service'
|
||||
import { Injectable } from '@nestjs/common'
|
||||
|
||||
@Injectable()
|
||||
export class WebhookService {
|
||||
constructor(
|
||||
private prismaService: PrismaService,
|
||||
private liveKitService: LiveKitService,
|
||||
) {
|
||||
}
|
||||
|
||||
public async receiveWebhookLiveKit(body: string, authorization: string) {
|
||||
const event = this.liveKitService.webhook.receive(body, authorization, true)
|
||||
|
||||
if (event.event === 'ingress_started' && event.ingressInfo?.ingressId) {
|
||||
await this.prismaService.stream.update({
|
||||
where: { ingressId: event.ingressInfo.ingressId },
|
||||
data: { isLive: true },
|
||||
})
|
||||
}
|
||||
|
||||
if (event.event === 'ingress_ended' && event.ingressInfo?.ingressId) {
|
||||
await this.prismaService.stream.update({
|
||||
where: { ingressId: event.ingressInfo.ingressId },
|
||||
data: { isLive: false },
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
21
backend/src/shared/middlewares/raw-body.middleware.ts
Normal file
21
backend/src/shared/middlewares/raw-body.middleware.ts
Normal file
@ -0,0 +1,21 @@
|
||||
import { BadRequestException, Injectable, NestMiddleware } from '@nestjs/common'
|
||||
import { NextFunction, Request, Response } from 'express'
|
||||
import * as getRawBody from 'raw-body'
|
||||
|
||||
@Injectable()
|
||||
export class RawBodyMiddleware implements NestMiddleware {
|
||||
use(req: Request, res: Response, next: NextFunction) {
|
||||
if (!req.readable) {
|
||||
return next(new BadRequestException('Неправильный запрос'))
|
||||
}
|
||||
|
||||
getRawBody(req, { encoding: 'utf-8' })
|
||||
.then((rawBody) => {
|
||||
req.body = rawBody
|
||||
next()
|
||||
})
|
||||
.catch((error: string) => {
|
||||
throw new BadRequestException('Ошибка при получении', error)
|
||||
})
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user