const uuidv4 = require("uuid").v4 class Notification { constructor(notification = null) { this.id = null this.libraryId = null this.eventName = '' this.urls = [] this.titleTemplate = '' this.bodyTemplate = '' this.type = 'info' this.enabled = false this.lastFiredAt = null this.lastAttemptFailed = false this.numConsecutiveFailedAttempts = 0 this.numTimesFired = 0 this.createdAt = null if (notification) { this.construct(notification) } } construct(notification) { this.id = notification.id this.libraryId = notification.libraryId || null this.eventName = notification.eventName this.urls = notification.urls || [] this.titleTemplate = notification.titleTemplate || '' this.bodyTemplate = notification.bodyTemplate || '' this.type = notification.type || 'info' this.enabled = !!notification.enabled this.lastFiredAt = notification.lastFiredAt || null this.lastAttemptFailed = !!notification.lastAttemptFailed this.numConsecutiveFailedAttempts = notification.numConsecutiveFailedAttempts || 0 this.numTimesFired = notification.numTimesFired || 0 this.createdAt = notification.createdAt } toJSON() { return { id: this.id, libraryId: this.libraryId, eventName: this.eventName, urls: this.urls, titleTemplate: this.titleTemplate, bodyTemplate: this.bodyTemplate, enabled: this.enabled, type: this.type, lastFiredAt: this.lastFiredAt, lastAttemptFailed: this.lastAttemptFailed, numConsecutiveFailedAttempts: this.numConsecutiveFailedAttempts, numTimesFired: this.numTimesFired, createdAt: this.createdAt } } setData(payload) { this.id = uuidv4() this.libraryId = payload.libraryId || null this.eventName = payload.eventName this.urls = payload.urls this.titleTemplate = payload.titleTemplate this.bodyTemplate = payload.bodyTemplate this.enabled = !!payload.enabled this.type = payload.type || null this.createdAt = Date.now() } update(payload) { if (!this.enabled && payload.enabled) { // Reset this.lastFiredAt = null this.lastAttemptFailed = false this.numConsecutiveFailedAttempts = 0 } const keysToUpdate = ['libraryId', 'eventName', 'urls', 'titleTemplate', 'bodyTemplate', 'enabled', 'type'] var hasUpdated = false for (const key of keysToUpdate) { if (payload[key] !== undefined) { if (key === 'urls') { if (payload[key].join(',') !== this.urls.join(',')) { this.urls = [...payload[key]] hasUpdated = true } } else if (payload[key] !== this[key]) { this[key] = payload[key] hasUpdated = true } } } return hasUpdated } updateNotificationFired(success) { this.lastFiredAt = Date.now() this.lastAttemptFailed = !success this.numConsecutiveFailedAttempts = success ? 0 : this.numConsecutiveFailedAttempts + 1 this.numTimesFired++ } replaceVariablesInTemplate(templateText, data) { const ptrn = /{{ ?([a-zA-Z]+) ?}}/mg var match var updatedTemplate = templateText while ((match = ptrn.exec(templateText)) != null) { if (data[match[1]]) { updatedTemplate = updatedTemplate.replace(match[0], data[match[1]]) } } return updatedTemplate } parseTitleTemplate(data) { return this.replaceVariablesInTemplate(this.titleTemplate, data) } parseBodyTemplate(data) { return this.replaceVariablesInTemplate(this.bodyTemplate, data) } getApprisePayload(data) { return { urls: this.urls, title: this.parseTitleTemplate(data), body: this.parseBodyTemplate(data) } } } module.exports = Notification