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,
+ },
}, {