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;