NotificationLatch/src/notification/facade.js

102 lines
2.7 KiB
JavaScript

class NotificationFacade
{
constructor(logger, dateTimeProvider, transportProvider, subjectParser, notificationRepository, config)
{
this.logger = logger;
this.dateTimeProvider = dateTimeProvider;
this.transportProvider = transportProvider;
this.subjectParser = subjectParser;
this.notificationRepository = notificationRepository;
this.contacts = config.contacts.filter(contact =>
{
if (transportProvider.byType(contact.type) === null)
{
logger.error(`Unknown transport type '${contact.type}' for contact '${contact.description}', skipping contact`)
return false;
}
return true;
});
}
async postNotification(subject, message, priority)
{
var parsedSubject = this.subjectParser.parse(subject);
const token = await this.notificationRepository.storeNotification(parsedSubject.id, parsedSubject.title);
if (token === null)
return;
this._sendNotification({
id: parsedSubject.id,
token: token,
title: parsedSubject.title,
message: message,
priority: priority,
sound: parsedSubject.sound,
timestamp: this.dateTimeProvider.unixTimestamp(),
url: 'https://www.hierhaduwurlkunnenstaan.nl/'
});
}
async resetNotification(token)
{
await this.notificationRepository.resetNotification(token);
}
_sendNotification(notification)
{
this.contacts.forEach(contact =>
{
const transport = this.transportProvider.byType(contact.type);
this._retryableSend(transport, contact, notification);
});
}
_delay(ms)
{
return new Promise(resolve => setTimeout(resolve, ms));
}
async _retryableSend(transport, contact, notification)
{
let attempt = 1;
const retryInterval = contact.retryIntervalSeconds || 0;
const maxAttempts = contact.maxAttempts || 1;
while (true)
{
try
{
this.logger.info(`Sending notification '${notification.id}' with token '${notification.token}' to '${contact.description}' (attempt ${attempt})`);
await transport.send(contact, notification);
this.logger.info(`Notification '${notification.id}' succesfully sent to '${contact.description}'`);
return;
}
catch (err)
{
if (attempt >= maxAttempts)
{
this.logger.info(`Error while sending notification '${notification.id}' to '${contact.description}', max attempts reached: ${err}`);
return;
}
this.logger.info(`Error while sending notification '${notification.id}' to '${contact.description}', retrying in ${retryInterval} seconds: ${err}`);
await this._delay(retryInterval * 1000);
attempt++;
}
}
}
}
module.exports = NotificationFacade;