From ccc3b6ffecb6026483eb8f86bd72ac2882e160c6 Mon Sep 17 00:00:00 2001 From: Gronod Date: Tue, 19 May 2026 21:35:26 +0100 Subject: [PATCH] fix(status): Check actual webhook config, show enabled even with 0 events The status panel was showing webhooks as disabled (null) when no events had been received yet. Now it checks Sonarr/Radarr API to see if the Sofarr webhook notification is actually configured. - Added checkWebhookConfigured() to verify webhook exists in Sonarr/Radarr - Shows 'enabled: true' with 0 events when webhook is configured - Only shows null when webhook is not configured at all --- server/routes/dashboard.js | 44 +++++++++++++++++++++++++++++++++----- 1 file changed, 39 insertions(+), 5 deletions(-) diff --git a/server/routes/dashboard.js b/server/routes/dashboard.js index 12cba6e..a3253da 100644 --- a/server/routes/dashboard.js +++ b/server/routes/dashboard.js @@ -772,7 +772,7 @@ router.get('/user-summary', requireAuth, async (req, res) => { }); // Admin-only status page with cache stats -router.get('/status', requireAuth, (req, res) => { +router.get('/status', requireAuth, async (req, res) => { try { const user = req.user; if (!user.isAdmin) { @@ -786,6 +786,32 @@ router.get('/status', requireAuth, (req, res) => { const { getGlobalWebhookMetrics } = require('../utils/cache'); const webhookMetrics = getGlobalWebhookMetrics(); + // Check if Sofarr webhook is configured in Sonarr/Radarr + async function checkWebhookConfigured(instance, type) { + try { + const response = await axios.get(`${instance.url}/api/v3/notification`, { + headers: { 'X-Api-Key': instance.apiKey }, + timeout: 5000 + }); + const notifications = response.data || []; + return notifications.some(n => n.name === 'Sofarr' && n.implementation === 'Webhook'); + } catch (err) { + console.log(`[Status] Failed to check ${type} webhook config: ${err.message}`); + return false; + } + } + + // Check webhook configuration for each service + const sonarrInstances = getSonarrInstances(); + const radarrInstances = getRadarrInstances(); + + const sonarrWebhookConfigured = sonarrInstances.length > 0 + ? await checkWebhookConfigured(sonarrInstances[0], 'Sonarr') + : false; + const radarrWebhookConfigured = radarrInstances.length > 0 + ? await checkWebhookConfigured(radarrInstances[0], 'Radarr') + : false; + // Find Sonarr and Radarr metrics from instances const sonarrMetrics = {}; const radarrMetrics = {}; @@ -798,9 +824,17 @@ router.get('/status', requireAuth, (req, res) => { } // Aggregate metrics for each service - const aggregateMetrics = (metricsMap) => { + const aggregateMetrics = (metricsMap, configured) => { const values = Object.values(metricsMap); - if (values.length === 0) return null; + if (values.length === 0) { + // Return default metrics if configured but no events yet + return configured ? { + enabled: true, + eventsReceived: 0, + pollsSkipped: 0, + lastEvent: null + } : null; + } return { enabled: true, eventsReceived: values.reduce((sum, m) => sum + (m.eventsReceived || 0), 0), @@ -827,8 +861,8 @@ router.get('/status', requireAuth, (req, res) => { cache: cacheStats, clients: getActiveClients(), webhooks: { - sonarr: aggregateMetrics(sonarrMetrics), - radarr: aggregateMetrics(radarrMetrics) + sonarr: aggregateMetrics(sonarrMetrics, sonarrWebhookConfigured), + radarr: aggregateMetrics(radarrMetrics, radarrWebhookConfigured) } }); } catch (err) {