diff --git a/backend/app/services/telegram_templates.py b/backend/app/services/telegram_templates.py
index f67fbc0..bb2f776 100644
--- a/backend/app/services/telegram_templates.py
+++ b/backend/app/services/telegram_templates.py
@@ -95,7 +95,8 @@ def _line(emoji: str, label: str, value: str) -> str:
return f"{emoji} {label}: {value}\n"
-def _event_generated_by(event: Event) -> str:
+def _event_content_author(event: Event) -> str:
+ """Кто сгенерировал содержимое события (ingest / отчёт)."""
details = _details_dict(event)
gb = details.get("generated_by")
if isinstance(gb, str) and gb.strip().lower() in ("agent", "sac"):
@@ -108,6 +109,21 @@ def _event_generated_by(event: Event) -> str:
return "agent"
+def _notification_delivered_by(event: Event) -> str:
+ """Кто доставил сообщение в Telegram (footer «📡 Оповещение»).
+
+ Шаблоны здесь используются только при отправке из SAC. Агент добавляет footer сам.
+ """
+ details = _details_dict(event)
+ via = details.get("telegram_via")
+ if isinstance(via, str) and via.strip().lower() in ("agent", "sac"):
+ return via.strip().lower()
+ if _event_content_author(event) == "sac":
+ return "sac"
+ # ingest от агента, канал Telegram — SAC (exclusive / notify_lifecycle)
+ return "sac"
+
+
def _event_product_version(event: Event) -> tuple[str | None, str | None]:
details = _details_dict(event)
platform = None
@@ -137,12 +153,13 @@ def _event_product_version(event: Event) -> tuple[str | None, str | None]:
def _append_event_source(html_msg: str, event: Event) -> str:
+ delivered = _notification_delivered_by(event)
product, version = _event_product_version(event)
return append_notification_source_html(
html_msg,
- generated_by=_event_generated_by(event),
- product=product,
- product_version=version,
+ generated_by=delivered,
+ product=product if delivered == "agent" else None,
+ product_version=version if delivered == "agent" else None,
)
diff --git a/backend/tests/test_daily_report.py b/backend/tests/test_daily_report.py
index bbfd75e..98e17ef 100644
--- a/backend/tests/test_daily_report.py
+++ b/backend/tests/test_daily_report.py
@@ -248,7 +248,7 @@ def test_daily_report_telegram_html_uses_report_html(db_session):
payload={},
)
assert format_event_telegram_html(event) == (
- "📊 OK\nline\n📡 Оповещение: агент (ssh-monitor)"
+ "📊 OK\nline\n📡 Оповещение: SAC (Security Alert Center)"
)
diff --git a/backend/tests/test_telegram_templates.py b/backend/tests/test_telegram_templates.py
index dcd7584..b1884c3 100644
--- a/backend/tests/test_telegram_templates.py
+++ b/backend/tests/test_telegram_templates.py
@@ -65,7 +65,7 @@ def test_rdp_success_template():
text = format_event_telegram_html(event)
assert "УСПЕШНЫЙ" in text
assert "Сеть/RDP" in text
- assert "📡 Оповещение: агент" in text
+ assert "📡 Оповещение: SAC (Security Alert Center)" in text
def test_event_telegram_includes_sac_source_for_sac_daily_report():
@@ -107,7 +107,26 @@ def test_lifecycle_started_template():
assert "K6A-DC3" in text
assert "1.2.30-SAC" in text
assert "загрузка ОС" in text
- assert "📡 Оповещение: агент" in text
+ assert "📡 Оповещение: SAC (Security Alert Center)" in text
+
+
+def test_lifecycle_footer_uses_telegram_via_agent_when_present():
+ host = Host(hostname="WIN01", display_name="H1", os_family="windows")
+ event = Event(
+ event_id="00000000-0000-4000-8000-000000000506",
+ host_id=1,
+ host=host,
+ occurred_at=datetime(2026, 5, 29, 9, 0, tzinfo=timezone.utc),
+ category="agent",
+ type="agent.lifecycle",
+ severity="info",
+ title="started",
+ summary="x",
+ details={"lifecycle": "started", "telegram_via": "agent"},
+ payload={"source": {"product": "rdp-login-monitor", "product_version": "1.2.30-SAC"}},
+ )
+ text = format_event_telegram_html(event)
+ assert "📡 Оповещение: агент (rdp-login-monitor 1.2.30-SAC)" in text
def test_rdp_shadow_control_template():