notifications big
This commit is contained in:
parent
af1635b7da
commit
95fc180d3c
@ -315,9 +315,203 @@ export class RocketChatAdapter implements NotificationAdapter {
|
||||
}
|
||||
|
||||
async getNotifications(userId: string, page = 1, limit = 20): Promise<Notification[]> {
|
||||
// For now, return empty array - we can implement this later if needed
|
||||
// The notification count is what matters for the badge
|
||||
return [];
|
||||
logger.debug('[ROCKETCHAT_ADAPTER] getNotifications called', { userId, page, limit });
|
||||
|
||||
try {
|
||||
const email = await this.getUserEmail();
|
||||
if (!email) {
|
||||
logger.error('[ROCKETCHAT_ADAPTER] Could not get user email');
|
||||
return [];
|
||||
}
|
||||
|
||||
const rocketChatUserId = await this.getRocketChatUserId(email);
|
||||
if (!rocketChatUserId) {
|
||||
logger.debug('[ROCKETCHAT_ADAPTER] User not found in RocketChat');
|
||||
return [];
|
||||
}
|
||||
|
||||
const userToken = await this.getUserToken(rocketChatUserId);
|
||||
if (!userToken) {
|
||||
logger.error('[ROCKETCHAT_ADAPTER] Could not get user token');
|
||||
return [];
|
||||
}
|
||||
|
||||
const userHeaders = {
|
||||
'X-Auth-Token': userToken.authToken,
|
||||
'X-User-Id': userToken.userId,
|
||||
'Content-Type': 'application/json'
|
||||
};
|
||||
|
||||
// Get user's subscriptions with unread messages
|
||||
const subscriptionsResponse = await fetch(`${this.baseUrl}/api/v1/subscriptions.get`, {
|
||||
method: 'GET',
|
||||
headers: userHeaders
|
||||
});
|
||||
|
||||
if (!subscriptionsResponse.ok) {
|
||||
logger.error('[ROCKETCHAT_ADAPTER] Failed to get subscriptions', {
|
||||
status: subscriptionsResponse.status,
|
||||
});
|
||||
return [];
|
||||
}
|
||||
|
||||
const subscriptionsData = await subscriptionsResponse.json();
|
||||
if (!subscriptionsData.success || !Array.isArray(subscriptionsData.update)) {
|
||||
logger.error('[ROCKETCHAT_ADAPTER] Invalid subscriptions response');
|
||||
return [];
|
||||
}
|
||||
|
||||
// Filter subscriptions with unread messages
|
||||
const userSubscriptions = subscriptionsData.update.filter((sub: any) => {
|
||||
return (sub.unread > 0 || sub.alert) && ['d', 'c', 'p'].includes(sub.t);
|
||||
});
|
||||
|
||||
// Get user info for comparison
|
||||
const usersResponse = await fetch(`${this.baseUrl}/api/v1/users.list`, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'X-Auth-Token': process.env.ROCKET_CHAT_TOKEN!,
|
||||
'X-User-Id': process.env.ROCKET_CHAT_USER_ID!,
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
});
|
||||
|
||||
let currentUser: any = null;
|
||||
if (usersResponse.ok) {
|
||||
const usersData = await usersResponse.json();
|
||||
if (usersData.success && Array.isArray(usersData.users)) {
|
||||
const username = email.split('@')[0];
|
||||
currentUser = usersData.users.find((u: any) =>
|
||||
u.username === username || u.emails?.some((e: any) => e.address === email)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const notifications: Notification[] = [];
|
||||
|
||||
// Fetch messages for each subscription with unread messages
|
||||
for (const subscription of userSubscriptions) {
|
||||
try {
|
||||
// Determine the correct endpoint based on room type
|
||||
let endpoint;
|
||||
switch (subscription.t) {
|
||||
case 'c':
|
||||
endpoint = 'channels.messages';
|
||||
break;
|
||||
case 'p':
|
||||
endpoint = 'groups.messages';
|
||||
break;
|
||||
case 'd':
|
||||
endpoint = 'im.messages';
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
|
||||
const queryParams = new URLSearchParams({
|
||||
roomId: subscription.rid,
|
||||
count: String(Math.max(subscription.unread, 1)) // Fetch at least 1 message
|
||||
});
|
||||
|
||||
const messagesResponse = await fetch(
|
||||
`${this.baseUrl}/api/v1/${endpoint}?${queryParams}`, {
|
||||
method: 'GET',
|
||||
headers: userHeaders
|
||||
}
|
||||
);
|
||||
|
||||
if (!messagesResponse.ok) {
|
||||
logger.error('[ROCKETCHAT_ADAPTER] Failed to get messages for room', {
|
||||
roomName: subscription.name,
|
||||
status: messagesResponse.status,
|
||||
});
|
||||
continue;
|
||||
}
|
||||
|
||||
const messageData = await messagesResponse.json();
|
||||
|
||||
if (messageData.success && messageData.messages?.length > 0) {
|
||||
// Get the latest unread message (skip own messages)
|
||||
const unreadMessages = messageData.messages.filter((msg: any) => {
|
||||
// Skip messages sent by current user
|
||||
if (currentUser && msg.u?._id === currentUser._id) {
|
||||
return false;
|
||||
}
|
||||
// Skip system messages
|
||||
if (msg.t || !msg.msg) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
if (unreadMessages.length > 0) {
|
||||
const latestMessage = unreadMessages[0];
|
||||
const messageUser = latestMessage.u || {};
|
||||
const roomName = subscription.fname || subscription.name || subscription.name;
|
||||
|
||||
// Determine room type for link
|
||||
let roomTypePath = 'channel';
|
||||
if (subscription.t === 'd') roomTypePath = 'direct';
|
||||
else if (subscription.t === 'p') roomTypePath = 'group';
|
||||
|
||||
const notification: Notification = {
|
||||
id: `rocketchat-${latestMessage._id}`,
|
||||
source: 'rocketchat',
|
||||
sourceId: latestMessage._id,
|
||||
type: 'message',
|
||||
title: subscription.t === 'd'
|
||||
? `Message de ${messageUser.name || messageUser.username || 'Utilisateur'}`
|
||||
: `${messageUser.name || messageUser.username || 'Utilisateur'} dans ${roomName}`,
|
||||
message: latestMessage.msg || '',
|
||||
link: `${this.baseUrl}/${roomTypePath}/${subscription.name}`,
|
||||
isRead: false, // All messages here are unread
|
||||
timestamp: new Date(latestMessage.ts),
|
||||
priority: subscription.alert ? 'high' : 'normal',
|
||||
user: {
|
||||
id: messageUser._id || '',
|
||||
name: messageUser.name || messageUser.username || 'Utilisateur',
|
||||
},
|
||||
metadata: {
|
||||
roomId: subscription.rid,
|
||||
roomName: roomName,
|
||||
roomType: subscription.t,
|
||||
unreadCount: subscription.unread,
|
||||
}
|
||||
};
|
||||
|
||||
notifications.push(notification);
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
logger.error('[ROCKETCHAT_ADAPTER] Error fetching messages for room', {
|
||||
roomName: subscription.name,
|
||||
error: error instanceof Error ? error.message : String(error),
|
||||
});
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// Sort by timestamp (newest first) and apply pagination
|
||||
notifications.sort((a, b) => b.timestamp.getTime() - a.timestamp.getTime());
|
||||
|
||||
const startIndex = (page - 1) * limit;
|
||||
const endIndex = startIndex + limit;
|
||||
const paginatedNotifications = notifications.slice(startIndex, endIndex);
|
||||
|
||||
logger.debug('[ROCKETCHAT_ADAPTER] getNotifications result', {
|
||||
total: notifications.length,
|
||||
returned: paginatedNotifications.length,
|
||||
page,
|
||||
limit,
|
||||
});
|
||||
|
||||
return paginatedNotifications;
|
||||
} catch (error) {
|
||||
logger.error('[ROCKETCHAT_ADAPTER] Error getting notifications', {
|
||||
error: error instanceof Error ? error.message : String(error),
|
||||
});
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
async markAsRead(userId: string, notificationId: string): Promise<boolean> {
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
export interface Notification {
|
||||
id: string;
|
||||
source: 'leantime' | 'nextcloud' | 'gitea' | 'dolibarr' | 'moodle';
|
||||
source: 'leantime' | 'rocketchat' | 'email' | 'nextcloud' | 'gitea' | 'dolibarr' | 'moodle';
|
||||
sourceId: string; // Original ID from the source system
|
||||
type: string; // Type of notification (e.g., 'task', 'mention', 'comment')
|
||||
type: string; // Type of notification (e.g., 'task', 'mention', 'comment', 'message')
|
||||
title: string;
|
||||
message: string;
|
||||
link?: string; // Link to view the item in the source system
|
||||
|
||||
Loading…
Reference in New Issue
Block a user