import { getServerSession } from "next-auth"; import { authOptions } from "@/app/api/auth/[...nextauth]/route"; import { NextResponse } from "next/server"; if (!process.env.ROCKET_CHAT_TOKEN || !process.env.ROCKET_CHAT_USER_ID) { console.error('Missing Rocket.Chat credentials in environment variables'); } export async function GET() { try { const session = await getServerSession(authOptions); if (!session) { return NextResponse.json({ error: "Unauthorized" }, { status: 401 }); } // Debug log to see all session data console.log('Session data:', { user: session.user, accessToken: session.accessToken ? 'present' : 'missing' }); if (!session.accessToken) { return NextResponse.json({ error: "No access token found" }, { status: 401 }); } // First get the username from Keycloak const keycloakResponse = await fetch( `${process.env.KEYCLOAK_BASE_URL}/realms/${process.env.KEYCLOAK_REALM}/protocol/openid-connect/userinfo`, { headers: { 'Authorization': `Bearer ${session.accessToken}` } } ); if (!keycloakResponse.ok) { console.error('Failed to get Keycloak user info:', { status: keycloakResponse.status, statusText: keycloakResponse.statusText, response: await keycloakResponse.text().catch(() => 'Could not get response text') }); return NextResponse.json( { error: "Failed to get user info from Keycloak" }, { status: keycloakResponse.status } ); } const keycloakUser = await keycloakResponse.json(); const username = keycloakUser.preferred_username; console.log('Keycloak user info:', { username, sub: keycloakUser.sub }); if (!username) { return NextResponse.json( { error: "No username found in Keycloak user info" }, { status: 400 } ); } // Get user info using personal access token const userInfoResponse = await fetch( `https://parole.slm-lab.net/api/v1/users.info?username=${username}`, { headers: { 'X-Auth-Token': process.env.ROCKET_CHAT_TOKEN!, 'X-User-Id': process.env.ROCKET_CHAT_USER_ID!, 'Content-Type': 'application/json' } } ); if (!userInfoResponse.ok) { console.error('Failed to get user info:', { status: userInfoResponse.status, statusText: userInfoResponse.statusText, headers: userInfoResponse.headers, response: await userInfoResponse.text().catch(() => 'Could not get response text') }); return NextResponse.json( { error: "Failed to get user info" }, { status: userInfoResponse.status } ); } const userInfo = await userInfoResponse.json(); console.log('User info success:', { userId: userInfo.user._id, username: userInfo.user.username }); // Get the user's subscriptions (rooms they are in) const subscriptionsResponse = await fetch( 'https://parole.slm-lab.net/api/v1/subscriptions.get', { headers: { 'X-Auth-Token': process.env.ROCKET_CHAT_TOKEN!, 'X-User-Id': userInfo.user._id, 'Content-Type': 'application/json' } } ); if (!subscriptionsResponse.ok) { console.error('Rocket.Chat subscriptions error:', { status: subscriptionsResponse.status, statusText: subscriptionsResponse.statusText, response: await subscriptionsResponse.text().catch(() => 'Could not get response text') }); return NextResponse.json( { error: "Failed to fetch subscriptions" }, { status: subscriptionsResponse.status } ); } const subscriptions = await subscriptionsResponse.json(); console.log('Subscriptions response:', subscriptions); if (!subscriptions.update || subscriptions.update.length === 0) { console.log('No subscriptions found'); return NextResponse.json({ messages: [] }); } // Get the last message from each room const messages = await Promise.all( subscriptions.update.map(async (subscription: any) => { try { if (!subscription.rid) { console.log('No room ID found for subscription:', subscription); return null; } // Choose the appropriate endpoint based on room type const endpoint = subscription.t === 'd' ? 'im.messages' : subscription.t === 'c' ? 'channels.messages' : 'groups.messages'; console.log(`Fetching messages for room ${subscription.name} using endpoint ${endpoint}`); // Get the most recent messages from the room const messagesResponse = await fetch( `https://parole.slm-lab.net/api/v1/${endpoint}?roomId=${subscription.rid}&count=1`, { headers: { 'X-Auth-Token': process.env.ROCKET_CHAT_TOKEN!, 'X-User-Id': process.env.ROCKET_CHAT_USER_ID!, 'Content-Type': 'application/json' } } ); if (!messagesResponse.ok) { console.error('Failed to fetch messages:', { roomId: subscription.rid, endpoint, status: messagesResponse.status, response: await messagesResponse.text().catch(() => 'Could not get response text') }); return null; } const messagesData = await messagesResponse.json(); console.log(`Messages response for ${subscription.name}:`, { count: messagesData.messages?.length, success: messagesData.success }); if (messagesData.messages && messagesData.messages.length > 0) { const message = messagesData.messages[0]; return { ...message, roomName: subscription.fname || subscription.name || 'Direct Message', roomType: subscription.t, }; } console.log('No messages found for room:', subscription.rid); return null; } catch (error) { console.error('Error processing room:', subscription.rid, error); return null; } }) ); // Filter out any null messages and sort by timestamp const validMessages = messages .filter((msg): msg is NonNullable => msg !== null) .sort((a, b) => new Date(b.ts).getTime() - new Date(a.ts).getTime()); console.log('Found messages:', validMessages.length); return NextResponse.json({ messages: validMessages }); } catch (error) { console.error('Error fetching messages:', error); return NextResponse.json( { error: "Internal server error" }, { status: 500 } ); } }