Skip to content

Commit

Permalink
refactor: remove chat message notification queue, implement merge IDs…
Browse files Browse the repository at this point in the history
… for chat message notifications, so they can be grouped together
  • Loading branch information
julianlam committed Oct 2, 2023
1 parent a5c1b2a commit 3ba371f
Show file tree
Hide file tree
Showing 6 changed files with 30 additions and 36 deletions.
2 changes: 1 addition & 1 deletion public/language/en-GB/email.json
Expand Up @@ -45,7 +45,7 @@
"digest.title.week": "Your Weekly Digest",
"digest.title.month": "Your Monthly Digest",

"notif.chat.subject": "New chat message received from %1",
"notif.chat.subject": "New chat message received in \"%1\"",
"notif.chat.public-chat-subject": "New message from %1 in room %2",
"notif.chat.cta": "Click here to continue the conversation",
"notif.chat.unsub.info": "This chat notification was sent to you due to your subscription settings.",
Expand Down
3 changes: 3 additions & 0 deletions public/language/en-GB/notifications.json
Expand Up @@ -27,6 +27,9 @@


"new_message_from": "New message from <strong>%1</strong>",
"new_messages_from": "%1 new messages from <strong>%2</strong>",
"new_message_in": "New message in <strong>%1</strong>",
"new_messages_in": "%1 new messages in <strong>%2</strong>",
"user_posted_in_public_room": "<strong>%1</strong> wrote in <strong class=\"text-nowrap\"><i class=\"fa %2\"></i>%3</strong>",
"user_posted_in_public_room_dual": "<strong>%1</strong> and <strong>%2</strong> wrote in <strong class=\"text-nowrap\"><i class=\"fa %3\"></i>%4</strong>",
"user_posted_in_public_room_triple": "<strong>%1</strong>, <strong>%2</strong> and <strong>%3</strong> wrote in <strong class=\"text-nowrap\"><i class=\"fa %4\"></i>%5</strong>",
Expand Down
2 changes: 1 addition & 1 deletion src/messaging/index.js
Expand Up @@ -201,7 +201,7 @@ Messaging.getRecentChats = async (callerUid, uid, start, stop) => {
await Promise.all(results.roomData.map(async (room, index) => {
if (room) {
room.users = results.users[index];
room.groupChat = room.hasOwnProperty('groupChat') ? room.groupChat : room.users.length > 2;
room.groupChat = room.users.length > 2;
room.unread = results.unread[index];
room.teaser = results.teasers[index];

Expand Down
40 changes: 11 additions & 29 deletions src/messaging/notifications.js
Expand Up @@ -8,12 +8,8 @@ const notifications = require('../notifications');
const user = require('../user');
const io = require('../socket.io');
const plugins = require('../plugins');
const meta = require('../meta');

module.exports = function (Messaging) {
// Only used to notify a user of a new chat message
Messaging.notifyQueue = {};

Messaging.setUserNotificationSetting = async (uid, roomId, value) => {
if (parseInt(value, 10) === -1) {
// go back to default
Expand Down Expand Up @@ -73,26 +69,11 @@ module.exports = function (Messaging) {
Messaging.pushUnreadCount(uids, unreadData);
}

// Delayed notifications
let queueObj = Messaging.notifyQueue[`${fromUid}:${roomId}`];
if (queueObj) {
queueObj.message.content += `\n${messageObj.content}`;
clearTimeout(queueObj.timeout);
} else {
queueObj = {
message: messageObj,
};
Messaging.notifyQueue[`${fromUid}:${roomId}`] = queueObj;
try {
await sendNotification(fromUid, roomId, messageObj);
} catch (err) {
winston.error(`[messaging/notifications] Unabled to send notification\n${err.stack}`);
}

queueObj.timeout = setTimeout(async () => {
try {
await sendNotification(fromUid, roomId, queueObj.message);
delete Messaging.notifyQueue[`${fromUid}:${roomId}`];
} catch (err) {
winston.error(`[messaging/notifications] Unabled to send notification\n${err.stack}`);
}
}, meta.config.notificationSendDelay * 1000);
};

async function sendNotification(fromUid, roomId, messageObj) {
Expand Down Expand Up @@ -121,21 +102,22 @@ module.exports = function (Messaging) {
if (uidsToNotify.length) {
const { displayname } = messageObj.fromUser;
const isGroupChat = await Messaging.isGroupChat(roomId);
const roomName = roomData.roomName || `[[modules:chat.room-id, ${roomId}]]`;
const notifData = {
type: isGroupChat ? 'new-group-chat' : 'new-chat',
subject: `[[email:notif.chat.subject, ${displayname}]]`,
bodyShort: `[[notifications:new_message_from, ${displayname}]]`,
subject: `[[email:notif.chat.subject, ${roomName}]]`,
bodyShort: isGroupChat || roomData.roomName ? `[[notifications:new_message_in, ${roomName}]]` : `[[notifications:new_message_from, ${displayname}]]`,
bodyLong: messageObj.content,
nid: `chat_${roomId}_${fromUid}`,
nid: `chat_${roomId}_${fromUid}_${Date.now()}`,
mergeId: `new-chat|${roomId}`, // as roomId is the differentiator, no distinction between direct vs. group req'd.
from: fromUid,
roomId: roomId,
roomId,
roomName,
path: `/chats/${messageObj.roomId}`,
};
if (roomData.public) {
const icon = Messaging.getRoomIcon(roomData);
const roomName = roomData.roomName || `[[modules:chat.room-id, ${roomId}]]`;
notifData.type = 'new-public-chat';
notifData.roomName = roomName;
notifData.roomIcon = icon;
notifData.subject = `[[email:notif.chat.public-chat-subject, ${displayname}, ${roomName}]]`;
notifData.bodyShort = `[[notifications:user_posted_in_public_room, ${displayname}, ${icon}, ${roomName}]]`;
Expand Down
9 changes: 4 additions & 5 deletions src/messaging/rooms.js
Expand Up @@ -48,9 +48,7 @@ module.exports = function (Messaging) {
db.parseIntFields(data, intFields, fields);
data.roomName = validator.escape(String(data.roomName || ''));
data.public = parseInt(data.public, 10) === 1;
if (data.hasOwnProperty('groupChat')) {
data.groupChat = parseInt(data.groupChat, 10) === 1;
}
data.groupChat = data.userCount > 2;

if (!fields.length || fields.includes('notificationSetting')) {
data.notificationSetting = data.notificationSetting ||
Expand Down Expand Up @@ -287,7 +285,8 @@ module.exports = function (Messaging) {
};

Messaging.isGroupChat = async function (roomId) {
return (await Messaging.getRoomData(roomId)).groupChat;
const count = await Messaging.getUserCountInRoom(roomId);
return count > 2;
};

async function updateUserCount(roomIds) {
Expand Down Expand Up @@ -523,7 +522,7 @@ module.exports = function (Messaging) {
room.isOwner = isOwner;
room.users = users;
room.canReply = canReply;
room.groupChat = room.hasOwnProperty('groupChat') ? room.groupChat : users.length > 2;
room.groupChat = users.length > 2;
room.icon = Messaging.getRoomIcon(room);
room.usernames = Messaging.generateUsernames(room, uid);
room.chatWithMessage = await Messaging.generateChatWithMessage(room, uid, settings.userLang);
Expand Down
10 changes: 10 additions & 0 deletions src/notifications.js
Expand Up @@ -374,6 +374,7 @@ Notifications.merge = async function (notifications) {
'notifications:user_posted_to',
'notifications:user_flagged_post_in',
'notifications:user_flagged_user',
'new-chat',
'notifications:user_posted_in_public_room',
'new_register',
'post-queue',
Expand Down Expand Up @@ -417,6 +418,15 @@ Notifications.merge = async function (notifications) {
}
const notifObj = notifications[modifyIndex];
switch (mergeId) {
case 'new-chat': {
const { roomId, roomName, type, user } = set[0];
const isGroupChat = type === 'new-group-chat';
notifObj.bodyShort = isGroupChat || (roomName !== `[[modules:chat.room-id, ${roomId}]]`) ?
`[[notifications:new_messages_in, ${set.length}, ${roomName}]]` :
`[[notifications:new_messages_from, ${set.length}, ${user.displayname}]]`;
break;
}

case 'notifications:user_posted_in_public_room': {
const usernames = _.uniq(set.map(notifObj => notifObj && notifObj.user && notifObj.user.displayname));
if (usernames.length === 2 || usernames.length === 3) {
Expand Down

0 comments on commit 3ba371f

Please sign in to comment.