feat: Telegram settings in DB with UI edit and test send
Store notification_channels (migration 004), effective config DB over env, PUT/test API endpoints, Settings form, and pass db session into ingest notify. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -64,9 +64,9 @@ def post_event(
|
||||
problem_created = False
|
||||
if created:
|
||||
problem, problem_created = maybe_create_problem(db, event)
|
||||
notify_event(event)
|
||||
notify_event(event, db=db)
|
||||
if problem is not None and problem_created:
|
||||
notify_problem(problem, event)
|
||||
notify_problem(problem, event, db=db)
|
||||
logger.info("ingest created event_id=%s type=%s host_id=%s", event.event_id, event.type, event.host_id)
|
||||
else:
|
||||
logger.info("ingest duplicate event_id=%s", event.event_id)
|
||||
|
||||
@@ -1,8 +1,16 @@
|
||||
from fastapi import APIRouter, Depends
|
||||
from fastapi import APIRouter, Depends, HTTPException
|
||||
from pydantic import BaseModel, Field
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from app.auth.jwt_auth import get_current_user
|
||||
from app.config import get_settings
|
||||
from app.database import get_db
|
||||
from app.services.notification_settings import (
|
||||
VALID_SEVERITIES,
|
||||
TelegramConfig,
|
||||
get_effective_telegram_config,
|
||||
upsert_telegram_channel,
|
||||
)
|
||||
from app.services.telegram_notify import TelegramNotConfiguredError, TelegramSendError, send_telegram_test_message
|
||||
|
||||
router = APIRouter(prefix="/settings", tags=["settings"])
|
||||
|
||||
@@ -22,28 +30,77 @@ class TelegramSettingsResponse(BaseModel):
|
||||
chat_id_hint: str | None = None
|
||||
bot_token_hint: str | None = None
|
||||
min_severity: str
|
||||
source: str = Field(default="env", description="env until UI persistence (notif-12)")
|
||||
source: str = Field(description="env или db")
|
||||
|
||||
|
||||
class NotificationSettingsResponse(BaseModel):
|
||||
telegram: TelegramSettingsResponse
|
||||
|
||||
|
||||
class TelegramSettingsUpdate(BaseModel):
|
||||
enabled: bool
|
||||
min_severity: str
|
||||
bot_token: str | None = None
|
||||
chat_id: str | None = None
|
||||
|
||||
|
||||
class TelegramTestResponse(BaseModel):
|
||||
ok: bool = True
|
||||
message: str = "Тестовое сообщение отправлено в Telegram"
|
||||
|
||||
|
||||
def _telegram_to_response(cfg: TelegramConfig) -> TelegramSettingsResponse:
|
||||
return TelegramSettingsResponse(
|
||||
enabled=cfg.enabled,
|
||||
configured=cfg.configured,
|
||||
chat_id_hint=_mask_secret(cfg.chat_id),
|
||||
bot_token_hint=_mask_secret(cfg.bot_token),
|
||||
min_severity=cfg.min_severity,
|
||||
source=cfg.source,
|
||||
)
|
||||
|
||||
|
||||
@router.get("/notifications", response_model=NotificationSettingsResponse)
|
||||
def get_notification_settings(
|
||||
db: Session = Depends(get_db),
|
||||
_user: str = Depends(get_current_user),
|
||||
) -> NotificationSettingsResponse:
|
||||
settings = get_settings()
|
||||
token = settings.telegram_bot_token.strip()
|
||||
chat_id = settings.telegram_chat_id.strip()
|
||||
configured = bool(token and chat_id)
|
||||
return NotificationSettingsResponse(
|
||||
telegram=TelegramSettingsResponse(
|
||||
enabled=bool(settings.telegram_enabled and configured),
|
||||
configured=configured,
|
||||
chat_id_hint=_mask_secret(chat_id),
|
||||
bot_token_hint=_mask_secret(token),
|
||||
min_severity=settings.telegram_min_severity,
|
||||
source="env",
|
||||
cfg = get_effective_telegram_config(db)
|
||||
return NotificationSettingsResponse(telegram=_telegram_to_response(cfg))
|
||||
|
||||
|
||||
@router.put("/notifications/telegram", response_model=TelegramSettingsResponse)
|
||||
def update_telegram_settings(
|
||||
body: TelegramSettingsUpdate,
|
||||
db: Session = Depends(get_db),
|
||||
_user: str = Depends(get_current_user),
|
||||
) -> TelegramSettingsResponse:
|
||||
if body.min_severity not in VALID_SEVERITIES:
|
||||
raise HTTPException(status_code=422, detail=f"min_severity must be one of: {sorted(VALID_SEVERITIES)}")
|
||||
try:
|
||||
cfg = upsert_telegram_channel(
|
||||
db,
|
||||
enabled=body.enabled,
|
||||
min_severity=body.min_severity,
|
||||
bot_token=body.bot_token,
|
||||
chat_id=body.chat_id,
|
||||
)
|
||||
)
|
||||
except ValueError as exc:
|
||||
raise HTTPException(status_code=422, detail=str(exc)) from exc
|
||||
return _telegram_to_response(cfg)
|
||||
|
||||
|
||||
@router.post("/notifications/telegram/test", response_model=TelegramTestResponse)
|
||||
def test_telegram_settings(
|
||||
db: Session = Depends(get_db),
|
||||
_user: str = Depends(get_current_user),
|
||||
) -> TelegramTestResponse:
|
||||
cfg = get_effective_telegram_config(db)
|
||||
try:
|
||||
send_telegram_test_message(config=cfg)
|
||||
except TelegramNotConfiguredError as exc:
|
||||
raise HTTPException(status_code=400, detail=str(exc)) from exc
|
||||
except TelegramSendError as exc:
|
||||
code = exc.status_code if exc.status_code and 400 <= exc.status_code < 500 else 502
|
||||
raise HTTPException(status_code=code, detail=str(exc)) from exc
|
||||
return TelegramTestResponse()
|
||||
|
||||
Reference in New Issue
Block a user