51 lines
1.5 KiB
Python
51 lines
1.5 KiB
Python
import uuid
|
|
|
|
import httpx
|
|
|
|
from ..config import settings
|
|
|
|
|
|
class BonvoiceError(Exception):
|
|
def __init__(self, message: str, status_code: int | None = None) -> None:
|
|
super().__init__(message)
|
|
self.status_code = status_code
|
|
|
|
|
|
async def initiate_outbound_call(
|
|
*,
|
|
destination: str,
|
|
leg_a_caller_id: str,
|
|
voicebot_url: str,
|
|
event_id: str | None = None,
|
|
) -> dict:
|
|
if not settings.bonvoice_token:
|
|
raise BonvoiceError("Bonvoice credentials are not configured", status_code=503)
|
|
|
|
payload = {
|
|
"autocallType": "5",
|
|
"destination": destination,
|
|
"legACallerID": leg_a_caller_id,
|
|
"eventID": event_id or uuid.uuid4().hex.upper(),
|
|
"voicebotProvider": "BONVOICE",
|
|
"voicebotURL": voicebot_url,
|
|
}
|
|
headers = {
|
|
"Authorization": f"Token {settings.bonvoice_token}",
|
|
"Content-Type": "application/json",
|
|
}
|
|
async with httpx.AsyncClient(timeout=30.0) as client:
|
|
response = await client.post(settings.bonvoice_api_url, headers=headers, json=payload)
|
|
|
|
if response.status_code >= 400:
|
|
raise BonvoiceError(
|
|
f"Bonvoice API rejected the call ({response.status_code})",
|
|
status_code=502,
|
|
)
|
|
|
|
body = response.json()
|
|
if body.get("responseCode") not in (200, "200"):
|
|
raise BonvoiceError(
|
|
body.get("responseDescription") or "Bonvoice API returned an error",
|
|
status_code=502,
|
|
)
|
|
return body
|