mirror of
				https://github.com/NodeBB/NodeBB.git
				synced 2025-10-31 11:05:54 +01:00 
			
		
		
		
	refactored chat notification system to wait a bit before sending notif/email, closes #2098
This commit is contained in:
		| @@ -17,10 +17,15 @@ | |||||||
| 	"digest.latest_topics": "Latest topics from %1", | 	"digest.latest_topics": "Latest topics from %1", | ||||||
| 	"digest.cta": "Click here to visit %1", | 	"digest.cta": "Click here to visit %1", | ||||||
| 	"digest.unsub.info": "This digest was sent to you due to your subscription settings.", | 	"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", | 	"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.", | 	"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!" | 	"closing": "Thanks!" | ||||||
| } | } | ||||||
| @@ -31,7 +31,7 @@ Emailer.send = function(template, uid, params) { | |||||||
| 		email: async.apply(User.getUserField, uid, 'email'), | 		email: async.apply(User.getUserField, uid, 'email'), | ||||||
| 		settings: async.apply(User.getSettings, uid) | 		settings: async.apply(User.getSettings, uid) | ||||||
| 	}, function(err, results) { | 	}, 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) { | 			translator.translate(raw, results.settings.language || meta.config.defaultLang || 'en_GB', function(translated) { | ||||||
| 				next(undefined, translated); | 				next(undefined, translated); | ||||||
| 			}); | 			}); | ||||||
| @@ -45,7 +45,7 @@ Emailer.send = function(template, uid, params) { | |||||||
| 			Plugins.fireHook('action:email.send', { | 			Plugins.fireHook('action:email.send', { | ||||||
| 				to: results.email, | 				to: results.email, | ||||||
| 				from: Meta.config['email:from'] || 'no-reply@localhost.lan', | 				from: Meta.config['email:from'] || 'no-reply@localhost.lan', | ||||||
| 				subject: params.subject, | 				subject: translated[2], | ||||||
| 				html: translated[0], | 				html: translated[0], | ||||||
| 				plaintext: translated[1], | 				plaintext: translated[1], | ||||||
| 				template: template, | 				template: template, | ||||||
|   | |||||||
| @@ -2,16 +2,19 @@ | |||||||
|  |  | ||||||
| var db = require('./database'), | var db = require('./database'), | ||||||
| 	async = require('async'), | 	async = require('async'), | ||||||
|  | 	nconf = require('nconf'), | ||||||
| 	winston = require('winston'), | 	winston = require('winston'), | ||||||
| 	user = require('./user'), | 	user = require('./user'), | ||||||
| 	plugins = require('./plugins'), | 	plugins = require('./plugins'), | ||||||
| 	meta = require('./meta'), | 	meta = require('./meta'), | ||||||
| 	utils = require('../public/src/utils'), | 	utils = require('../public/src/utils'), | ||||||
| 	notifications = require('./notifications'), | 	notifications = require('./notifications'), | ||||||
| 	userNotifications = require('./user/notifications'); | 	userNotifications = require('./user/notifications'), | ||||||
|  | 	websockets = require('./socket.io'), | ||||||
|  | 	emailer = require('./emailer'); | ||||||
|  |  | ||||||
| (function(Messaging) { | (function(Messaging) { | ||||||
|  | 	Messaging.notifyQueue = {};	// Only used to notify a user of a new chat message, see Messaging.notifyUser | ||||||
|  |  | ||||||
| 	function sortUids(fromuid, touid) { | 	function sortUids(fromuid, touid) { | ||||||
| 		return [fromuid, touid].sort(); | 		return [fromuid, touid].sort(); | ||||||
| @@ -336,6 +339,52 @@ var db = require('./database'), | |||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		return (matrix[b.length][a.length] / b.length < 0.1); | 		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)); | }(exports)); | ||||||
|   | |||||||
| @@ -146,6 +146,7 @@ var async = require('async'), | |||||||
| 			db.sortedSetsRemoveRangeByScore(readKeys, 0, oneWeekAgo); | 			db.sortedSetsRemoveRangeByScore(readKeys, 0, oneWeekAgo); | ||||||
|  |  | ||||||
| 			plugins.fireHook('action:notification.pushed', {notification: notification, uids: uids}); | 			plugins.fireHook('action:notification.pushed', {notification: notification, uids: uids}); | ||||||
|  | 			callback(); | ||||||
|  |  | ||||||
| 			for(var i=0; i<uids.length; ++i) { | 			for(var i=0; i<uids.length; ++i) { | ||||||
| 				websockets.in('uid_' + uids[i]).emit('event:new_notification', notification); | 				websockets.in('uid_' + uids[i]).emit('event:new_notification', notification); | ||||||
|   | |||||||
| @@ -197,7 +197,7 @@ SocketModules.chats.send = function(socket, data, callback) { | |||||||
| 			return callback(err); | 			return callback(err); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		sendChatNotification(socket.uid, touid, message); | 		Messaging.notifyUser(socket.uid, touid, message); | ||||||
|  |  | ||||||
| 		// Recipient | 		// Recipient | ||||||
| 		SocketModules.chats.pushUnreadCount(touid); | 		SocketModules.chats.pushUnreadCount(touid); | ||||||
| @@ -217,23 +217,6 @@ SocketModules.chats.send = function(socket, data, callback) { | |||||||
| 	}); | 	}); | ||||||
| }; | }; | ||||||
|  |  | ||||||
| function sendChatNotification(fromuid, touid, messageObj) { |  | ||||||
| 	// todo #1798 -- this should check if the user is in room `chat_{uidA}_{uidB}` instead, see `Sockets.uidInRoom(uid, room);` |  | ||||||
| 	if (!module.parent.exports.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]); |  | ||||||
| 			} |  | ||||||
| 		}); |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| SocketModules.chats.pushUnreadCount = function(uid) { | SocketModules.chats.pushUnreadCount = function(uid) { | ||||||
| 	Messaging.getUnreadCount(uid, function(err, unreadCount) { | 	Messaging.getUnreadCount(uid, function(err, unreadCount) { | ||||||
| 		if (err) { | 		if (err) { | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user