open-webui/backend/open_webui/routers/notifications.py
Timothy Jaeryang Baek 810378c0b8
Some checks failed
Create and publish Docker images with specific build args / build (map[arch:linux/arm64 runner:ubuntu-24.04-arm], map[build_args:USE_CUDA=true USE_CUDA_VER=cu126 free_disk:true name:cuda126 suffix:-cuda126]) (push) Has been cancelled
Create and publish Docker images with specific build args / build (map[arch:linux/arm64 runner:ubuntu-24.04-arm], map[build_args:USE_CUDA=true free_disk:true name:cuda suffix:-cuda]) (push) Has been cancelled
Create and publish Docker images with specific build args / build (map[arch:linux/arm64 runner:ubuntu-24.04-arm], map[build_args:USE_OLLAMA=true free_disk:false name:ollama suffix:-ollama]) (push) Has been cancelled
Create and publish Docker images with specific build args / build (map[arch:linux/arm64 runner:ubuntu-24.04-arm], map[build_args:USE_SLIM=true free_disk:false name:slim suffix:-slim]) (push) Has been cancelled
Create and publish Docker images with specific build args / build (map[arch:linux/amd64 runner:ubuntu-latest], map[build_args:USE_OLLAMA=true free_disk:false name:ollama suffix:-ollama]) (push) Has been cancelled
Create and publish Docker images with specific build args / build (map[arch:linux/amd64 runner:ubuntu-latest], map[build_args:USE_SLIM=true free_disk:false name:slim suffix:-slim]) (push) Has been cancelled
Create and publish Docker images with specific build args / build (map[arch:linux/arm64 runner:ubuntu-24.04-arm], map[build_args: free_disk:false name:main suffix:]) (push) Has been cancelled
Create and publish Docker images with specific build args / build (map[arch:linux/amd64 runner:ubuntu-latest], map[build_args: free_disk:false name:main suffix:]) (push) Has been cancelled
Create and publish Docker images with specific build args / build (map[arch:linux/amd64 runner:ubuntu-latest], map[build_args:USE_CUDA=true USE_CUDA_VER=cu126 free_disk:true name:cuda126 suffix:-cuda126]) (push) Has been cancelled
Create and publish Docker images with specific build args / build (map[arch:linux/amd64 runner:ubuntu-latest], map[build_args:USE_CUDA=true free_disk:true name:cuda suffix:-cuda]) (push) Has been cancelled
Frontend Build / Format & Build (push) Has been cancelled
Frontend Build / Unit Tests (push) Has been cancelled
Python CI / Ruff Format (3.11) (push) Has been cancelled
Python CI / Ruff Format (3.12) (push) Has been cancelled
Create and publish Docker images with specific build args / merge (map[name:cuda suffix:-cuda]) (push) Has been cancelled
Create and publish Docker images with specific build args / merge (map[name:cuda126 suffix:-cuda126]) (push) Has been cancelled
Create and publish Docker images with specific build args / merge (map[name:main suffix:]) (push) Has been cancelled
Create and publish Docker images with specific build args / merge (map[name:ollama suffix:-ollama]) (push) Has been cancelled
Create and publish Docker images with specific build args / merge (map[name:slim suffix:-slim]) (push) Has been cancelled
Create and publish Docker images with specific build args / notify-helm-charts (push) Has been cancelled
Create and publish Docker images with specific build args / copy-to-dockerhub (, main) (push) Has been cancelled
Create and publish Docker images with specific build args / copy-to-dockerhub (-cuda, cuda) (push) Has been cancelled
Create and publish Docker images with specific build args / copy-to-dockerhub (-cuda126, cuda126) (push) Has been cancelled
Create and publish Docker images with specific build args / copy-to-dockerhub (-ollama, ollama) (push) Has been cancelled
Create and publish Docker images with specific build args / copy-to-dockerhub (-slim, slim) (push) Has been cancelled
refac
2026-07-27 19:39:36 -04:00

103 lines
3.7 KiB
Python

from __future__ import annotations
from typing import Any
from fastapi import APIRouter, Depends, HTTPException, Request, status
from pydantic import BaseModel
from open_webui.constants import ERROR_MESSAGES
from open_webui.models.config import Config
from open_webui.utils.access_control import has_permission
from open_webui.utils.auth import get_verified_user
from open_webui.utils.notifications import (
create_target,
delete_target,
get_notification_event_catalog,
list_targets,
set_default_target,
test_target,
update_target,
)
router = APIRouter()
class NotificationTargetForm(BaseModel):
id: str | None = None
type: str | None = None
enabled: bool | None = None
events: list[str] | None = None
delivery: str | None = None
config: dict[str, Any] | None = None
async def _check_notifications_access(user) -> None:
if not await Config.get('ui.enable_user_webhooks'):
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=ERROR_MESSAGES.NOT_FOUND)
if user.role != 'admin' and not await has_permission(
user.id, 'features.webhooks', await Config.get('user.permissions')
):
raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail=ERROR_MESSAGES.ACCESS_PROHIBITED)
@router.get('/events')
async def get_notification_events(user=Depends(get_verified_user)):
await _check_notifications_access(user)
return {'events': get_notification_event_catalog()}
@router.get('/targets')
async def get_notification_targets(user=Depends(get_verified_user)):
await _check_notifications_access(user)
return await list_targets(user.id)
@router.post('/targets')
async def create_notification_target(form_data: NotificationTargetForm, user=Depends(get_verified_user)):
await _check_notifications_access(user)
try:
return await create_target(user.id, form_data.model_dump(exclude_unset=True))
except ValueError as e:
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))
@router.put('/targets/{target_id}')
async def update_notification_target(
target_id: str, form_data: NotificationTargetForm, user=Depends(get_verified_user)
):
await _check_notifications_access(user)
try:
return await update_target(user.id, target_id, form_data.model_dump(exclude_unset=True))
except ValueError as e:
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))
@router.delete('/targets/{target_id}')
async def delete_notification_target(target_id: str, user=Depends(get_verified_user)):
await _check_notifications_access(user)
if not await delete_target(user.id, target_id):
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=ERROR_MESSAGES.NOT_FOUND)
return {'ok': True}
@router.put('/targets/{target_id}/default')
async def set_default_notification_target(target_id: str, user=Depends(get_verified_user)):
await _check_notifications_access(user)
try:
return await set_default_target(user.id, target_id)
except ValueError as e:
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))
@router.post('/targets/{target_id}/test')
async def test_notification_target(request: Request, target_id: str, user=Depends(get_verified_user)):
await _check_notifications_access(user)
try:
# LICENSE covers this Open WebUI notification identifier.
# Do not alter, remove, obscure, or replace it except as LICENSE permits:
# https://docs.openwebui.com/license.
app_name = getattr(request.app.state, 'WEBUI_NAME', 'Open WebUI')
return await test_target(user.id, target_id, app_name)
except ValueError as e:
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))