KI-AGENT: Matrix-Raum-API verallgemeinern

This commit is contained in:
2026-05-18 18:12:26 +02:00
parent 8824b1c9c8
commit f33ccf730a
3 changed files with 286 additions and 118 deletions

View File

@@ -35,6 +35,12 @@ type MatrixUserSession = {
validUntilMs: number
}
type MatrixTenantRoomOptions = {
key?: string
name?: string
topic?: string
}
type MatrixCachedValue<T = any> = {
exists: true
cachedUntil: number
@@ -48,6 +54,13 @@ const matrixTenantSpaceCache = new Map<string, MatrixCachedValue>()
const matrixTenantRoomCache = new Map<string, MatrixCachedValue>()
let matrixServiceSessionCache: MatrixUserSession | null = null
const defaultTenantRooms: Required<Pick<MatrixTenantRoomOptions, "key" | "name">>[] = [
{
key: "allgemein",
name: "Allgemeiner Chat",
},
]
const trimTrailingSlash = (value: string) => value.replace(/\/+$/, "")
const readLocalDevRegistrationSharedSecret = () => {
if (process.env.NODE_ENV === "production") return ""
@@ -173,6 +186,19 @@ export function matrixService(server: FastifyInstance) {
roomKey: string
) => `#${tenantRoomAliasLocalpart(tenant, roomKey)}:${serverName()}`
const normalizeTenantRoomOptions = (options: MatrixTenantRoomOptions = {}) => {
const fallbackName = options.key || options.name || "Allgemeiner Chat"
const key = normalizeMatrixAliasSeed(options.key || fallbackName)
const name = (options.name || fallbackName).trim() || "Allgemeiner Chat"
const topic = options.topic?.trim()
return {
key,
name,
topic,
}
}
const buildSharedSecretMac = (
nonce: string,
username: string,
@@ -637,16 +663,13 @@ export function matrixService(server: FastifyInstance) {
const provisionTenantRoom = async (
userId: string,
tenantId: number | null,
options: {
key?: string
name?: string
topic?: string
} = {}
options: MatrixTenantRoomOptions = {}
) => {
const tenant = await getCurrentTenant(tenantId)
const key = normalizeMatrixAliasSeed(options.key || options.name || "allgemein")
const name = (options.name || "Allgemeiner Chat").trim() || "Allgemeiner Chat"
const topic = (options.topic || `Allgemeiner Kommunikationsraum für ${tenant.name}`).trim()
const normalizedOptions = normalizeTenantRoomOptions(options)
const key = normalizedOptions.key
const name = normalizedOptions.name
const topic = (normalizedOptions.topic || `Allgemeiner Kommunikationsraum für ${tenant.name}`).trim()
const cacheKey = `${tenant.id}:${key}`
const cachedRoom = matrixTenantRoomCache.get(cacheKey)
@@ -780,11 +803,39 @@ export function matrixService(server: FastifyInstance) {
return session
}
const getGeneralRoomMessages = async (userId: string, tenantId: number | null) => {
const room = await provisionTenantRoom(userId, tenantId, {
key: "allgemein",
name: "Allgemeiner Chat",
})
const listTenantRooms = async (tenantId: number | null) => {
const tenant = await getCurrentTenant(tenantId)
const rooms = new Map<string, any>()
for (const room of defaultTenantRooms) {
rooms.set(room.key, await getTenantRoomStatus(tenant.id, room.key, room.name))
}
for (const [cacheKey, cachedRoom] of matrixTenantRoomCache.entries()) {
const [cachedTenantId, roomKey] = cacheKey.split(":")
if (cachedTenantId !== String(tenant.id) || !cachedRoom.value) continue
rooms.set(roomKey, {
...cachedRoom.value,
exists: true,
})
}
return {
tenantId: tenant.id,
tenantName: tenant.name,
rooms: Array.from(rooms.values()).sort((a, b) =>
String(a.name || a.key).localeCompare(String(b.name || b.key), "de")
),
}
}
const getTenantRoomMessages = async (
userId: string,
tenantId: number | null,
options: MatrixTenantRoomOptions = {}
) => {
const room = await provisionTenantRoom(userId, tenantId, options)
const session = await ensureCurrentUserJoinedRoom(userId, tenantId, {
roomId: room.roomId,
@@ -807,6 +858,8 @@ export function matrixService(server: FastifyInstance) {
return {
roomId: room.roomId,
alias: room.alias,
key: room.key,
name: room.name,
matrixUserId: session.matrixUserId,
messages: response.chunk
.filter((event) => event.type === "m.room.message" && event.content?.msgtype === "m.text")
@@ -822,11 +875,12 @@ export function matrixService(server: FastifyInstance) {
}
}
const getGeneralRoomMembers = async (userId: string, tenantId: number | null) => {
const room = await provisionTenantRoom(userId, tenantId, {
key: "allgemein",
name: "Allgemeiner Chat",
})
const getTenantRoomMembers = async (
userId: string,
tenantId: number | null,
options: MatrixTenantRoomOptions = {}
) => {
const room = await provisionTenantRoom(userId, tenantId, options)
const session = await ensureCurrentUserJoinedRoom(userId, tenantId, {
roomId: room.roomId,
@@ -840,6 +894,8 @@ export function matrixService(server: FastifyInstance) {
return {
roomId: room.roomId,
alias: room.alias,
key: room.key,
name: room.name,
members: Object.entries(members.joined).map(([matrixUserId, member]) => ({
matrixUserId,
displayName: member.display_name || matrixUserId,
@@ -849,9 +905,10 @@ export function matrixService(server: FastifyInstance) {
}
}
const sendGeneralRoomMessage = async (
const sendTenantRoomMessage = async (
userId: string,
tenantId: number | null,
options: MatrixTenantRoomOptions = {},
text: string
) => {
const message = text.trim()
@@ -863,10 +920,7 @@ export function matrixService(server: FastifyInstance) {
)
}
const room = await provisionTenantRoom(userId, tenantId, {
key: "allgemein",
name: "Allgemeiner Chat",
})
const room = await provisionTenantRoom(userId, tenantId, options)
const session = await ensureCurrentUserJoinedRoom(userId, tenantId, {
roomId: room.roomId,
@@ -896,9 +950,33 @@ export function matrixService(server: FastifyInstance) {
own: true,
roomId: room.roomId,
alias: room.alias,
key: room.key,
}
}
const getGeneralRoomMessages = (userId: string, tenantId: number | null) =>
getTenantRoomMessages(userId, tenantId, {
key: "allgemein",
name: "Allgemeiner Chat",
})
const getGeneralRoomMembers = (userId: string, tenantId: number | null) =>
getTenantRoomMembers(userId, tenantId, {
key: "allgemein",
name: "Allgemeiner Chat",
})
const sendGeneralRoomMessage = (userId: string, tenantId: number | null, text: string) =>
sendTenantRoomMessage(
userId,
tenantId,
{
key: "allgemein",
name: "Allgemeiner Chat",
},
text
)
return {
getStatus,
matrixUserIdForUser,
@@ -906,9 +984,13 @@ export function matrixService(server: FastifyInstance) {
provisionCurrentUser,
getTenantSpaceStatus,
provisionCurrentTenantSpace,
listTenantRooms,
getTenantRoomStatus,
provisionTenantRoom,
createAccessTokenForUser,
getTenantRoomMessages,
getTenantRoomMembers,
sendTenantRoomMessage,
getGeneralRoomMessages,
getGeneralRoomMembers,
sendGeneralRoomMessage,