KI-AGENT: Matrix-Teilnehmer synchronisieren
This commit is contained in:
@@ -2,7 +2,7 @@ import { createHash, createHmac, randomBytes } from "node:crypto"
|
||||
import { existsSync, readFileSync } from "node:fs"
|
||||
import { resolve } from "node:path"
|
||||
import { FastifyInstance } from "fastify"
|
||||
import { authProfiles, authUsers, communicationRooms, tenants } from "../../db/schema"
|
||||
import { authProfiles, authTenantUsers, authUsers, communicationRooms, tenants } from "../../db/schema"
|
||||
import { and, eq } from "drizzle-orm"
|
||||
import { secrets } from "../utils/secrets"
|
||||
|
||||
@@ -944,21 +944,15 @@ export function matrixService(server: FastifyInstance) {
|
||||
return session
|
||||
}
|
||||
|
||||
try {
|
||||
await requestMatrixJson(
|
||||
`/_matrix/client/v3/join/${encodeURIComponent(room.roomId || room.alias)}`,
|
||||
session.accessToken,
|
||||
{
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({}),
|
||||
}
|
||||
)
|
||||
} catch (err: any) {
|
||||
if (err.errcode !== "M_FORBIDDEN" && err.errcode !== "M_UNKNOWN") {
|
||||
throw err
|
||||
await requestMatrixJson(
|
||||
`/_matrix/client/v3/join/${encodeURIComponent(room.roomId || room.alias)}`,
|
||||
session.accessToken,
|
||||
{
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({}),
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
matrixJoinedRoomCache.set(joinCacheKey, Date.now() + 30 * 60 * 1000)
|
||||
return session
|
||||
@@ -1112,6 +1106,125 @@ export function matrixService(server: FastifyInstance) {
|
||||
}
|
||||
}
|
||||
|
||||
const listTenantCommunicationUsers = async (tenantId: number | null) => {
|
||||
const tenant = await getCurrentTenant(tenantId)
|
||||
const rows = await server.db
|
||||
.select({
|
||||
userId: authTenantUsers.user_id,
|
||||
email: authUsers.email,
|
||||
profileActive: authProfiles.active,
|
||||
firstName: authProfiles.first_name,
|
||||
lastName: authProfiles.last_name,
|
||||
fullName: authProfiles.full_name,
|
||||
})
|
||||
.from(authTenantUsers)
|
||||
.innerJoin(authUsers, eq(authUsers.id, authTenantUsers.user_id))
|
||||
.leftJoin(authProfiles, and(
|
||||
eq(authProfiles.user_id, authTenantUsers.user_id),
|
||||
eq(authProfiles.tenant_id, tenant.id)
|
||||
))
|
||||
.where(eq(authTenantUsers.tenant_id, tenant.id))
|
||||
|
||||
return rows
|
||||
.filter((row) => row.profileActive !== false)
|
||||
.map((row) => ({
|
||||
userId: row.userId,
|
||||
email: row.email,
|
||||
displayName: row.fullName || `${row.firstName || ""} ${row.lastName || ""}`.trim() || row.email,
|
||||
}))
|
||||
}
|
||||
|
||||
const inviteMatrixUserToRoom = async (
|
||||
room: { roomId: string },
|
||||
matrixUserId: string,
|
||||
reason?: string
|
||||
) => {
|
||||
const serviceLogin = await ensureServiceAccessToken()
|
||||
|
||||
try {
|
||||
await requestMatrixJson(
|
||||
`/_matrix/client/v3/rooms/${encodeURIComponent(room.roomId)}/invite`,
|
||||
serviceLogin.accessToken,
|
||||
{
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({
|
||||
user_id: matrixUserId,
|
||||
reason,
|
||||
}),
|
||||
}
|
||||
)
|
||||
|
||||
return "invited"
|
||||
} catch (err: any) {
|
||||
if (
|
||||
err.errcode === "M_FORBIDDEN" ||
|
||||
err.errcode === "M_BAD_STATE" ||
|
||||
err.errcode === "M_UNKNOWN"
|
||||
) {
|
||||
return "already_available"
|
||||
}
|
||||
|
||||
throw err
|
||||
}
|
||||
}
|
||||
|
||||
const syncTenantRoomMembers = async (
|
||||
requestingUserId: string,
|
||||
tenantId: number | null,
|
||||
options: MatrixTenantRoomOptions = {}
|
||||
) => {
|
||||
const room = await provisionTenantRoom(requestingUserId, tenantId, options)
|
||||
const users = await listTenantCommunicationUsers(tenantId)
|
||||
const results = []
|
||||
|
||||
for (const user of users) {
|
||||
try {
|
||||
const account = await provisionCurrentUser(user.userId, tenantId)
|
||||
await inviteMatrixUserToRoom(
|
||||
{ roomId: room.roomId },
|
||||
account.matrixUserId,
|
||||
`FEDEO-Raumsynchronisation: ${room.name}`
|
||||
)
|
||||
await ensureCurrentUserJoinedRoom(user.userId, tenantId, {
|
||||
roomId: room.roomId,
|
||||
alias: room.alias,
|
||||
})
|
||||
|
||||
results.push({
|
||||
userId: user.userId,
|
||||
email: user.email,
|
||||
displayName: user.displayName,
|
||||
matrixUserId: account.matrixUserId,
|
||||
status: "joined",
|
||||
ok: true,
|
||||
})
|
||||
} catch (err: any) {
|
||||
results.push({
|
||||
userId: user.userId,
|
||||
email: user.email,
|
||||
displayName: user.displayName,
|
||||
status: "failed",
|
||||
ok: false,
|
||||
error: err.message || "Synchronisation fehlgeschlagen",
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
roomId: room.roomId,
|
||||
alias: room.alias,
|
||||
key: room.key,
|
||||
name: room.name,
|
||||
total: results.length,
|
||||
joined: results.filter((item) => item.status === "joined").length,
|
||||
invited: results.filter((item) => item.status === "invited").length,
|
||||
alreadyAvailable: results.filter((item) => item.status === "already_available").length,
|
||||
failed: results.filter((item) => !item.ok).length,
|
||||
results,
|
||||
}
|
||||
}
|
||||
|
||||
const getGeneralRoomMessages = (userId: string, tenantId: number | null) =>
|
||||
getTenantRoomMessages(userId, tenantId, {
|
||||
key: "allgemein",
|
||||
@@ -1149,6 +1262,7 @@ export function matrixService(server: FastifyInstance) {
|
||||
getTenantRoomMessages,
|
||||
getTenantRoomMembers,
|
||||
sendTenantRoomMessage,
|
||||
syncTenantRoomMembers,
|
||||
getGeneralRoomMessages,
|
||||
getGeneralRoomMembers,
|
||||
sendGeneralRoomMessage,
|
||||
|
||||
Reference in New Issue
Block a user