feat: Implement notification system with Apprise integration and credential checks
This commit is contained in:
@@ -5,6 +5,7 @@ Configuration validation package for the application.
|
||||
from app.utils.config_validator.validators import (
|
||||
validate_email_config,
|
||||
validate_storage_configs,
|
||||
validate_notification_config,
|
||||
check_all_configs
|
||||
)
|
||||
from app.utils.config_validator.masking import mask_sensitive_value
|
||||
@@ -17,6 +18,7 @@ from app.utils.config_validator.settings_display import (
|
||||
__all__ = [
|
||||
'validate_email_config',
|
||||
'validate_storage_configs',
|
||||
'validate_notification_config',
|
||||
'mask_sensitive_value',
|
||||
'get_provider_status',
|
||||
'get_settings_for_display',
|
||||
|
||||
@@ -11,6 +11,24 @@ def get_provider_status():
|
||||
"""
|
||||
providers = {}
|
||||
|
||||
# Add Notification configuration - Make sure this provider is near the top of the list
|
||||
providers["Notifications"] = {
|
||||
"name": "Notifications",
|
||||
"icon": "fa-solid fa-bell",
|
||||
"configured": bool(getattr(settings, 'notification_urls', None)),
|
||||
"enabled": True,
|
||||
"description": "Send system notifications via various services",
|
||||
"details": {
|
||||
"services": str(len(getattr(settings, 'notification_urls', []))) + " service(s) configured" if getattr(settings, 'notification_urls', None) else "Not configured",
|
||||
"task_failure": getattr(settings, 'notify_on_task_failure', True),
|
||||
"credential_failure": getattr(settings, 'notify_on_credential_failure', True),
|
||||
"startup": getattr(settings, 'notify_on_startup', True),
|
||||
"shutdown": getattr(settings, 'notify_on_shutdown', False)
|
||||
},
|
||||
"testable": True,
|
||||
"test_endpoint": "/api/diagnostic/test-notification"
|
||||
}
|
||||
|
||||
# Add AI services first
|
||||
providers["OpenAI"] = {
|
||||
"name": "OpenAI",
|
||||
@@ -253,4 +271,5 @@ def get_provider_status():
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return providers
|
||||
|
||||
@@ -23,6 +23,20 @@ def dump_all_settings():
|
||||
value = f"{value[:visible_start]}{'*' * (len(value) - visible_start - visible_end)}{value[-visible_end:]}"
|
||||
else:
|
||||
value = f"{value[:2]}{'*' * (len(value) - 4)}{value[-2:]}" if isinstance(value, str) and len(value) > 4 else "****"
|
||||
|
||||
# Special handling for notification URLs
|
||||
if key == 'notification_urls' and value:
|
||||
try:
|
||||
from app.utils.notification import _mask_sensitive_url
|
||||
if isinstance(value, list):
|
||||
masked_urls = [_mask_sensitive_url(url) for url in value]
|
||||
logger.info(f"{key}: {masked_urls}")
|
||||
else:
|
||||
logger.info(f"{key}: {_mask_sensitive_url(value)}")
|
||||
continue # Skip the default logging
|
||||
except (ImportError, AttributeError):
|
||||
pass # Fall back to default logging if _mask_sensitive_url is not available
|
||||
|
||||
logger.info(f"{key}: {value}")
|
||||
logger.info("--- END OF SETTINGS DUMP ---")
|
||||
|
||||
@@ -169,6 +183,13 @@ def get_settings_for_display(show_values=False):
|
||||
"Monitoring": [
|
||||
"uptime_kuma_url",
|
||||
"uptime_kuma_ping_interval"
|
||||
],
|
||||
"Notifications": [
|
||||
"notification_urls",
|
||||
"notify_on_task_failure",
|
||||
"notify_on_credential_failure",
|
||||
"notify_on_startup",
|
||||
"notify_on_shutdown"
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
@@ -136,6 +136,36 @@ def validate_storage_configs():
|
||||
|
||||
return issues
|
||||
|
||||
def validate_notification_config():
|
||||
"""Check notification configuration"""
|
||||
issues = []
|
||||
|
||||
# Check if any notification URLs are configured
|
||||
if not getattr(settings, 'notification_urls', None):
|
||||
issues.append("No notification URLs configured")
|
||||
else:
|
||||
try:
|
||||
# Try initializing Apprise to validate URLs
|
||||
import apprise
|
||||
a = apprise.Apprise()
|
||||
|
||||
for url in settings.notification_urls:
|
||||
try:
|
||||
if not a.add(url):
|
||||
issues.append(f"Invalid notification URL format: {url}")
|
||||
except Exception as e:
|
||||
issues.append(f"Error with notification URL: {str(e)}")
|
||||
|
||||
except ImportError:
|
||||
issues.append("Apprise module not installed")
|
||||
|
||||
if not issues:
|
||||
logger.info("Notification configuration valid")
|
||||
else:
|
||||
logger.warning(f"Notification configuration issues: {', '.join(issues)}")
|
||||
|
||||
return issues
|
||||
|
||||
def check_all_configs():
|
||||
"""Run all configuration validations and log results"""
|
||||
from app.utils.config_validator.settings_display import dump_all_settings
|
||||
@@ -161,8 +191,16 @@ def check_all_configs():
|
||||
else:
|
||||
logger.info(f"{provider.capitalize()} configuration OK")
|
||||
|
||||
# Check notification configuration
|
||||
notification_issues = validate_notification_config()
|
||||
if notification_issues:
|
||||
logger.warning(f"Notification configuration issues: {', '.join(notification_issues)}")
|
||||
else:
|
||||
logger.info("Notification configuration OK")
|
||||
|
||||
# Return all identified issues
|
||||
return {
|
||||
'email': email_issues,
|
||||
'storage': storage_issues
|
||||
'storage': storage_issues,
|
||||
'notification': notification_issues
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user