mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2025-07-23 16:58:13 +02:00
.devcontainer
.github
.vscode
build
client
images
server
controllers
finders
libs
managers
AbMergeManager.js
ApiCacheManager.js
AudioMetadataManager.js
BackupManager.js
BinaryManager.js
CacheManager.js
CoverManager.js
CronManager.js
EmailManager.js
LogManager.js
NotificationManager.js
PlaybackSessionManager.js
PodcastManager.js
RssFeedManager.js
TaskManager.js
models
objects
providers
routers
scanner
utils
Auth.js
Database.js
Logger.js
Server.js
SocketAuthority.js
Watcher.js
test
.dockerignore
.gitattributes
.gitignore
Dockerfile
LICENSE
custom-metadata-provider-specification.yaml
docker-compose.yml
docker-template.xml
index.js
package-lock.json
package.json
prod.js
readme.md
119 lines
4.9 KiB
JavaScript
119 lines
4.9 KiB
JavaScript
const axios = require('axios')
|
|
const Logger = require("../Logger")
|
|
const SocketAuthority = require('../SocketAuthority')
|
|
const Database = require('../Database')
|
|
const { notificationData } = require('../utils/notifications')
|
|
|
|
class NotificationManager {
|
|
constructor() {
|
|
this.sendingNotification = false
|
|
this.notificationQueue = []
|
|
}
|
|
|
|
getData() {
|
|
return notificationData
|
|
}
|
|
|
|
async onPodcastEpisodeDownloaded(libraryItem, episode) {
|
|
if (!Database.notificationSettings.isUseable) return
|
|
|
|
Logger.debug(`[NotificationManager] onPodcastEpisodeDownloaded: Episode "${episode.title}" for podcast ${libraryItem.media.metadata.title}`)
|
|
const library = await Database.libraryModel.getOldById(libraryItem.libraryId)
|
|
const eventData = {
|
|
libraryItemId: libraryItem.id,
|
|
libraryId: libraryItem.libraryId,
|
|
libraryName: library?.name || 'Unknown',
|
|
mediaTags: (libraryItem.media.tags || []).join(', '),
|
|
podcastTitle: libraryItem.media.metadata.title,
|
|
podcastAuthor: libraryItem.media.metadata.author || '',
|
|
podcastDescription: libraryItem.media.metadata.description || '',
|
|
podcastGenres: (libraryItem.media.metadata.genres || []).join(', '),
|
|
episodeId: episode.id,
|
|
episodeTitle: episode.title,
|
|
episodeSubtitle: episode.subtitle || '',
|
|
episodeDescription: episode.description || ''
|
|
}
|
|
this.triggerNotification('onPodcastEpisodeDownloaded', eventData)
|
|
}
|
|
|
|
onTest() {
|
|
this.triggerNotification('onTest')
|
|
}
|
|
|
|
async triggerNotification(eventName, eventData, intentionallyFail = false) {
|
|
if (!Database.notificationSettings.isUseable) return
|
|
|
|
// Will queue the notification if sendingNotification and queue is not full
|
|
if (!this.checkTriggerNotification(eventName, eventData)) return
|
|
|
|
const notifications = Database.notificationSettings.getActiveNotificationsForEvent(eventName)
|
|
for (const notification of notifications) {
|
|
Logger.debug(`[NotificationManager] triggerNotification: Sending ${eventName} notification ${notification.id}`)
|
|
const success = intentionallyFail ? false : await this.sendNotification(notification, eventData)
|
|
|
|
notification.updateNotificationFired(success)
|
|
if (!success) { // Failed notification
|
|
if (notification.numConsecutiveFailedAttempts >= Database.notificationSettings.maxFailedAttempts) {
|
|
Logger.error(`[NotificationManager] triggerNotification: ${notification.eventName}/${notification.id} reached max failed attempts`)
|
|
notification.enabled = false
|
|
} else {
|
|
Logger.error(`[NotificationManager] triggerNotification: ${notification.eventName}/${notification.id} ${notification.numConsecutiveFailedAttempts} failed attempts`)
|
|
}
|
|
}
|
|
}
|
|
|
|
await Database.updateSetting(Database.notificationSettings)
|
|
SocketAuthority.emitter('notifications_updated', Database.notificationSettings.toJSON())
|
|
|
|
this.notificationFinished()
|
|
}
|
|
|
|
// Return TRUE if notification should be triggered now
|
|
checkTriggerNotification(eventName, eventData) {
|
|
if (this.sendingNotification) {
|
|
if (this.notificationQueue.length >= Database.notificationSettings.maxNotificationQueue) {
|
|
Logger.warn(`[NotificationManager] Notification queue is full - ignoring event ${eventName}`)
|
|
} else {
|
|
Logger.debug(`[NotificationManager] Queueing notification ${eventName} (Queue size: ${this.notificationQueue.length})`)
|
|
this.notificationQueue.push({ eventName, eventData })
|
|
}
|
|
return false
|
|
}
|
|
this.sendingNotification = true
|
|
return true
|
|
}
|
|
|
|
notificationFinished() {
|
|
// Delay between events then run next notification in queue
|
|
setTimeout(() => {
|
|
this.sendingNotification = false
|
|
if (this.notificationQueue.length) { // Send next notification in queue
|
|
const nextNotificationEvent = this.notificationQueue.shift()
|
|
this.triggerNotification(nextNotificationEvent.eventName, nextNotificationEvent.eventData)
|
|
}
|
|
}, Database.notificationSettings.notificationDelay)
|
|
}
|
|
|
|
sendTestNotification(notification) {
|
|
const eventData = notificationData.events.find(e => e.name === notification.eventName)
|
|
if (!eventData) {
|
|
Logger.error(`[NotificationManager] sendTestNotification: Event not found ${notification.eventName}`)
|
|
return false
|
|
}
|
|
|
|
return this.sendNotification(notification, eventData.testData)
|
|
}
|
|
|
|
sendNotification(notification, eventData) {
|
|
const payload = notification.getApprisePayload(eventData)
|
|
return axios.post(Database.notificationSettings.appriseApiUrl, payload, { timeout: 6000 }).then((response) => {
|
|
Logger.debug(`[NotificationManager] sendNotification: ${notification.eventName}/${notification.id} response=`, response.data)
|
|
return true
|
|
}).catch((error) => {
|
|
Logger.error(`[NotificationManager] sendNotification: ${notification.eventName}/${notification.id} error=`, error)
|
|
return false
|
|
})
|
|
}
|
|
}
|
|
module.exports = NotificationManager
|