From b85ff61de6c7dcf30a58ea22e67f3db07c2bfd49 Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Tue, 16 Sep 2014 13:27:26 -0400 Subject: [PATCH] refactored chat notification system to wait a bit before sending notif/email, closes #2098 --- public/language/en_GB/email.json | 7 ++++- src/emailer.js | 4 +-- src/messaging.js | 53 ++++++++++++++++++++++++++++++-- src/notifications.js | 1 + src/socket.io/modules.js | 19 +----------- 5 files changed, 61 insertions(+), 23 deletions(-) diff --git a/public/language/en_GB/email.json b/public/language/en_GB/email.json index 87d3a5be39..bfcf159de8 100644 --- a/public/language/en_GB/email.json +++ b/public/language/en_GB/email.json @@ -17,10 +17,15 @@ "digest.latest_topics": "Latest topics from %1", "digest.cta": "Click here to visit %1", "digest.unsub.info": "This digest was sent to you due to your subscription settings.", - "digest.unsub.cta": "Click here to alter those settings", "digest.daily.no_topics": "There have been no active topics in the past day", + "notif.chat.subject": "New chat message received from %1", + "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.", + "test.text1": "This is a test email to verify that the emailer is set up correctly for your NodeBB.", + "unsub.cta": "Click here to alter those settings", + "closing": "Thanks!" } \ No newline at end of file diff --git a/src/emailer.js b/src/emailer.js index 7d3d281add..362309f7d7 100644 --- a/src/emailer.js +++ b/src/emailer.js @@ -31,7 +31,7 @@ Emailer.send = function(template, uid, params) { email: async.apply(User.getUserField, uid, 'email'), settings: async.apply(User.getSettings, uid) }, function(err, results) { - async.map([results.html, results.plaintext], function(raw, next) { + async.map([results.html, results.plaintext, params.subject], function(raw, next) { translator.translate(raw, results.settings.language || meta.config.defaultLang || 'en_GB', function(translated) { next(undefined, translated); }); @@ -45,7 +45,7 @@ Emailer.send = function(template, uid, params) { Plugins.fireHook('action:email.send', { to: results.email, from: Meta.config['email:from'] || 'no-reply@localhost.lan', - subject: params.subject, + subject: translated[2], html: translated[0], plaintext: translated[1], template: template, diff --git a/src/messaging.js b/src/messaging.js index 16a56dd23e..bbea385473 100644 --- a/src/messaging.js +++ b/src/messaging.js @@ -2,16 +2,19 @@ var db = require('./database'), async = require('async'), + nconf = require('nconf'), winston = require('winston'), user = require('./user'), plugins = require('./plugins'), meta = require('./meta'), utils = require('../public/src/utils'), notifications = require('./notifications'), - userNotifications = require('./user/notifications'); - + userNotifications = require('./user/notifications'), + websockets = require('./socket.io'), + emailer = require('./emailer'); (function(Messaging) { + Messaging.notifyQueue = {}; // Only used to notify a user of a new chat message, see Messaging.notifyUser function sortUids(fromuid, touid) { return [fromuid, touid].sort(); @@ -336,6 +339,52 @@ var db = require('./database'), } return (matrix[b.length][a.length] / b.length < 0.1); + }; + + Messaging.notifyUser = function(fromuid, touid, messageObj) { + var queueObj = Messaging.notifyQueue[fromuid + ':' + touid]; + if (queueObj) { + queueObj.message.content += '\n' + messageObj.content; + clearTimeout(queueObj.timeout); + } else { + queueObj = Messaging.notifyQueue[fromuid + ':' + touid] = { + message: messageObj + }; + } + + queueObj.timeout = setTimeout(function() { + sendNotifications(fromuid, touid, queueObj.message, function(err) { + if (!err) { + delete Messaging.notifyQueue[fromuid + ':' + touid]; + } + }); + }, 1000*60); // wait 60s before sending + }; + + function sendNotifications(fromuid, touid, messageObj, callback) { + // todo #1798 -- this should check if the user is in room `chat_{uidA}_{uidB}` instead, see `Sockets.uidInRoom(uid, room);` + if (!websockets.isUserOnline(touid)) { + notifications.create({ + bodyShort: '[[notifications:new_message_from, ' + messageObj.fromUser.username + ']]', + bodyLong: messageObj.content, + path: nconf.get('relative_path') + '/chats/' + utils.slugify(messageObj.fromUser.username), + nid: 'chat_' + fromuid + '_' + touid, + from: fromuid + }, function(err, notification) { + if (!err && notification) { + notifications.push(notification, [touid], callback); + } + }); + + emailer.send('notif_chat', touid, { + subject: '[[email:notif.chat.subject, ' + messageObj.fromUser.username + ']]', + username: messageObj.toUser.username, + summary: '[[notifications:new_message_from, ' + messageObj.fromUser.username + ']]', + message: messageObj, + site_title: meta.config.site_title || 'NodeBB', + url: nconf.get('url') + '/chats/' + utils.slugify(messageObj.fromUser.username) + }); + } } }(exports)); diff --git a/src/notifications.js b/src/notifications.js index b1ac1639f6..0e38a3eec7 100644 --- a/src/notifications.js +++ b/src/notifications.js @@ -146,6 +146,7 @@ var async = require('async'), db.sortedSetsRemoveRangeByScore(readKeys, 0, oneWeekAgo); plugins.fireHook('action:notification.pushed', {notification: notification, uids: uids}); + callback(); for(var i=0; i