feat(notifications): add Telegram test button
New "Test senden" button next to Speichern posts current form
credentials (not DB) to /actions/notifications/test, which fires a
test message and redirects back with a flash chip showing the outcome
(including the Telegram API's error description on failure).
telegram_send is now public and returns (ok, detail) so the UI can
surface real error messages ("chat not found", "Unauthorized", etc.).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
d06dfdaca1
commit
64439fd42e
3 changed files with 63 additions and 8 deletions
|
|
@ -1,5 +1,7 @@
|
|||
"""Einstellungen (settings) tab: profile, filter info, notifications, partner,
|
||||
account, plus the related action endpoints."""
|
||||
from urllib.parse import quote
|
||||
|
||||
from fastapi import APIRouter, Depends, Form, HTTPException, Request
|
||||
from fastapi.responses import HTMLResponse, RedirectResponse
|
||||
|
||||
|
|
@ -7,6 +9,7 @@ import db
|
|||
from auth import current_user, hash_password, require_csrf, require_user
|
||||
from common import base_context, client_ip, templates
|
||||
from matching import row_to_dict
|
||||
from notifications import telegram_send
|
||||
|
||||
|
||||
router = APIRouter()
|
||||
|
|
@ -39,6 +42,8 @@ def tab_settings(request: Request, section: str):
|
|||
ctx["filters"] = row_to_dict(db.get_filters(u["id"]))
|
||||
elif section == "benachrichtigungen":
|
||||
ctx["notifications"] = db.get_notifications(u["id"])
|
||||
ctx["notif_flash"] = request.query_params.get("flash") or ""
|
||||
ctx["notif_flash_detail"] = request.query_params.get("detail") or ""
|
||||
elif section == "partner":
|
||||
ctx["partner"] = db.get_partner_user(u["id"])
|
||||
ctx["partner_profile"] = db.get_profile(ctx["partner"]["id"]) if ctx["partner"] else None
|
||||
|
|
@ -105,6 +110,34 @@ async def action_notifications(request: Request, user=Depends(require_user)):
|
|||
return RedirectResponse("/einstellungen/benachrichtigungen", status_code=303)
|
||||
|
||||
|
||||
@router.post("/actions/notifications/test")
|
||||
async def action_notifications_test(request: Request, user=Depends(require_user)):
|
||||
"""Send a test Telegram message using the credentials currently in the
|
||||
form (not the DB), so unsaved edits can be verified before saving."""
|
||||
form = await request.form()
|
||||
require_csrf(user["id"], form.get("csrf", ""))
|
||||
token = (form.get("telegram_bot_token") or "").strip()
|
||||
chat_id = (form.get("telegram_chat_id") or "").strip()
|
||||
if not token or not chat_id:
|
||||
return RedirectResponse(
|
||||
"/einstellungen/benachrichtigungen?flash=test_missing",
|
||||
status_code=303,
|
||||
)
|
||||
ok, detail = telegram_send(
|
||||
token, chat_id, f"*lazyflat* Testnachricht ✅\nfür `{user['username']}`",
|
||||
)
|
||||
db.log_audit(
|
||||
user["username"], "notifications.tested",
|
||||
f"ok={ok} detail={detail[:120]}",
|
||||
user_id=user["id"], ip=client_ip(request),
|
||||
)
|
||||
flash = "test_ok" if ok else "test_fail"
|
||||
target = f"/einstellungen/benachrichtigungen?flash={flash}"
|
||||
if not ok:
|
||||
target += f"&detail={quote(detail[:200])}"
|
||||
return RedirectResponse(target, status_code=303)
|
||||
|
||||
|
||||
@router.post("/actions/account/password")
|
||||
async def action_password(
|
||||
request: Request,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue