40 lines
1.4 KiB
Python
40 lines
1.4 KiB
Python
import json
|
|
import logging
|
|
import urllib.error
|
|
import urllib.request
|
|
|
|
from ..config import settings
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
def get_ngrok_wss_base() -> str | None:
|
|
"""Detect ngrok public WSS base (test_bonvoice/outbound_call.py pattern)."""
|
|
tunnel_hosts = ("127.0.0.1:4040", "host.docker.internal:4040")
|
|
for host in tunnel_hosts:
|
|
try:
|
|
with urllib.request.urlopen(f"http://{host}/api/tunnels", timeout=2) as resp:
|
|
data = json.load(resp)
|
|
for tunnel in data.get("tunnels", []):
|
|
public = tunnel.get("public_url", "")
|
|
if public.startswith("https://"):
|
|
ngrok_host = public.removeprefix("https://")
|
|
return f"wss://{ngrok_host}/api/v1/voice"
|
|
except (urllib.error.URLError, TimeoutError, json.JSONDecodeError, OSError):
|
|
continue
|
|
return None
|
|
|
|
|
|
def resolve_voice_relay_public_base() -> str:
|
|
configured = settings.voice_relay_public_url.rstrip("/")
|
|
if "localhost" in configured or "127.0.0.1" in configured:
|
|
ngrok_base = get_ngrok_wss_base()
|
|
if ngrok_base:
|
|
logger.info("Using ngrok voice relay base: %s", ngrok_base)
|
|
return ngrok_base
|
|
return configured
|
|
|
|
|
|
def unified_voicebot_url() -> str:
|
|
"""Bonvoice outbound media URL (voicebotURL)."""
|
|
return f"{resolve_voice_relay_public_base()}/ws/media"
|