KI-AGENT: Matrix Service User automatisch in Räume aufnehmen

This commit is contained in:
2026-05-22 21:29:31 +02:00
parent 38ccdd058b
commit 45ca4f7327
2 changed files with 95 additions and 1 deletions

View File

@@ -72,6 +72,7 @@ export function startMatrixPushWorker(server: FastifyInstance) {
let running = false
let stopped = false
let timer: ReturnType<typeof setTimeout> | undefined
let lastServiceJoinSyncAt = 0
const getTenantRecipients = async (tenantId: number) => {
const rows = await server.db
@@ -186,6 +187,18 @@ export function startMatrixPushWorker(server: FastifyInstance) {
running = true
try {
if (!lastServiceJoinSyncAt || Date.now() - lastServiceJoinSyncAt > 60_000) {
const joinResult = await matrix.syncServiceJoinedTenantRooms()
lastServiceJoinSyncAt = Date.now()
if (joinResult.failed) {
console.warn("Matrix-Push-Worker: Service-User konnte nicht alle Räume joinen", {
total: joinResult.total,
joined: joinResult.joined,
failed: joinResult.failed,
})
}
}
const initial = !since
const sync = await matrix.syncServiceRoomEvents(since, initial)
since = sync.nextBatch || since

View File

@@ -3,7 +3,7 @@ import { existsSync, readFileSync } from "node:fs"
import { resolve } from "node:path"
import { FastifyInstance } from "fastify"
import { authProfiles, authTenantUsers, authUsers, communicationRooms, tenants } from "../../db/schema"
import { and, eq } from "drizzle-orm"
import { and, eq, isNotNull } from "drizzle-orm"
import { secrets } from "../utils/secrets"
import jwt from "jsonwebtoken"
@@ -1126,6 +1126,86 @@ export function matrixService(server: FastifyInstance) {
}
}
const ensureServiceUserJoinedRoom = async (room: { roomId?: string | null; alias?: string | null }) => {
const target = room.roomId || room.alias
if (!target) return { ok: false, status: "missing_room" }
const serviceLogin = await ensureServiceAccessToken()
try {
await requestMatrixJson(
`/_synapse/admin/v1/join/${encodeURIComponent(target)}`,
serviceLogin.accessToken,
{
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ user_id: serviceLogin.matrixUserId }),
}
)
return { ok: true, status: "joined_admin", roomId: target }
} catch (adminErr: any) {
try {
await requestMatrixJson(
`/_matrix/client/v3/join/${encodeURIComponent(target)}`,
serviceLogin.accessToken,
{
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({}),
}
)
return { ok: true, status: "joined_client", roomId: target }
} catch (clientErr: any) {
return {
ok: false,
status: "failed",
roomId: target,
error: clientErr.message || adminErr.message || "Service-Join fehlgeschlagen",
}
}
}
}
const syncServiceJoinedTenantRooms = async () => {
const rooms = await server.db
.select({
id: communicationRooms.id,
tenantId: communicationRooms.tenantId,
key: communicationRooms.key,
name: communicationRooms.name,
matrixRoomId: communicationRooms.matrixRoomId,
matrixAlias: communicationRooms.matrixAlias,
})
.from(communicationRooms)
.where(and(
eq(communicationRooms.archived, false),
isNotNull(communicationRooms.matrixRoomId)
))
const results = []
for (const room of rooms) {
const result = await ensureServiceUserJoinedRoom({
roomId: room.matrixRoomId,
alias: room.matrixAlias,
})
results.push({
roomId: room.matrixRoomId,
roomKey: room.key,
roomName: room.name,
...result,
})
}
return {
total: results.length,
joined: results.filter((result) => result.ok).length,
failed: results.filter((result) => !result.ok).length,
results,
}
}
const ensureCurrentUserJoinedRoom = async (
userId: string,
tenantId: number | null,
@@ -2253,6 +2333,7 @@ export function matrixService(server: FastifyInstance) {
searchTenantRoomMessages,
syncTenantRoomEvents,
syncServiceRoomEvents,
syncServiceJoinedTenantRooms,
sendTenantRoomMessage,
sendTenantRoomReaction,
editTenantRoomMessage,