feat(avatar): add BOXIM chat takeover
This commit is contained in:
@@ -11,7 +11,7 @@ router = APIRouter(tags=["授权"])
|
||||
TARGET_TYPES = {"user", "organization", "application"}
|
||||
PERMISSION_ORDER = ("friend", "chat", "publish", "browse", "interact", "takeover")
|
||||
ALLOWED_PERMISSIONS = set(PERMISSION_ORDER)
|
||||
AVATAR_PERMISSION_ORDER = PERMISSION_ORDER[:-1]
|
||||
AVATAR_PERMISSION_ORDER = PERMISSION_ORDER
|
||||
AVATAR_PERMISSION_KEY = "authorizationPermissions"
|
||||
DEFAULT_AVATAR_PERMISSIONS = ["friend", "chat"]
|
||||
LEGACY_PERMISSION_MAP = {
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
"""数字分身单聊接管配置 API。"""
|
||||
"""数字分身 BOXIM 单聊接管 API。"""
|
||||
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
from fastapi import APIRouter, Body, Depends, Header
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from database import get_db
|
||||
from models import TakeoverCursor, TakeoverReplyTask, User
|
||||
from responses import fail, ok
|
||||
from routers.authorizations import _require_authorization
|
||||
from routers.avatars import _require_owned_avatar
|
||||
@@ -11,6 +14,53 @@ from routers.avatars import _require_owned_avatar
|
||||
router = APIRouter(tags=["分身接管"])
|
||||
|
||||
|
||||
@router.get("/avatar/{avatar_id}/takeover/status")
|
||||
def get_takeover_status(
|
||||
avatar_id: str,
|
||||
authorization: str = Header(None),
|
||||
db: Session = Depends(get_db),
|
||||
):
|
||||
avatar = _require_owned_avatar(db, avatar_id, authorization)
|
||||
permissions = (avatar.config or {}).get("authorizationPermissions", [])
|
||||
enabled = isinstance(permissions, list) and "takeover" in permissions
|
||||
user = db.query(User).filter(User.huihui_user_id == avatar.owner_id).first()
|
||||
cursor = db.query(TakeoverCursor).filter(TakeoverCursor.avatar_id == avatar.id).first()
|
||||
pending_count = (
|
||||
db.query(TakeoverReplyTask)
|
||||
.filter(
|
||||
TakeoverReplyTask.avatar_id == avatar.id,
|
||||
TakeoverReplyTask.status.in_(("pending", "generating", "ready", "sending")),
|
||||
)
|
||||
.count()
|
||||
)
|
||||
|
||||
if not enabled:
|
||||
status, message = "disabled", "主动接管未开启"
|
||||
elif not user or not user.huihui_token:
|
||||
status, message = "needs_login", "请重新登录会会生产账号以连接 BOXIM"
|
||||
elif cursor and cursor.last_error:
|
||||
status, message = "error", cursor.last_error
|
||||
elif (
|
||||
cursor
|
||||
and cursor.initialized
|
||||
and cursor.last_polled_at
|
||||
and cursor.last_polled_at >= datetime.utcnow() - timedelta(seconds=15)
|
||||
):
|
||||
status, message = "ready", "BOXIM 已连接,收到私聊消息 3 秒后自动回复"
|
||||
else:
|
||||
status, message = "connecting", "正在连接 BOXIM"
|
||||
|
||||
return ok(
|
||||
{
|
||||
"enabled": enabled,
|
||||
"status": status,
|
||||
"message": message,
|
||||
"pendingCount": pending_count,
|
||||
"lastPolledAt": cursor.last_polled_at.isoformat() if cursor and cursor.last_polled_at else None,
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
def _has(payload: dict, camel_key: str, snake_key: str) -> bool:
|
||||
return camel_key in payload or snake_key in payload
|
||||
|
||||
|
||||
Reference in New Issue
Block a user