From 2b8a7c73acbcb9f5bf4721adc58ee810cd276f53 Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Tue, 18 Mar 2014 15:35:48 -0400 Subject: [PATCH] daily digest emails! resolved #326 --- app.js | 3 -- src/user.js | 2 +- src/user/jobs.js | 66 +++++++++++++++++++++++++++++++++++++++ src/user/notifications.js | 22 +++++++++---- src/webserver.js | 4 +++ 5 files changed, 87 insertions(+), 10 deletions(-) create mode 100644 src/user/jobs.js diff --git a/app.js b/app.js index 9878c22786..1836539edc 100644 --- a/app.js +++ b/app.js @@ -123,7 +123,6 @@ function start() { webserver = require('./src/webserver'), sockets = require('./src/socket.io'), plugins = require('./src/plugins'), - notifications = require('./src/notifications'), upgrade = require('./src/upgrade'); templates.setGlobal('relative_path', nconf.get('relative_path')); @@ -141,8 +140,6 @@ function start() { webserver.init(); }); - notifications.init(); - process.on('SIGTERM', shutdown); process.on('SIGINT', shutdown); process.on('SIGHUP', restart); diff --git a/src/user.js b/src/user.js index 32bba3d6ce..4fed66e30f 100644 --- a/src/user.js +++ b/src/user.js @@ -31,7 +31,7 @@ var bcrypt = require('bcryptjs'), require('./user/delete')(User); require('./user/settings')(User); require('./user/search')(User); - + require('./user/jobs')(User); User.getUserField = function(uid, field, callback) { db.getObjectField('user:' + uid, field, callback); diff --git a/src/user/jobs.js b/src/user/jobs.js new file mode 100644 index 0000000000..bcccb8ae6e --- /dev/null +++ b/src/user/jobs.js @@ -0,0 +1,66 @@ + +'use strict'; + +var db = require('../database'), + async = require('async'), + winston = require('winston'), + cronJob = require('cron').CronJob, + nconf = require('nconf'), + + user = require('../user'), + UserNotifications = require('./notifications'), + topics = require('../topics'), + emailer = require('../emailer'), + meta = require('../meta'); + +module.exports = function(User) { + User.startJobs = function() { + winston.info('[user.startJobs] Registering User Jobs'); + + new cronJob('0 0 17 * * *', function() { + User.sendDailyDigests(); + }, null, true); + }; + + User.sendDailyDigests = function() { + async.parallel({ + recent: function(next) { + topics.getLatestTopics(0, 0, 10, 'day', next); + }, + uids: function(next) { + db.getSortedSetRange('users:joindate', 0, -1, next); + } + }, function(err, data) { + var now = new Date(); + + async.each(data.uids, function(uid, next) { + UserNotifications.getDailyUnread(uid, function(err, notifications) { + if (!err && notifications && notifications.length) { + user.getUserField(uid, 'username', function(err, username) { + // Send daily digest email + // winston.info('[user/notifications] Sending Daily Digest to uid ' + uid); + emailer.send('dailydigest', uid, { + subject: '[' + meta.config.title + '] Daily Digest for ' + now.getFullYear()+ '/' + (now.getMonth()+1) + '/' + now.getDate(), + username: username, + url: nconf.get('url'), + site_title: meta.config.title, + notifications: notifications, + recent: data.recent.topics + }); + }); + } + + next(err); + }); + }, function(err) { + // When finished... + if (!err) { + winston.info('[user/notifications] Daily Digests sent!'); + } else { + winston.error('[user/notifications] Could not send daily digests: ' + err.message); + } + }); + }); + }; +}; + diff --git a/src/user/notifications.js b/src/user/notifications.js index 088caa5760..df3096b8e8 100644 --- a/src/user/notifications.js +++ b/src/user/notifications.js @@ -5,14 +5,13 @@ var async = require('async'), nconf = require('nconf'), winston = require('winston'), - user = require('./../user'), - utils = require('./../../public/src/utils'), - db = require('./../database'), - notifications = require('./../notifications'), - topics = require('./../topics'); + user = require('../user'), + utils = require('../../public/src/utils'), + db = require('../database'), + notifications = require('../notifications'), + topics = require('../topics'); (function(UserNotifications) { - UserNotifications.get = function(uid, callback) { function getNotifications(set, start, stop, iterator, done) { db.getSortedSetRevRange(set, start, stop, function(err, nids) { @@ -110,7 +109,18 @@ var async = require('async'), }); }); }); + }; + UserNotifications.getDailyUnread = function(uid, callback) { + var now = Date.now(), + yesterday = now - (1000*60*60*24); // Approximate, can be more or less depending on time changes, makes no difference really. + db.getSortedSetRangeByScore(['uid:' + uid + ':notifications:unread', yesterday, now], function(err, nids) { + async.map(nids, function(nid, next) { + notifications.get(nid, uid, function(notif_data) { + next(null, notif_data); + }); + }, callback); + }); }; UserNotifications.getUnreadCount = function(uid, callback) { diff --git a/src/webserver.js b/src/webserver.js index 30ecd20f19..0477cd2ad9 100644 --- a/src/webserver.js +++ b/src/webserver.js @@ -12,6 +12,8 @@ var path = require('path'), db = require('./database'), auth = require('./routes/authentication'), meta = require('./meta'), + user = require('./user'), + notifications = require('./notifications'), logger = require('./logger'), middleware = require('./middleware'), routes = require('./routes'), @@ -34,6 +36,8 @@ if(nconf.get('ssl')) { logger.init(app); auth.registerApp(app); emailer.registerApp(app); + notifications.init(); + user.startJobs(); async.series({ themesData: meta.themes.get,