From 7df73beea3ee84b92fe98971bf4c6a6949ff8bc1 Mon Sep 17 00:00:00 2001 From: Nir Simionovich Date: Thu, 14 May 2026 15:50:14 +0300 Subject: [PATCH] =?UTF-8?q?Resolve=20an=20issue=20with=20direct=20socket?= =?UTF-8?q?=20connections=20using=20the=20wrong=20event=E2=80=A6=20(#289)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Resolve an issue with direct socket connections using the wrong event data. * Resolve the formatting issus in the provider file * chore: fix import ordering with ruff Co-Authored-By: Claude Opus 4.7 (1M context) --------- Co-authored-by: Nir Simionovich Co-authored-by: Abhishek Kumar Co-authored-by: Claude Opus 4.7 (1M context) --- .../telephony/providers/cloudonix/provider.py | 41 ++++++++++++------- 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/api/services/telephony/providers/cloudonix/provider.py b/api/services/telephony/providers/cloudonix/provider.py index 349335a..28ebcea 100644 --- a/api/services/telephony/providers/cloudonix/provider.py +++ b/api/services/telephony/providers/cloudonix/provider.py @@ -544,12 +544,13 @@ class CloudonixProvider(TelephonyProvider): try: stream_sid = start_msg["start"]["streamSid"] call_sid = start_msg["start"]["callSid"] + call_session = start_msg["start"]["session"] except KeyError: - logger.error("Missing streamSid or callSid in start message") + logger.error("Missing streamSid or callSid or session in start message") await websocket.close(code=4400, reason="Missing stream identifiers") return - if not await self._validate_session(domain_id, call_sid, bearer_token): + if not await self._validate_session(domain_id, call_session, bearer_token): await websocket.close( code=4400, reason="Cloudonix session validation failed" ) @@ -557,7 +558,7 @@ class CloudonixProvider(TelephonyProvider): logger.info( f"Cloudonix agent-stream connected for workflow_run " - f"{workflow_run_id} stream_sid={stream_sid} call_sid={call_sid} " + f"{workflow_run_id} stream_sid={stream_sid} call_sid={call_sid} session={call_session}" f"telephony_configuration_id={config.id}" ) @@ -567,9 +568,9 @@ class CloudonixProvider(TelephonyProvider): workflow_id=workflow_id, workflow_run_id=workflow_run_id, user_id=user_id, - call_id=call_sid, + call_id=call_session, transport_kwargs={ - "call_id": call_sid, + "call_id": call_session, "stream_sid": stream_sid, "bearer_token": bearer_token, "domain_id": domain_id, @@ -581,17 +582,15 @@ class CloudonixProvider(TelephonyProvider): raise async def _validate_session( - self, domain_id: str, call_id: str, bearer_token: str + self, domain_id: str, call_session: str, bearer_token: str ) -> bool: """Confirm the session is live with Cloudonix. - Hits ``GET /customers/self/domains/{domain_id}/sessions/{call_id}`` + Hits ``GET /customers/self/domains/{domain_id}/sessions/{call_session}`` with the supplied bearer token. A 200 response means both the token is valid and the session exists. """ - endpoint = ( - f"{self.base_url}/customers/self/domains/{domain_id}/sessions/{call_id}" - ) + endpoint = f"{self.base_url}/customers/self/domains/{domain_id}/sessions/{call_session}" headers = { "Authorization": f"Bearer {bearer_token}", "Content-Type": "application/json", @@ -605,13 +604,13 @@ class CloudonixProvider(TelephonyProvider): logger.error( f"Cloudonix session validation failed: " f"HTTP {response.status} domain_id={domain_id} " - f"call_id={call_id} body={body}" + f"call_id={call_session} body={body}" ) return False except Exception as e: logger.error( f"Cloudonix session validation error for domain_id={domain_id} " - f"call_id={call_id}: {e}" + f"call_id={call_session}: {e}" ) return False @@ -952,10 +951,24 @@ class CloudonixProvider(TelephonyProvider): **kwargs: Any, ) -> Dict[str, Any]: """ - Cloudonix provider does not support call transfers. + Initiate a call transfer via Cloudonix. + + Uses inline CXML to put the destination into a conference when they answer, + and a status callback to track the transfer outcome. + + Args: + destination: The destination phone number (E.164 format) + transfer_id: Unique identifier for tracking this transfer + conference_name: Name of the conference to join the destination into + timeout: Transfer timeout in seconds + **kwargs: Additional Twilio-specific parameters + + Returns: + Dict containing transfer result information Raises: - NotImplementedError: Cloudonix call transfers are yet to be implemented + ValueError: If provider configuration is invalid + Exception: If Twilio API call fails """ raise NotImplementedError("Cloudonix provider does not support call transfers")