refactor Notifications

This commit is contained in:
alma 2026-01-16 00:48:12 +01:00
parent b926597a48
commit 2d35dbe074
2 changed files with 158 additions and 30 deletions

View File

@ -19,45 +19,52 @@ export function useRocketChatCalls() {
*/ */
const getRocketChatCredentials = useCallback(async () => { const getRocketChatCredentials = useCallback(async () => {
if (!session?.user?.id) { if (!session?.user?.id) {
console.log('[useRocketChatCalls] No session user ID');
return null; return null;
} }
try { try {
// Get user token from RocketChat API console.log('[useRocketChatCalls] Getting RocketChat credentials...');
const response = await fetch('/api/rocket-chat/messages?refresh=true', {
credentials: 'include',
});
if (!response.ok) {
logger.error('[useRocketChatCalls] Failed to get RocketChat credentials');
return null;
}
// Extract base URL from environment // Extract base URL from environment
const baseUrl = process.env.NEXT_PUBLIC_IFRAME_PAROLE_URL?.split('/channel')[0]; const baseUrl = process.env.NEXT_PUBLIC_IFRAME_PAROLE_URL?.split('/channel')[0];
if (!baseUrl) { if (!baseUrl) {
console.error('[useRocketChatCalls] RocketChat base URL not configured');
logger.error('[useRocketChatCalls] RocketChat base URL not configured'); logger.error('[useRocketChatCalls] RocketChat base URL not configured');
return null; return null;
} }
// Get user's RocketChat ID and token // Get user's RocketChat ID and token
// We need to call the API to get the user token
const tokenResponse = await fetch('/api/rocket-chat/user-token', { const tokenResponse = await fetch('/api/rocket-chat/user-token', {
credentials: 'include', credentials: 'include',
}); });
if (!tokenResponse.ok) { if (!tokenResponse.ok) {
logger.error('[useRocketChatCalls] Failed to get user token'); const errorText = await tokenResponse.text();
console.error('[useRocketChatCalls] Failed to get user token', {
status: tokenResponse.status,
error: errorText,
});
logger.error('[useRocketChatCalls] Failed to get user token', {
status: tokenResponse.status,
});
return null; return null;
} }
const tokenData = await tokenResponse.json(); const tokenData = await tokenResponse.json();
console.log('[useRocketChatCalls] ✅ Got credentials', {
userId: tokenData.userId,
hasToken: !!tokenData.authToken,
baseUrl,
});
return { return {
userId: tokenData.userId, userId: tokenData.userId,
authToken: tokenData.authToken, authToken: tokenData.authToken,
baseUrl, baseUrl,
}; };
} catch (error) { } catch (error) {
console.error('[useRocketChatCalls] Error getting credentials', error);
logger.error('[useRocketChatCalls] Error getting credentials', { error }); logger.error('[useRocketChatCalls] Error getting credentials', { error });
return null; return null;
} }
@ -68,11 +75,15 @@ export function useRocketChatCalls() {
*/ */
const initializeListener = useCallback(async () => { const initializeListener = useCallback(async () => {
if (initializedRef.current || listenerRef.current) { if (initializedRef.current || listenerRef.current) {
console.log('[useRocketChatCalls] Already initialized, skipping');
return; return;
} }
console.log('[useRocketChatCalls] Initializing call listener...');
const credentials = await getRocketChatCredentials(); const credentials = await getRocketChatCredentials();
if (!credentials) { if (!credentials) {
console.warn('[useRocketChatCalls] Could not get credentials, skipping initialization');
logger.warn('[useRocketChatCalls] Could not get credentials, skipping initialization'); logger.warn('[useRocketChatCalls] Could not get credentials, skipping initialization');
return; return;
} }
@ -85,12 +96,20 @@ export function useRocketChatCalls() {
credentials.baseUrl credentials.baseUrl
); );
console.log('[useRocketChatCalls] Listener initialization result:', success);
if (success) { if (success) {
listenerRef.current = listener; listenerRef.current = listener;
initializedRef.current = true; initializedRef.current = true;
// Subscribe to call events // Subscribe to call events
const unsubscribe = listener.onCall((callEvent: CallEvent) => { const unsubscribe = listener.onCall((callEvent: CallEvent) => {
console.log('[useRocketChatCalls] 🎉 INCOMING CALL DETECTED!', {
from: callEvent.from.username,
roomId: callEvent.roomId,
roomName: callEvent.roomName,
});
logger.info('[useRocketChatCalls] Incoming call detected', { logger.info('[useRocketChatCalls] Incoming call detected', {
from: callEvent.from.username, from: callEvent.from.username,
roomId: callEvent.roomId, roomId: callEvent.roomId,
@ -114,13 +133,21 @@ export function useRocketChatCalls() {
}, },
}, },
], ],
}).then(() => {
console.log('[useRocketChatCalls] ✅ Notification triggered successfully');
}).catch((error) => {
console.error('[useRocketChatCalls] ❌ Error triggering notification', error);
}); });
}); });
unsubscribeRef.current = unsubscribe; unsubscribeRef.current = unsubscribe;
console.log('[useRocketChatCalls] ✅ Call listener initialized and subscribed');
logger.debug('[useRocketChatCalls] Call listener initialized'); logger.debug('[useRocketChatCalls] Call listener initialized');
} else {
console.error('[useRocketChatCalls] ❌ Failed to initialize listener');
} }
} catch (error) { } catch (error) {
console.error('[useRocketChatCalls] Error initializing listener', error);
logger.error('[useRocketChatCalls] Error initializing listener', { error }); logger.error('[useRocketChatCalls] Error initializing listener', { error });
} }
}, [getRocketChatCredentials, triggerNotification]); }, [getRocketChatCredentials, triggerNotification]);

View File

@ -152,11 +152,13 @@ export class RocketChatCallListener {
*/ */
private subscribeToCalls(): void { private subscribeToCalls(): void {
if (!this.ws || !this.userId) { if (!this.ws || !this.userId) {
console.warn('[ROCKETCHAT_CALL_LISTENER] Cannot subscribe - missing ws or userId');
return; return;
} }
this.subscriptionId = `call-sub-${Date.now()}`; this.subscriptionId = `call-sub-${Date.now()}`;
// Subscribe to webrtc events
const subscribeMessage = { const subscribeMessage = {
msg: 'sub', msg: 'sub',
id: this.subscriptionId, id: this.subscriptionId,
@ -164,12 +166,30 @@ export class RocketChatCallListener {
params: [`${this.userId}/webrtc`, false], params: [`${this.userId}/webrtc`, false],
}; };
console.log('[ROCKETCHAT_CALL_LISTENER] Subscribing to webrtc events', {
subscriptionId: this.subscriptionId,
userId: this.userId,
message: subscribeMessage,
});
logger.debug('[ROCKETCHAT_CALL_LISTENER] Subscribing to webrtc events', { logger.debug('[ROCKETCHAT_CALL_LISTENER] Subscribing to webrtc events', {
subscriptionId: this.subscriptionId, subscriptionId: this.subscriptionId,
userId: this.userId, userId: this.userId,
}); });
this.ws.send(JSON.stringify(subscribeMessage)); this.ws.send(JSON.stringify(subscribeMessage));
// Also subscribe to all user notifications to catch any call-related events
const allNotificationsSubId = `all-notifications-${Date.now()}`;
const allNotificationsMessage = {
msg: 'sub',
id: allNotificationsSubId,
name: 'stream-notify-user',
params: [`${this.userId}/notification`, false],
};
console.log('[ROCKETCHAT_CALL_LISTENER] Also subscribing to all notifications');
this.ws.send(JSON.stringify(allNotificationsMessage));
} }
/** /**
@ -198,9 +218,42 @@ export class RocketChatCallListener {
const eventName = message.fields?.eventName; const eventName = message.fields?.eventName;
const args = message.fields?.args || []; const args = message.fields?.args || [];
if (eventName?.includes('/webrtc') && args.length > 0) { console.log('[ROCKETCHAT_CALL_LISTENER] Received changed message:', {
this.handleCallEvent(args[0]); eventName,
argsCount: args.length,
message: JSON.stringify(message, null, 2),
});
// Check if this is a webrtc event
if (eventName?.includes('/webrtc')) {
console.log('[ROCKETCHAT_CALL_LISTENER] ✅ This is a webrtc event!');
if (args.length > 0) {
this.handleCallEvent(args[0]);
} else {
// Sometimes the event data might be in the message itself
this.handleCallEvent(message.fields);
}
} }
// Also check for other possible call-related events
if (eventName?.includes('/call') || eventName?.includes('/video') || eventName?.includes('/audio')) {
console.log('[ROCKETCHAT_CALL_LISTENER] ✅ This might be a call event!');
if (args.length > 0) {
this.handleCallEvent(args[0]);
} else {
this.handleCallEvent(message.fields);
}
}
}
// Log all messages for debugging
if (message.msg && message.collection === 'stream-notify-user') {
console.log('[ROCKETCHAT_CALL_LISTENER] Stream notify user message:', {
msg: message.msg,
collection: message.collection,
eventName: message.fields?.eventName,
hasArgs: !!(message.fields?.args && message.fields.args.length > 0),
});
} }
} }
@ -208,37 +261,77 @@ export class RocketChatCallListener {
* Handle call event from RocketChat * Handle call event from RocketChat
*/ */
private handleCallEvent(eventData: any): void { private handleCallEvent(eventData: any): void {
console.log('[ROCKETCHAT_CALL_LISTENER] Received webrtc event - FULL DATA:', JSON.stringify(eventData, null, 2));
logger.debug('[ROCKETCHAT_CALL_LISTENER] Received call event', { eventData }); logger.debug('[ROCKETCHAT_CALL_LISTENER] Received call event', { eventData });
try { try {
// Parse the call event data // RocketChat webrtc events can have different formats
// RocketChat webrtc events typically contain: // Let's check multiple possible structures
// - type: 'call', 'ringing', 'answered', 'ended' let callType: string | null = null;
// - from: user info let from: any = {};
// - roomId: room identifier let roomId: string | null = null;
const callType = eventData.type || eventData.action; let roomName: string | null = null;
const from = eventData.from || eventData.caller || {};
const roomId = eventData.roomId || eventData.rid;
if (!callType || !roomId) { // Try different event structures
logger.warn('[ROCKETCHAT_CALL_LISTENER] Invalid call event data', { eventData }); if (eventData.type) {
return; callType = eventData.type;
} else if (eventData.action) {
callType = eventData.action;
} else if (eventData.event) {
callType = eventData.event;
} else if (eventData.callType) {
callType = eventData.callType;
} }
// Detect incoming call // Extract room info
if (callType === 'call' || callType === 'ringing' || eventData.action === 'ringing') { roomId = eventData.roomId || eventData.rid || eventData.room?._id || eventData.room?._id;
roomName = eventData.roomName || eventData.room?.name || eventData.room?.fname;
// Extract caller info
from = eventData.from || eventData.caller || eventData.user || eventData.sender || {};
// Log all possible fields for debugging
console.log('[ROCKETCHAT_CALL_LISTENER] Parsed event:', {
callType,
roomId,
roomName,
from,
allKeys: Object.keys(eventData),
});
// Check if this is an incoming call event
// RocketChat might send: 'call', 'ringing', 'incoming', 'offer', etc.
const isIncomingCall =
callType === 'call' ||
callType === 'ringing' ||
callType === 'incoming' ||
callType === 'offer' ||
callType === 'video' ||
callType === 'audio' ||
eventData.action === 'ringing' ||
eventData.type === 'video' ||
eventData.type === 'audio' ||
(eventData.type === 'call' && eventData.status === 'ringing');
if (isIncomingCall && roomId) {
const callEvent: CallEvent = { const callEvent: CallEvent = {
type: 'call-incoming', type: 'call-incoming',
from: { from: {
userId: from._id || from.userId || '', userId: from._id || from.userId || from.id || '',
username: from.username || '', username: from.username || from.name || 'Unknown',
name: from.name || from.username, name: from.name || from.username || 'Unknown',
}, },
roomId, roomId,
roomName: eventData.roomName || from.name, roomName: roomName || from.name || 'Chat',
timestamp: new Date(), timestamp: new Date(),
}; };
console.log('[ROCKETCHAT_CALL_LISTENER] ✅ Incoming call detected!', {
from: callEvent.from.username,
roomId: callEvent.roomId,
roomName: callEvent.roomName,
});
logger.info('[ROCKETCHAT_CALL_LISTENER] Incoming call detected', { logger.info('[ROCKETCHAT_CALL_LISTENER] Incoming call detected', {
from: callEvent.from.username, from: callEvent.from.username,
roomId, roomId,
@ -249,11 +342,19 @@ export class RocketChatCallListener {
try { try {
handler(callEvent); handler(callEvent);
} catch (error) { } catch (error) {
console.error('[ROCKETCHAT_CALL_LISTENER] Error in call handler', error);
logger.error('[ROCKETCHAT_CALL_LISTENER] Error in call handler', { error }); logger.error('[ROCKETCHAT_CALL_LISTENER] Error in call handler', { error });
} }
}); });
} else {
console.log('[ROCKETCHAT_CALL_LISTENER] ⚠️ Event not recognized as incoming call', {
callType,
roomId,
isIncomingCall,
});
} }
} catch (error) { } catch (error) {
console.error('[ROCKETCHAT_CALL_LISTENER] Error handling call event', error);
logger.error('[ROCKETCHAT_CALL_LISTENER] Error handling call event', { logger.error('[ROCKETCHAT_CALL_LISTENER] Error handling call event', {
error: error instanceof Error ? error.message : String(error), error: error instanceof Error ? error.message : String(error),
eventData, eventData,