1
0
mirror of https://github.com/advplyr/audiobookshelf.git synced 2025-07-23 16:58:13 +02:00
Files
.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
audiobookshelf/server/managers/NotificationManager.js
2023-08-20 13:34:03 -05:00

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