fix: Seaca push uses same lifecycle text as Telegram (0.9.11)

Reuse telegram templates for FCM title/body so agent start/restart
reasons reach mobile without Seaca app changes.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
PTah
2026-06-17 11:35:17 +10:00
parent 8a97bbfb43
commit 55f047cd35
7 changed files with 129 additions and 8 deletions
+2 -2
View File
@@ -16,6 +16,7 @@ from app.models import Event, Problem
from app.models.mobile_device import MobileDevice
from app.services.notification_severity import severity_meets_minimum
from app.services.notification_policy import get_effective_notification_policy
from app.services.telegram_templates import format_event_mobile_push
logger = logging.getLogger(__name__)
@@ -170,8 +171,7 @@ def _send_fcm_data(
def _event_payload(event: Event) -> tuple[str, str, dict[str, str]]:
title = f"[{event.severity}] {event.title}"
body = (event.summary or "")[:200]
title, body = format_event_mobile_push(event)
data = {
"kind": "event",
"id": str(event.id),
@@ -506,6 +506,43 @@ def format_event_telegram_html(event: Event) -> str:
return _append_event_source(_format_event_body_html(event), event)
_TELEGRAM_INLINE_TAGS = re.compile(r"</?(?:b|i|u|s|code|pre|tg-spoiler)(\s[^>]*)?>", re.I)
_TELEGRAM_ANCHOR_OPEN = re.compile(r"<a\b[^>]*>", re.I)
_TELEGRAM_ANCHOR_CLOSE = re.compile(r"</a>", re.I)
_MOBILE_PUSH_BODY_MAX = 3500
def telegram_html_to_plaintext(text: str) -> str:
"""Plain text for Seaca push from the same HTML templates as Telegram."""
out = sanitize_telegram_html(text)
out = _TELEGRAM_INLINE_TAGS.sub("", out)
out = _TELEGRAM_ANCHOR_OPEN.sub("", out)
out = _TELEGRAM_ANCHOR_CLOSE.sub("", out)
out = html.unescape(out)
out = re.sub(r"\n{3,}", "\n\n", out)
return out.strip()
def format_event_mobile_push(event: Event) -> tuple[str, str]:
"""Title + body for FCM data payload (mirrors Telegram wording)."""
plain = telegram_html_to_plaintext(format_event_telegram_html(event))
lines = [line.strip() for line in plain.split("\n") if line.strip()]
if lines:
title = lines[0]
body = "\n".join(lines[1:]).strip()
if not body:
body = (event.summary or "").strip()
else:
title = f"[{event.severity}] {event.title}"
body = (event.summary or "").strip()
if len(title) > 120:
title = title[:117] + ""
if len(body) > _MOBILE_PUSH_BODY_MAX:
body = body[: _MOBILE_PUSH_BODY_MAX - 1] + ""
return title, body
def _format_rdg_html(event: Event) -> str:
details = _details_dict(event)
if event.type.endswith(".success"):
+1 -1
View File
@@ -1,5 +1,5 @@
"""Единый источник версии SAC (API, health, логи, OpenAPI)."""
APP_NAME = "Security Alert Center"
APP_VERSION = "0.9.10"
APP_VERSION = "0.9.11"
APP_VERSION_LABEL = f"{APP_NAME} v.{APP_VERSION}"