diff --git a/app/api/rocket-chat/user-token/route.ts b/app/api/rocket-chat/user-token/route.ts index 8ea8ff9..9edc39f 100644 --- a/app/api/rocket-chat/user-token/route.ts +++ b/app/api/rocket-chat/user-token/route.ts @@ -101,10 +101,18 @@ export async function GET(request: Request) { const tokenData = await createTokenResponse.json(); + logger.debug('[ROCKET_CHAT_USER_TOKEN] Token created', { + userId: currentUser._id, + hasAuthToken: !!tokenData.data?.authToken, + tokenLength: tokenData.data?.authToken?.length, + }); + return NextResponse.json({ userId: currentUser._id, authToken: tokenData.data.authToken, username: currentUser.username, + // Also return the full token data for debugging + tokenData: tokenData.data, }); } catch (error: any) { logger.error('[ROCKET_CHAT_USER_TOKEN] Error', { diff --git a/components/layout/layout-wrapper.tsx b/components/layout/layout-wrapper.tsx index 59dcfe0..77ad7f0 100644 --- a/components/layout/layout-wrapper.tsx +++ b/components/layout/layout-wrapper.tsx @@ -20,8 +20,64 @@ export function LayoutWrapper({ children, isSignInPage, isAuthenticated }: Layou const { currentBackground, changeBackground } = useBackgroundImage(); const { data: session } = useSession(); - // Listen for incoming RocketChat calls + // Listen for incoming RocketChat calls via WebSocket useRocketChatCalls(); + + // Also listen for RocketChat iframe events (fallback) + useEffect(() => { + if (isSignInPage) return; + + const handleRocketChatMessage = (event: MessageEvent) => { + // Listen for RocketChat iframe events + if (event.data && typeof event.data === 'object') { + // Check for new messages that might be call invitations + if (event.data.event === 'new-message' || event.data.eventName === 'new-message') { + const message = event.data.message || event.data.data; + if (message) { + // Check if message contains call-related content + const text = message.text || message.msg || ''; + const isCallMessage = + text.includes('video') || + text.includes('audio') || + text.includes('call') || + message.attachments?.some((att: any) => + att.actions?.some((action: any) => + action.type === 'button' && + (action.text?.toLowerCase().includes('join') || action.text?.toLowerCase().includes('appel')) + ) + ); + + if (isCallMessage) { + console.log('[ROCKETCHAT_IFRAME] 📞 Possible call message detected from iframe', message); + } + } + } + + // Check for notification events that might be calls + if (event.data.event === 'notification' || event.data.eventName === 'notification') { + const notification = event.data.notification || event.data.data; + if (notification) { + const title = notification.title || ''; + const text = notification.text || ''; + const isCallNotification = + title.toLowerCase().includes('call') || + title.toLowerCase().includes('appel') || + text.toLowerCase().includes('video') || + text.toLowerCase().includes('audio'); + + if (isCallNotification) { + console.log('[ROCKETCHAT_IFRAME] 📞 Possible call notification from iframe', notification); + } + } + } + } + }; + + window.addEventListener('message', handleRocketChatMessage); + return () => { + window.removeEventListener('message', handleRocketChatMessage); + }; + }, [isSignInPage]); // Global listener for logout messages from iframe applications useEffect(() => { diff --git a/lib/services/rocketchat-call-listener.ts b/lib/services/rocketchat-call-listener.ts index 33b86c6..6a0609a 100644 --- a/lib/services/rocketchat-call-listener.ts +++ b/lib/services/rocketchat-call-listener.ts @@ -104,7 +104,9 @@ export class RocketChatCallListener { collection: message.collection, id: message.id, eventName: message.fields?.eventName, - fullMessage: message, + error: message.error, + reason: message.reason, + fullMessage: JSON.stringify(message, null, 2), }); this.handleMessage(message); } catch (error) { @@ -143,7 +145,7 @@ export class RocketChatCallListener { } /** - * Authenticate with RocketChat + * Authenticate with RocketChat using resume token */ private authenticate(): void { if (!this.ws || !this.authToken || !this.userId) { @@ -155,6 +157,7 @@ export class RocketChatCallListener { return; } + // Try method 1: resume token const loginMessage = { msg: 'method', method: 'login', @@ -166,13 +169,38 @@ export class RocketChatCallListener { ], }; - console.log('[ROCKETCHAT_CALL_LISTENER] 🔐 Sending login message', { + console.log('[ROCKETCHAT_CALL_LISTENER] 🔐 Sending login message (resume token)', { + method: 'login', + hasToken: !!this.authToken, + userId: this.userId, + tokenLength: this.authToken.length, + }); + logger.debug('[ROCKETCHAT_CALL_LISTENER] Sending login message'); + this.ws.send(JSON.stringify(loginMessage)); + } + + /** + * Alternative authentication method - try different token formats + */ + private authenticateAlternative(): void { + if (!this.ws || !this.authToken || !this.userId) { + return; + } + + // Try method 2: token as string (not in object) + const loginMessage2 = { + msg: 'method', + method: 'login', + id: `login-alt-${Date.now()}`, + params: [this.authToken], + }; + + console.log('[ROCKETCHAT_CALL_LISTENER] 🔐 Trying alternative login (token as string)', { method: 'login', hasToken: !!this.authToken, userId: this.userId, }); - logger.debug('[ROCKETCHAT_CALL_LISTENER] Sending login message'); - this.ws.send(JSON.stringify(loginMessage)); + this.ws.send(JSON.stringify(loginMessage2)); } /** @@ -224,6 +252,28 @@ export class RocketChatCallListener { * Handle incoming WebSocket messages */ private handleMessage(message: any): void { + // Handle error messages + if (message.msg === 'error') { + const errorDetails = { + error: message.error, + reason: message.reason, + message: message.message, + errorType: message.error?.error, + errorMessage: message.error?.message, + errorIsString: typeof message.error === 'string', + fullError: JSON.stringify(message, null, 2), + }; + console.error('[ROCKETCHAT_CALL_LISTENER] ❌ WebSocket error received:', errorDetails); + console.error('[ROCKETCHAT_CALL_LISTENER] ❌ Full error object:', message); + + // If it's a login error, log it but don't retry automatically + if (message.id?.startsWith('login-') || message.id?.startsWith('login-alt-')) { + console.error('[ROCKETCHAT_CALL_LISTENER] 🔴 LOGIN FAILED - Error details above'); + // The error message will tell us what's wrong + } + return; + } + // Handle login response if (message.msg === 'result' && message.id?.startsWith('login-')) { console.log('[ROCKETCHAT_CALL_LISTENER] 📋 Login response received', {