KI-AGENT: LiveKit-Calls nativ in FEDEO integrieren

This commit is contained in:
2026-05-18 19:15:36 +02:00
parent c93ea4284d
commit 248da3412c
7 changed files with 480 additions and 54 deletions

View File

@@ -5,6 +5,7 @@ import { FastifyInstance } from "fastify"
import { authProfiles, authTenantUsers, authUsers, communicationRooms, tenants } from "../../db/schema"
import { and, eq } from "drizzle-orm"
import { secrets } from "../utils/secrets"
import jwt from "jsonwebtoken"
type MatrixErrorResponse = {
errcode?: string
@@ -40,6 +41,13 @@ type MatrixLoginTokenResponse = {
expires_in_ms: number
}
type LiveKitGrant = {
roomJoin: boolean
room: string
canPublish: boolean
canSubscribe: boolean
}
type MatrixTenantRoomOptions = {
key?: string
name?: string
@@ -153,6 +161,16 @@ export function matrixService(server: FastifyInstance) {
? `wss://${rtcHost()}/livekit/sfu`
: `ws://localhost:${process.env.MATRIX_DEV_LIVEKIT_PORT || "7880"}`)
const livekitKey = () =>
process.env.LIVEKIT_KEY ||
secrets.LIVEKIT_KEY ||
(process.env.NODE_ENV === "production" ? "" : "devkey")
const livekitSecret = () =>
process.env.LIVEKIT_SECRET ||
secrets.LIVEKIT_SECRET ||
(process.env.NODE_ENV === "production" ? "" : "devsecret-local-matrix-stack-32-chars")
const serviceUserLocalpart = () =>
process.env.MATRIX_SERVICE_USER_LOCALPART ||
secrets.MATRIX_SERVICE_USER_LOCALPART ||
@@ -1185,6 +1203,62 @@ export function matrixService(server: FastifyInstance) {
}
}
const createLiveKitRoomSession = async (
userId: string,
tenantId: number | null,
options: MatrixTenantRoomOptions = {}
) => {
if (!livekitKey() || !livekitSecret()) {
throw Object.assign(
new Error("LIVEKIT_KEY and LIVEKIT_SECRET are not configured"),
{ statusCode: 503 }
)
}
const room = await provisionTenantRoom(userId, tenantId, options)
const session = await ensureCurrentUserJoinedRoom(userId, tenantId, {
roomId: room.roomId,
alias: room.alias,
})
const displayName = await getCurrentUserDisplayName(userId, tenantId)
const liveKitRoomName = `fedeo-${tenantId || "global"}-${room.key}`.replace(/[^a-zA-Z0-9_-]/g, "_")
const now = Math.floor(Date.now() / 1000)
const expiresInSeconds = 60 * 60
const video: LiveKitGrant = {
roomJoin: true,
room: liveKitRoomName,
canPublish: true,
canSubscribe: true,
}
const token = jwt.sign(
{
sub: session.matrixUserId,
name: displayName,
video,
nbf: now - 10,
exp: now + expiresInSeconds,
},
livekitSecret(),
{
algorithm: "HS256",
issuer: livekitKey(),
}
)
return {
roomId: room.roomId,
alias: room.alias,
key: room.key,
name: room.name,
matrixUserId: session.matrixUserId,
displayName,
liveKitUrl: livekitUrl(),
liveKitRoomName,
liveKitToken: token,
expiresInMs: expiresInSeconds * 1000,
}
}
const listTenantCommunicationUsers = async (tenantId: number | null) => {
const tenant = await getCurrentTenant(tenantId)
const rows = await server.db
@@ -1342,6 +1416,7 @@ export function matrixService(server: FastifyInstance) {
getTenantRoomMembers,
sendTenantRoomMessage,
createElementRoomSession,
createLiveKitRoomSession,
syncTenantRoomMembers,
getGeneralRoomMessages,
getGeneralRoomMembers,