mz_chatbot / app /api /push.py
Shurem's picture
Claude Sonnet 5
feat: real Web Push (VAPID) notifications
a52db70
Raw History Blame Contribute Delete
1.58 kB
"""
api/push.py -- Web Push (VAPID) subscribe/unsubscribe for the signed-in user's own device.
Mirrors api/notifications.py's "scoped to the caller" posture: no login, no subscription (nothing to
scope it to).
"""
from __future__ import annotations
from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy.orm import Session
from app.api.deps import get_current_user, get_db
from app.config import settings
from app.crud import push as crud
from app.models import User
from app.schemas.push import PushSubscribeInput, PushUnsubscribeInput, VapidPublicKeyOut
router = APIRouter(tags=["push"])
@router.get("/push/vapid-public-key", response_model=VapidPublicKeyOut)
def vapid_public_key():
return VapidPublicKeyOut(key=settings.vapid_public_key)
@router.post("/push/subscribe")
def subscribe(
body: PushSubscribeInput,
db: Session = Depends(get_db),
user: User | None = Depends(get_current_user),
):
if user is None:
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Please sign in.")
crud.save_subscription(db, user_id=user.id, endpoint=body.endpoint, p256dh=body.p256dh, auth=body.auth)
return {"ok": True}
@router.post("/push/unsubscribe")
def unsubscribe(
body: PushUnsubscribeInput,
db: Session = Depends(get_db),
user: User | None = Depends(get_current_user),
):
if user is None:
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Please sign in.")
crud.remove_subscription(db, user_id=user.id, endpoint=body.endpoint)
return {"ok": True}