rtc-voice-chat/backend/routes/proxy.py
2026-04-02 09:40:23 +08:00

97 lines
3.6 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""
POST /proxy — RTC OpenAPI 代理(含请求签名)
"""
import httpx
from fastapi import APIRouter, Request
from fastapi.responses import JSONResponse
from config.custom_scene import get_rtc_openapi_version
from security.signer import Signer
from services.scene_service import Scenes, prepare_scene_runtime
from services.session_store import load_session
from utils.responses import error_response
from utils.validation import assert_scene_value, assert_value
router = APIRouter()
@router.post("/proxy")
async def proxy(request: Request):
action = request.query_params.get("Action", "")
version = request.query_params.get("Version") or get_rtc_openapi_version()
try:
assert_value(action, "Action 不能为空")
assert_value(version, "Version 不能为空")
body = await request.json()
scene_id = body.get("SceneID", "")
assert_value(scene_id, "SceneID 不能为空SceneID 用于指定场景配置")
json_data = Scenes.get(scene_id)
if not json_data:
raise ValueError(f"{scene_id} 不存在,请先配置对应场景。")
_, _, voice_chat = prepare_scene_runtime(scene_id, json_data)
account_config = json_data.get("AccountConfig", {})
assert_scene_value(
scene_id, "AccountConfig.accessKeyId", account_config.get("accessKeyId")
)
assert_scene_value(
scene_id, "AccountConfig.secretKey", account_config.get("secretKey")
)
if action == "StartVoiceChat":
# 从 session 取回 getScenes 时分配的 RoomId/UserId/TaskId
sess = load_session(request, scene_id)
if sess.get("RoomId"):
voice_chat["RoomId"] = sess["RoomId"]
if sess.get("TaskId"):
voice_chat["TaskId"] = sess["TaskId"]
if sess.get("UserId"):
agent_config = voice_chat.get("AgentConfig", {})
target_user_ids = agent_config.get("TargetUserId", [])
if target_user_ids:
target_user_ids[0] = sess["UserId"]
else:
agent_config["TargetUserId"] = [sess["UserId"]]
req_body = voice_chat
elif action == "StopVoiceChat":
app_id = voice_chat.get("AppId", "")
sess = load_session(request, scene_id)
room_id = sess.get("RoomId") or voice_chat.get("RoomId", "")
task_id = sess.get("TaskId") or voice_chat.get("TaskId", "")
assert_scene_value(scene_id, "VoiceChat.AppId", app_id)
assert_scene_value(scene_id, "VoiceChat.RoomId", room_id)
assert_scene_value(scene_id, "VoiceChat.TaskId", task_id)
req_body = {"AppId": app_id, "RoomId": room_id, "TaskId": task_id}
else:
req_body = {}
request_data = {
"region": "cn-north-1",
"method": "POST",
"params": {"Action": action, "Version": version},
"headers": {
"Host": "rtc.volcengineapi.com",
"Content-type": "application/json",
},
"body": req_body,
}
signer = Signer(request_data, "rtc")
signer.add_authorization(account_config)
async with httpx.AsyncClient() as client:
resp = await client.post(
f"https://rtc.volcengineapi.com?Action={action}&Version={version}",
headers=request_data["headers"],
json=req_body,
)
return JSONResponse(resp.json())
except ValueError as e:
return error_response(action, str(e))
except Exception as e:
return error_response(action, str(e))