diff --git a/migrations/042-add-site-is-notified-field.js b/migrations/042-add-site-is-notified-field.js new file mode 100755 index 00000000..fa2b3f76 --- /dev/null +++ b/migrations/042-add-site-is-notified-field.js @@ -0,0 +1,15 @@ +let db = require('../src/db').sequelize; + +module.exports = { + up: function() { + + try { + return db.query(` + ALTER TABLE sites ADD adminIsNotified DATETIME NULL DEFAULT NULL AFTER areaId; + `); + } catch(e) { + return true; + } + + } +} diff --git a/src/cron/send_site_issues_notifications.js b/src/cron/send_site_issues_notifications.js index b72df737..b05759e9 100755 --- a/src/cron/send_site_issues_notifications.js +++ b/src/cron/send_site_issues_notifications.js @@ -31,8 +31,10 @@ module.exports = { // for each site for (let i=0; i < shouldHaveEndedButAreNot.length; i++) { let site = shouldHaveEndedButAreNot[i]; - if (!notificationsToBeSent[ site.id ]) notificationsToBeSent[ site.id ] = { site, messages: [] }; - notificationsToBeSent[ site.id ].messages.push(`Site ${ site.title } (${ site.domain }) has an endDate in the past but projectHasEnded is not set.`); + if (!site.adminIsNotified || site.adminIsNotified.getTime() < Date.now() - 23 * 60 * 60 * 1000) { + if (!notificationsToBeSent[ site.id ]) notificationsToBeSent[ site.id ] = { site, messages: [] }; + notificationsToBeSent[ site.id ].messages.push(`Site ${ site.title } (${ site.domain }) has an endDate in the past but projectHasEnded is not set.`); + } } // sites that have ended but are not anonymized @@ -42,22 +44,38 @@ module.exports = { // for each site for (let i=0; i < endedButNotAnonymized.length; i++) { let site = endedButNotAnonymized[i]; - if (!notificationsToBeSent[ site.id ]) notificationsToBeSent[ site.id ] = { site, messages: [] }; - notificationsToBeSent[ site.id ].messages.push(`Project ${ site.title } (${ site.domain }) has ended but is not yet anonymized.`); + if (!site.adminIsNotified || site.adminIsNotified.getTime() < Date.now() - 23 * 60 * 60 * 1000) { + if (!notificationsToBeSent[ site.id ]) notificationsToBeSent[ site.id ] = { site, messages: [] }; + notificationsToBeSent[ site.id ].messages.push(`Project ${ site.title } (${ site.domain }) has ended but is not yet anonymized.`); + } } - // send notifications + // aggregate notifications to the same address + let aggregatedNotificationsToBeSent = []; Object.keys(notificationsToBeSent).forEach(id => { let target = notificationsToBeSent[ id ]; - let data = { - from: target.site.config.notifications.fromAddress, - to: target.site.config.notifications.siteadminAddress, - subject: 'Sites with issues', - template: target.messages.join('\r\n'), - }; - Notifications.sendMessage({ site: target.site, data }); + let toAddress = target.site.config.notifications.siteadminAddress || target.site.config.notifications.projectmanagerAddress; + if ( aggregatedNotificationsToBeSent[ toAddress ] ) { + aggregatedNotificationsToBeSent[ toAddress ].data.template += '
\r\n' + target.messages.join('
\r\n'); + } else { + aggregatedNotificationsToBeSent[ toAddress ] = { + site: target.site, + data: { + from: target.site.config.notifications.fromAddress, + to: toAddress, + subject: 'Sites with issues', + template: target.messages.join('
\r\n'), + } + }; + } + target.site.update({ adminIsNotified: new Date() }) }); - + + // send notifications + Object.values(aggregatedNotificationsToBeSent).forEach(target => { + Notifications.sendMessage({ site: target.site, data: target.data }); + }) + return next(); } catch (err) { diff --git a/src/models/Site.js b/src/models/Site.js index f9cfb8e0..d8245fb3 100755 --- a/src/models/Site.js +++ b/src/models/Site.js @@ -67,7 +67,13 @@ module.exports = function (db, sequelize, DataTypes) { areaId: { type: DataTypes.INTEGER, allowNull: true, - } + }, + + adminIsNotified: { + type: DataTypes.DATE, + allowNull: true, + default: null, + }, }, {