Netdata.cloud bot for Zulip

more webhook support

Changed files
+36 -3
netdata_zulip_bot
+20 -2
netdata_zulip_bot/formatter.py
···
from typing import Union
-
from .models import AlertNotification, ReachabilityNotification
+
from .models import AlertNotification, ReachabilityNotification, TestNotification
class ZulipMessageFormatter:
···
return topic, message
-
def format_notification(self, notification: Union[AlertNotification, ReachabilityNotification]) -> tuple[str, str]:
+
def format_test(self, notification: TestNotification) -> tuple[str, str]:
+
"""Format test notification for Zulip.
+
+
Returns:
+
Tuple of (topic, message_content)
+
"""
+
topic = "test"
+
+
message = f"""🧪 **Netdata Webhook Test**
+
+
{notification.message}
+
+
Your webhook integration is working correctly! ✅"""
+
+
return topic, message
+
+
def format_notification(self, notification: Union[AlertNotification, ReachabilityNotification, TestNotification]) -> tuple[str, str]:
"""Format any notification type for Zulip.
Returns:
···
return self.format_alert(notification)
elif isinstance(notification, ReachabilityNotification):
return self.format_reachability(notification)
+
elif isinstance(notification, TestNotification):
+
return self.format_test(notification)
else:
raise ValueError(f"Unknown notification type: {type(notification)}")
+16 -1
netdata_zulip_bot/models.py
···
severity: AlertSeverity
date: datetime
alert_url: str
+
# Additional fields from full schema
+
Rooms: Optional[dict] = None
+
family: Optional[str] = None
+
class_: Optional[str] = Field(None, alias="class") # 'class' is a Python keyword
+
duration: Optional[str] = None
+
additional_active_critical_alerts: Optional[int] = None
+
additional_active_warning_alerts: Optional[int] = None
@field_validator('date', mode='before')
@classmethod
···
status: ReachabilityStatus
+
class TestNotification(BaseModel):
+
"""Test notification payload from Netdata Cloud."""
+
message: str
+
+
class WebhookPayload(BaseModel):
"""Union type for webhook payloads."""
@classmethod
-
def parse(cls, data: dict) -> Union[AlertNotification, ReachabilityNotification]:
+
def parse(cls, data: dict) -> Union[AlertNotification, ReachabilityNotification, TestNotification]:
"""Parse webhook payload and determine notification type."""
if 'alert' in data and 'chart' in data:
return AlertNotification(**data)
elif 'status' in data and 'host' in data:
return ReachabilityNotification(**data)
+
elif len(data) == 1 and 'message' in data:
+
# Test notification - only has a message field
+
return TestNotification(**data)
else:
raise ValueError(f"Unknown notification type: {data}")