// Copyright (c) 2026 Gordon Bolton. MIT License. import { state } from '../state.js'; import { fetchWebhookStatus as apiFetchWebhookStatus, enableSonarrWebhook as apiEnableSonarrWebhook, enableRadarrWebhook as apiEnableRadarrWebhook, enableOmbiWebhook as apiEnableOmbiWebhook, testSonarrWebhook as apiTestSonarrWebhook, testRadarrWebhook as apiTestRadarrWebhook, testOmbiWebhook as apiTestOmbiWebhook } from '../api.js'; import { formatTimeAgo } from '../utils/format.js'; export function initWebhooks() { const webhooksSection = document.getElementById('webhooks-section'); if (!webhooksSection) return; // Note: visibility is controlled by showDashboard() based on isAdmin document.getElementById('webhooks-header').addEventListener('click', toggleWebhookSection); document.getElementById('enable-sonarr-webhook').addEventListener('click', enableSonarrWebhook); document.getElementById('enable-radarr-webhook').addEventListener('click', enableRadarrWebhook); document.getElementById('enable-ombi-webhook').addEventListener('click', enableOmbiWebhook); document.getElementById('test-sonarr-webhook').addEventListener('click', testSonarrWebhook); document.getElementById('test-radarr-webhook').addEventListener('click', testRadarrWebhook); document.getElementById('test-ombi-webhook').addEventListener('click', testOmbiWebhook); } export function toggleWebhookSection() { state.webhookSectionExpanded = !state.webhookSectionExpanded; const content = document.getElementById('webhooks-content'); const toggle = document.getElementById('webhooks-toggle'); if (state.webhookSectionExpanded) { content.classList.remove('hidden'); } else { content.classList.add('hidden'); } toggle.classList.toggle('expanded', state.webhookSectionExpanded); if (state.webhookSectionExpanded) { fetchWebhookStatus(); } } export async function fetchWebhookStatus() { const loadingEl = document.getElementById('webhook-loading'); loadingEl.classList.remove('hidden'); try { const result = await apiFetchWebhookStatus(); if (result.success) { renderWebhookStatus(); } } catch (err) { console.error('Failed to fetch webhook status:', err); } finally { loadingEl.classList.add('hidden'); } } export function renderWebhookStatus() { // Sonarr const sonarrStatus = document.getElementById('sonarr-status'); const sonarrEnableBtn = document.getElementById('enable-sonarr-webhook'); const sonarrTestBtn = document.getElementById('test-sonarr-webhook'); const sonarrTriggers = document.getElementById('sonarr-triggers'); const sonarrStats = document.getElementById('sonarr-stats'); sonarrStatus.textContent = state.sonarrWebhook.enabled ? '● Enabled' : '○ Disabled'; sonarrStatus.className = 'status-indicator ' + (state.sonarrWebhook.enabled ? 'enabled' : 'disabled'); if (state.sonarrWebhook.enabled) { sonarrEnableBtn.classList.add('hidden'); sonarrTestBtn.classList.remove('hidden'); sonarrTriggers.classList.remove('hidden'); } else { sonarrEnableBtn.classList.remove('hidden'); sonarrTestBtn.classList.add('hidden'); sonarrTriggers.classList.add('hidden'); } if (state.sonarrWebhook.enabled) { document.getElementById('sonarr-onGrab').textContent = state.sonarrWebhook.triggers.onGrab ? '✓' : '✗'; document.getElementById('sonarr-onGrab').className = 'trigger-value ' + (state.sonarrWebhook.triggers.onGrab ? 'active' : 'inactive'); document.getElementById('sonarr-onDownload').textContent = state.sonarrWebhook.triggers.onDownload ? '✓' : '✗'; document.getElementById('sonarr-onDownload').className = 'trigger-value ' + (state.sonarrWebhook.triggers.onDownload ? 'active' : 'inactive'); document.getElementById('sonarr-onImport').textContent = state.sonarrWebhook.triggers.onImport ? '✓' : '✗'; document.getElementById('sonarr-onImport').className = 'trigger-value ' + (state.sonarrWebhook.triggers.onImport ? 'active' : 'inactive'); document.getElementById('sonarr-onUpgrade').textContent = state.sonarrWebhook.triggers.onUpgrade ? '✓' : '✗'; document.getElementById('sonarr-onUpgrade').className = 'trigger-value ' + (state.sonarrWebhook.triggers.onUpgrade ? 'active' : 'inactive'); } if (state.sonarrWebhook.stats) { sonarrStats.classList.remove('hidden'); document.getElementById('sonarr-events').textContent = state.sonarrWebhook.stats.eventsReceived ?? 0; document.getElementById('sonarr-polls').textContent = state.sonarrWebhook.stats.pollsSkipped ?? 0; document.getElementById('sonarr-last').textContent = formatTimeAgo(state.sonarrWebhook.stats.lastWebhookTimestamp); } else { sonarrStats.classList.add('hidden'); } // Radarr const radarrStatus = document.getElementById('radarr-status'); const radarrEnableBtn = document.getElementById('enable-radarr-webhook'); const radarrTestBtn = document.getElementById('test-radarr-webhook'); const radarrTriggers = document.getElementById('radarr-triggers'); const radarrStats = document.getElementById('radarr-stats'); radarrStatus.textContent = state.radarrWebhook.enabled ? '● Enabled' : '○ Disabled'; radarrStatus.className = 'status-indicator ' + (state.radarrWebhook.enabled ? 'enabled' : 'disabled'); if (state.radarrWebhook.enabled) { radarrEnableBtn.classList.add('hidden'); radarrTestBtn.classList.remove('hidden'); radarrTriggers.classList.remove('hidden'); } else { radarrEnableBtn.classList.remove('hidden'); radarrTestBtn.classList.add('hidden'); radarrTriggers.classList.add('hidden'); } if (state.radarrWebhook.enabled) { document.getElementById('radarr-onGrab').textContent = state.radarrWebhook.triggers.onGrab ? '✓' : '✗'; document.getElementById('radarr-onGrab').className = 'trigger-value ' + (state.radarrWebhook.triggers.onGrab ? 'active' : 'inactive'); document.getElementById('radarr-onDownload').textContent = state.radarrWebhook.triggers.onDownload ? '✓' : '✗'; document.getElementById('radarr-onDownload').className = 'trigger-value ' + (state.radarrWebhook.triggers.onDownload ? 'active' : 'inactive'); document.getElementById('radarr-onImport').textContent = state.radarrWebhook.triggers.onImport ? '✓' : '✗'; document.getElementById('radarr-onImport').className = 'trigger-value ' + (state.radarrWebhook.triggers.onImport ? 'active' : 'inactive'); document.getElementById('radarr-onUpgrade').textContent = state.radarrWebhook.triggers.onUpgrade ? '✓' : '✗'; document.getElementById('radarr-onUpgrade').className = 'trigger-value ' + (state.radarrWebhook.triggers.onUpgrade ? 'active' : 'inactive'); } if (state.radarrWebhook.stats) { radarrStats.classList.remove('hidden'); document.getElementById('radarr-events').textContent = state.radarrWebhook.stats.eventsReceived ?? 0; document.getElementById('radarr-polls').textContent = state.radarrWebhook.stats.pollsSkipped ?? 0; document.getElementById('radarr-last').textContent = formatTimeAgo(state.radarrWebhook.stats.lastWebhookTimestamp); } else { radarrStats.classList.add('hidden'); } // Ombi const ombiStatus = document.getElementById('ombi-status'); const ombiEnableBtn = document.getElementById('enable-ombi-webhook'); const ombiTestBtn = document.getElementById('test-ombi-webhook'); const ombiTriggers = document.getElementById('ombi-triggers'); const ombiStats = document.getElementById('ombi-stats'); ombiStatus.textContent = state.ombiWebhook.enabled ? '● Enabled' : '○ Disabled'; ombiStatus.className = 'status-indicator ' + (state.ombiWebhook.enabled ? 'enabled' : 'disabled'); if (state.ombiWebhook.enabled) { ombiEnableBtn.classList.add('hidden'); ombiTestBtn.classList.remove('hidden'); ombiTriggers.classList.remove('hidden'); } else { ombiEnableBtn.classList.remove('hidden'); ombiTestBtn.classList.add('hidden'); ombiTriggers.classList.add('hidden'); } if (state.ombiWebhook.enabled) { document.getElementById('ombi-requestAvailable').textContent = state.ombiWebhook.triggers.requestAvailable ? '✓' : '✗'; document.getElementById('ombi-requestAvailable').className = 'trigger-value ' + (state.ombiWebhook.triggers.requestAvailable ? 'active' : 'inactive'); document.getElementById('ombi-requestApproved').textContent = state.ombiWebhook.triggers.requestApproved ? '✓' : '✗'; document.getElementById('ombi-requestApproved').className = 'trigger-value ' + (state.ombiWebhook.triggers.requestApproved ? 'active' : 'inactive'); document.getElementById('ombi-requestDeclined').textContent = state.ombiWebhook.triggers.requestDeclined ? '✓' : '✗'; document.getElementById('ombi-requestDeclined').className = 'trigger-value ' + (state.ombiWebhook.triggers.requestDeclined ? 'active' : 'inactive'); document.getElementById('ombi-requestPending').textContent = state.ombiWebhook.triggers.requestPending ? '✓' : '✗'; document.getElementById('ombi-requestPending').className = 'trigger-value ' + (state.ombiWebhook.triggers.requestPending ? 'active' : 'inactive'); document.getElementById('ombi-requestProcessing').textContent = state.ombiWebhook.triggers.requestProcessing ? '✓' : '✗'; document.getElementById('ombi-requestProcessing').className = 'trigger-value ' + (state.ombiWebhook.triggers.requestProcessing ? 'active' : 'inactive'); } if (state.ombiWebhook.stats) { ombiStats.classList.remove('hidden'); document.getElementById('ombi-events').textContent = state.ombiWebhook.stats.eventsReceived ?? 0; document.getElementById('ombi-polls').textContent = state.ombiWebhook.stats.pollsSkipped ?? 0; document.getElementById('ombi-last').textContent = formatTimeAgo(state.ombiWebhook.stats.lastWebhookTimestamp); } else { ombiStats.classList.add('hidden'); } } export async function enableSonarrWebhook() { setWebhookLoading(true); try { const result = await apiEnableSonarrWebhook(); if (!result.success) { console.error('Failed to enable Sonarr webhook:', result.error); alert('Failed to enable Sonarr webhook. Check console for details.'); } } catch (err) { console.error('Failed to enable Sonarr webhook:', err); alert('Failed to enable Sonarr webhook. Check console for details.'); } finally { setWebhookLoading(false); } } export async function enableRadarrWebhook() { setWebhookLoading(true); try { const result = await apiEnableRadarrWebhook(); if (!result.success) { console.error('Failed to enable Radarr webhook:', result.error); alert('Failed to enable Radarr webhook. Check console for details.'); } } catch (err) { console.error('Failed to enable Radarr webhook:', err); alert('Failed to enable Radarr webhook. Check console for details.'); } finally { setWebhookLoading(false); } } export async function testSonarrWebhook() { setWebhookLoading(true); try { const result = await apiTestSonarrWebhook(); if (result.success) { alert('Sonarr webhook test sent successfully!'); } else { console.error('Failed to test Sonarr webhook:', result.error); alert('Failed to test Sonarr webhook. Check console for details.'); } } catch (err) { console.error('Failed to test Sonarr webhook:', err); alert('Failed to test Sonarr webhook. Check console for details.'); } finally { setWebhookLoading(false); } } export async function testRadarrWebhook() { setWebhookLoading(true); try { const result = await apiTestRadarrWebhook(); if (result.success) { alert('Radarr webhook test sent successfully!'); } else { console.error('Failed to test Radarr webhook:', result.error); alert('Failed to test Radarr webhook. Check console for details.'); } } catch (err) { console.error('Failed to test Radarr webhook:', err); alert('Failed to test Radarr webhook. Check console for details.'); } finally { setWebhookLoading(false); } } export async function enableOmbiWebhook() { setWebhookLoading(true); try { const result = await apiEnableOmbiWebhook(); if (!result.success) { console.error('Failed to enable Ombi webhook:', result.error); alert('Failed to enable Ombi webhook. Check console for details.'); } } catch (err) { console.error('Failed to enable Ombi webhook:', err); alert('Failed to enable Ombi webhook. Check console for details.'); } finally { setWebhookLoading(false); } } export async function testOmbiWebhook() { setWebhookLoading(true); try { const result = await apiTestOmbiWebhook(); if (result.success) { alert('Ombi webhook test sent successfully!'); } else { console.error('Failed to test Ombi webhook:', result.error); alert('Failed to test Ombi webhook. Check console for details.'); } } catch (err) { console.error('Failed to test Ombi webhook:', err); alert('Failed to test Ombi webhook. Check console for details.'); } finally { setWebhookLoading(false); } } export function setWebhookLoading(loading) { state.webhookLoading = loading; document.getElementById('enable-sonarr-webhook').disabled = loading; document.getElementById('enable-radarr-webhook').disabled = loading; document.getElementById('enable-ombi-webhook').disabled = loading; document.getElementById('test-sonarr-webhook').disabled = loading; document.getElementById('test-radarr-webhook').disabled = loading; document.getElementById('test-ombi-webhook').disabled = loading; const loadingEl = document.getElementById('webhook-loading'); if (loading) { loadingEl.classList.remove('hidden'); } else { loadingEl.classList.add('hidden'); } }