Finally, a script to end the annoying notifications from the Likes topic once and for all...

edit: hopefully the non-forum-breaking, non-everyone-notifying version...

(function () { // monkey-patch socket.onevent to process incoming events before they go to the default event handler(s) var real_onevent = socket.onevent.bind(socket); socket.onevent = function onevent(packet) { var eventName = packet.data[0], n = packet.data[1]; var preventDefault = false; if (eventName == 'event:new_notification') { // automatically mark upvote notifications from the "Likes" thread as read if (/^upvote/.test(n.nid) && n.topicTitle == "The Official Likes Topic") { console.log('Ignoring: ' + n.nid + ', ' + n.bodyShort); socket.emit('notifications.markRead', n.nid, function (e) { if (e) console.log(e); }); preventDefault = true; // prevents NodeBB's event handlers from even seeing this event } // automatically downvote any posts that mention trust_level_3 (BONUS! \o/) if (n.bodyShort.indexOf('[[notifications:user_mentioned_group_in,') == 0 && /:trust_level_3$/.test(n.nid)) { console.log('Downvoting @'+'trust_level_3 mention (post ' + n.pid + (n.user ? ' by @' + n.user.username : '') + ' in "' + n.bodyShort.slice(2, -2).split(', ').slice(3).join(', ') + '")'); socket.emit('posts.downvote', {pid: n.pid, room_id: 'topic_' + n.tid}); } } if (!preventDefault) real_onevent(packet); }; // monkey-patch socket.emit to process sent/received data before it goes to the default event handler(s) var real_emit = socket.emit; socket.emit = function emit(eventName) { var rest = [].slice.call(arguments, 1); var preventDefault = false; if (eventName == 'notifications.get') { // when getting the notification list, filter out upvotes from the Likes topic (and mark them read if they're not) var i = rest.length - 1, orig_fn = rest[i]; if (typeof orig_fn == 'function') { rest[i] = function (err, obj) { if (err == null) { function filter(n) { if (/^upvote/.test(n.nid) && n.topicTitle == "The Official Likes Topic") { if (!n.read) socket.emit('notifications.markRead', n.nid, e => e ? console.log(e) : 0); return false; } return true; } obj.unread = obj.unread.filter(filter); obj.read = obj.read.filter(filter); } orig_fn(err, obj); }; } } if (!preventDefault) real_emit.apply(socket, [eventName].concat(rest)); }; // finally, run through the whole notification list and mark them unread if they're upvotes in the Likes topic (function loadNotifications(start, arr, i) { socket.emit("notifications.loadMore", {after: start || 0}, function (err, obj) { if (obj.notifications.length) { loadNotifications(obj.nextStart, (arr || []).concat(obj.notifications)); } else if (i < 5) { loadNotifications(obj.nextStart, arr, i + 1 || 1); } else { arr.forEach(function (n) { if (!n.read && n.topicTitle == "The Official Likes Topic" && /^upvote/.test(n.nid)) { console.log('Clearing notification:', n.nid, '\n', n.bodyShort); socket.emit('notifications.markRead', n.nid, function (e) { if (e) console.log(e); }); } }); } }); })(); })();