diff --git a/index.js b/index.js
index 1b53082..f2ce9b7 100644
--- a/index.js
+++ b/index.js
@@ -19,6 +19,7 @@ const icons = {
external: '',
};
+const servicesNotifiedAboutOutage = new Set();
let renderedDashboard = null;
async function processOutage({ outage, server, settings, onDateUpdated }) {
@@ -71,64 +72,6 @@ async function processOutage({ outage, server, settings, onDateUpdated }) {
server.error('status: could not save web service heartbeat');
server.error(err);
}
-
- // Send e-mail notification
- if (server.sendEmail && settings.emailSender && settings.emailRecipient) {
- try {
- const date = new Date().toLocaleString('en-GB', {
- dateStyle: 'full',
- timeStyle: 'full',
- timeZone: 'Etc/UTC',
- });
-
- await server.sendEmail({
- sender: settings.emailSender,
- to: settings.emailRecipient,
- subject: `[outage] ${service.name} is down`,
- body: `Hello,
-
-As of ${date} UTC time, the service "${service.name}" does not meet the requirements for being
-considered as working.
-
-Technical information containing the reason for this alert:
-${JSON.stringify(testResult, null, 2)}
-
-Please always check this before taking action. This is an automated message.`,
- });
- }
- catch (err) {
- server.warn('status: could not send endpoint status notification e-mail');
- server.warn(err);
- }
- }
-
- // Draft outage entry
- if (settings.draftOutageEntries) {
- try {
- server
- .storage
- .store('smartyellow/webserviceoutage')
- .insert({
- id: makeId(),
- name: {
- en: `[automatic] Outage for ${service.name.en}`,
- },
- state: 'concept',
- resolved: false,
- services: [ service.id ],
- tags: [ 'automatically created' ],
- notes: [ {
- date: new Date(),
- userId: 'system',
- text: `Automatically created outage. Reason: ${JSON.stringify(testResult, null, 2)}`,
- } ],
- });
- }
- catch (err) {
- server.warn('status: could not automatically draft outage entry');
- server.warn(err);
- }
- }
}
}
@@ -244,16 +187,22 @@ module.exports = {
description: 'Tags that can be assigned to outage messages to categorise them.',
default: {},
},
- emailSender: {
- type: 'string',
- label: 'notification sender',
- description: 'Sender of notifications about service statuses. Format: Name ',
- default: '',
- },
- emailRecipient: {
+ // emailSender: {
+ // type: 'string',
+ // label: 'notification sender',
+ // description: 'Sender of notifications about service statuses. Format: Name ',
+ // default: '',
+ // },
+ // emailRecipient: {
+ // type: 'array',
+ // label: 'notification recipients',
+ // description: 'Recipients of notifications about service statuses. Format: Name ',
+ // default: [],
+ // },
+ smsRecipients: {
type: 'array',
- label: 'notification recipients',
- description: 'Recipients of notifications about service statuses. Format: Name ',
+ label: 'SMS recipients',
+ description: 'Recipients of SMSes about service statuses.',
default: [],
},
draftOutageEntries: {
@@ -404,7 +353,9 @@ module.exports = {
}
// Let other plugins enrich dashboard tiles with custom badges and priorities.
- await server.executePostHooks('pupulateDashboardTiles', { tiles });
+ await server.executePreHooks('populateDashboardTiles', { tiles });
+ await server.executePostHooks('populateDashboardTiles', { tiles });
+ await server.executePostHooks('pupulateDashboardTiles', { tiles }); // backwards compatibility
// Check if there are new outages and report them by ringing a bell on the dashboard.
newOutage = false;
@@ -460,6 +411,51 @@ module.exports = {
});
},
},
+
+ { id: 'sendSmsOnOutage',
+ order: 10,
+ event: 'populateDashboardTiles',
+ purpose: 'Sends an SMS when a tile with priority of 2 or higher is rendered',
+ handler: async ({ tiles }) => {
+ if ((typeof server.sendSMS !== 'function') || (settings.smsRecipients?.length < 1)) {
+ // sendSMS not available, or no recipients.
+ return;
+ }
+
+ const servicesToNotifyAbout = new Set();
+
+ for (const tile of tiles) {
+ if (tile.prio < 2) {
+ // Tile is not of priority 2 or higher. Remove its ID from servicesNotifiedAboutOutage.
+ servicesNotifiedAboutOutage.delete(tile.serviceId);
+ }
+ else {
+ // Tile is of high priority.
+ if (servicesNotifiedAboutOutage.has(tile.serviceId)) {
+ // Already notified about: do nothing.
+ }
+ else {
+ // Not yet notified about: send SMSes.
+ servicesNotifiedAboutOutage.add(tile.serviceId);
+ servicesToNotifyAbout.add(tile.service?.name?.en || tile.serviceId);
+ }
+ }
+ }
+
+ if (servicesToNotifyAbout.size > 0) {
+ // There are new critical tiles; send notification.
+ const string = [ ...servicesToNotifyAbout ].join(', ');
+ server.debug('Sending status SMSes for the following services: ', string);
+ settings.smsRecipients.forEach(phoneNumber => server.sendSMS({
+ to: phoneNumber,
+ msg: 'The following service/s is/are experiencing outage: ' + string,
+ }).catch(err => {
+ server.error('Failed to send status SMS');
+ server.error(err);
+ }));
+ }
+ },
+ },
],
routes: ({ server, settings }) => [