Add optional notification templates for Home Assistant integration

This commit is contained in:
Space-Banane
2026-03-12 16:12:26 +01:00
parent 8045da2dbe
commit fb9a9d7025
3 changed files with 35 additions and 7 deletions

View File

@@ -7,5 +7,9 @@ ADGUARD_PASSWORD=your-password
HASS_URL=https://your-hass-instance.com/api/services/notify/mobile_app_your_phone
HASS_TOKEN=your-long-lived-access-token
# (Optional) Notification Templates - Available: {event_type}, {client_name}, {host}, {reason}
# HASS_TITLE_TEMPLATE="{event_type}"
# HASS_MSG_TEMPLATE="{client_name} tried to access \"{host}\""
# Monitored Clients (JSON Format: {"IP": "Nickname"})
CLIENTS='{"192.168.1.100": "My Laptop", "192.168.1.101": "My Phone"}'

View File

@@ -43,4 +43,6 @@ Adguard Monitor is designed for openclaw, which should usually NEVER make a requ
- `ADGUARD_USER/PASSWORD`: API credentials.
- `CLIENTS`: A JSON-formatted dictionary mapping IPs to display names.
- `HASS_URL/TOKEN`: Home Assistant mobile notification endpoint and Long-Lived Access Token.
- `HASS_TITLE_TEMPLATE`: (Optional) Template for notification title. Available: `{event_type}`, `{client_name}`, `{host}`, `{reason}`. Default: `{event_type}`.
- `HASS_MSG_TEMPLATE`: (Optional) Template for notification body. Available: same as title. Default: `{client_name} tried to access "{host}"`.

View File

@@ -37,6 +37,10 @@ try:
"Content-Type": "application/json",
}
# Optional Notification Overrides
HASS_TITLE_TEMPLATE = os.getenv("HASS_TITLE_TEMPLATE", "{event_type}")
HASS_MSG_TEMPLATE = os.getenv("HASS_MSG_TEMPLATE", "{client_name} tried to access \"{host}\"")
# --- Custom Domain List ---
CUSTOM_DOMAINS = []
NEGATIVE_FILTERS = []
@@ -65,12 +69,19 @@ except (EnvironmentError, json.JSONDecodeError) as e:
print(f"Error during startup: {e}")
exit(1)
def notify_hass(client_name, host, reason, title="🛡️ Adguard Blocked a Request"):
def notify_hass(client_name, host, reason, event_type="🛡️ Adguard Blocked"):
# Format message and title using templates (supporting simple {placeholders})
try:
msg = HASS_MSG_TEMPLATE.format(client_name=client_name, host=host, reason=reason, event_type=event_type)
title = HASS_TITLE_TEMPLATE.format(client_name=client_name, host=host, reason=reason, event_type=event_type)
except KeyError as e:
logger.error(f"Template error: Missing key {e}. Falling back to defaults.")
msg = f"{client_name} tried to access \"{host}\""
title = event_type
payload = {
"message": msg,
"title": title,
"message": msg,
"data": {
"push": {
"sound": "default",
@@ -121,6 +132,10 @@ def get_auth_session():
session.auth = HTTPBasicAuth(USERNAME, PASSWORD)
return session
def hour_and_minute():
now = datetime.now()
return now.strftime("%H:%M")
def is_custom_match(host):
# Check negative filters first
for pattern in NEGATIVE_FILTERS:
@@ -175,15 +190,22 @@ def fetch_and_analyze(session, verbose=False):
if is_blocked or is_custom:
# Check for duplicate notifications within the same "event"
# Using host + client_ip as a unique key for the last notification
event_type = "BLOCKED" if is_blocked else "CUSTOM_MATCH"
event_label = "BLOCKED" if is_blocked else "CUSTOM_MATCH"
notification_key = f"{client_ip}:{host}:{reason}:{hour_and_minute()}"
if stats.last_notified_key == notification_key:
continue
stats.log_blocked()
title = "🛡️ Adguard Blocked a Request" if is_blocked else "⚠️ Custom Domain Match"
logger.warning(f"{event_type}: {client_name} -> {host} ({reason if is_blocked else 'Manual match'})")
notify_hass(client_name, host, reason if is_blocked else "Custom List", title=title)
default_title = "🛡️ Blocked" if is_blocked else "⚠️ Custom"
logger.warning(f"{event_label}: {client_name} -> {host} ({reason if is_blocked else 'Manual match'})")
# Pass details for templating
notify_hass(
client_name=client_name,
host=host,
reason=reason if is_blocked else "Custom List",
event_type=default_title
)
stats.last_notified_key = notification_key
# Dynamic limit adjustment