fix: test push errors, skip heartbeat notify, stale 5h (0.9.2)

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-06-10 17:25:16 +10:00
parent 5e9f0f8110
commit f9baf96d88
7 changed files with 69 additions and 7 deletions
+21 -3
View File
@@ -98,11 +98,22 @@ def _active_device_tokens(db: Session | None) -> list[str]:
return tokens
def _send_fcm_data(tokens: list[str], data: dict[str, str], *, title: str, body: str) -> None:
def _send_fcm_data(
tokens: list[str],
data: dict[str, str],
*,
title: str,
body: str,
require_success: bool = False,
) -> None:
if not tokens:
if require_success:
raise MobileSendError("Нет FCM-токенов для отправки")
return
cfg = get_effective_fcm_config()
if not cfg.active:
if require_success:
raise MobileNotConfiguredError("FCM не настроен на сервере")
return
access_token = _fcm_access_token(cfg.service_account_path)
@@ -111,6 +122,7 @@ def _send_fcm_data(tokens: list[str], data: dict[str, str], *, title: str, body:
"Authorization": f"Bearer {access_token}",
"Content-Type": "application/json",
}
errors: list[str] = []
with httpx.Client(timeout=12.0) as client:
for token in tokens:
@@ -128,8 +140,13 @@ def _send_fcm_data(tokens: list[str], data: dict[str, str], *, title: str, body:
except httpx.HTTPStatusError as exc:
detail = exc.response.text[:200] if exc.response is not None else str(exc)
logger.warning("FCM send failed for token prefix %s: %s", token[:8], detail)
except Exception:
errors.append(detail or f"HTTP {exc.response.status_code if exc.response else '?'}")
except Exception as exc:
logger.exception("FCM send failed")
errors.append(str(exc))
if require_success and errors:
raise MobileSendError(errors[0], status_code=502)
def _event_payload(event: Event) -> tuple[str, str, dict[str, str]]:
@@ -200,7 +217,8 @@ def send_test_push(*, db: Session, device_id: int) -> None:
_send_fcm_data(
[token],
{"kind": "test", "id": "0"},
{"kind": "test", "id": "0", "severity": "info"},
title="SAC: тестовое push",
body="Канал Seaca (FCM) работает.",
require_success=True,
)
+4
View File
@@ -8,6 +8,7 @@ from app.models import Event, Problem
from app.services import email_notify, mobile_notify, telegram_notify, webhook_notify
from app.services.notification_cooldown import should_notify_event, should_notify_problem
from app.services.notification_policy import get_effective_notification_policy
from app.services.host_health import HEARTBEAT_TYPE
from app.services.notification_severity import severity_meets_minimum
logger = logging.getLogger(__name__)
@@ -51,6 +52,9 @@ def _dispatch_problem_channels(problem: Problem, event: Event | None, *, db: Ses
def notify_event(event: Event, *, db: Session | None = None) -> None:
# Heartbeat — только для UI/статуса хоста, не для Telegram/email/push.
if event.type == HEARTBEAT_TYPE:
return
policy = get_effective_notification_policy(db)
if not severity_meets_minimum(event.severity, policy.min_severity):
return