fix: normalise telnyx event types

This commit is contained in:
Abhishek Kumar 2026-04-30 13:14:11 +05:30
parent 6c4830cb5e
commit ae4c297327
3 changed files with 18 additions and 7 deletions

View file

@ -25,6 +25,14 @@ if TYPE_CHECKING:
from fastapi import WebSocket
def normalize_event_type(event_type: str) -> str:
"""Telnyx delivers event types with either dots or underscores
(e.g. ``streaming.started`` vs ``streaming_started``). Normalize to the
dotted form so all downstream matching can use a single canonical shape.
"""
return (event_type or "").replace("_", ".")
class TelnyxProvider(TelephonyProvider):
"""
Telnyx implementation of TelephonyProvider.
@ -187,7 +195,7 @@ class TelnyxProvider(TelephonyProvider):
def parse_status_callback(self, data: Dict[str, Any]) -> Dict[str, Any]:
"""Parse Telnyx webhook event data into generic format."""
event_data = data.get("data", data)
event_type = event_data.get("event_type", "")
event_type = normalize_event_type(event_data.get("event_type", ""))
payload = event_data.get("payload", {})
status = self._resolve_status(event_type, payload)
@ -378,7 +386,7 @@ class TelnyxProvider(TelephonyProvider):
# Check for Telnyx event structure
data = webhook_data.get("data", {})
if data.get("record_type") == "event" and "event_type" in data:
event_type = data.get("event_type", "")
event_type = normalize_event_type(data.get("event_type", ""))
if event_type.startswith("call."):
return True
@ -401,7 +409,7 @@ class TelnyxProvider(TelephonyProvider):
from_number=TelnyxProvider.normalize_phone_number(payload.get("from", "")),
to_number=TelnyxProvider.normalize_phone_number(payload.get("to", "")),
direction=direction,
call_status=data.get("event_type", ""),
call_status=normalize_event_type(data.get("event_type", "")),
account_id=payload.get("connection_id"),
raw_data=webhook_data,
)

View file

@ -11,6 +11,7 @@ from loguru import logger
from api.db import db_client
from api.services.telephony.factory import get_telephony_provider
from api.services.telephony.providers.telnyx.provider import normalize_event_type
from api.services.telephony.status_processor import (
StatusCallbackRequest,
_process_status_update,
@ -37,9 +38,11 @@ async def handle_telnyx_events(
f"[run {workflow_run_id}] Received Telnyx event: {json.dumps(event_data)}"
)
# Extract event type from Telnyx envelope
# Extract event type from Telnyx envelope. Telnyx sometimes delivers the
# type with underscores (``streaming_started``) instead of dots
# (``streaming.started``); normalize so downstream comparisons match either.
data = event_data.get("data", {})
event_type = data.get("event_type", "")
event_type = normalize_event_type(data.get("event_type", ""))
# Skip streaming events — they're informational only
if event_type in ("streaming.started", "streaming.stopped"):

View file

@ -45,8 +45,8 @@ async def create_transport(
stream_id=stream_id,
call_control_id=call_control_id,
api_key=api_key,
inbound_encoding="PCMU", # Dograh → Telnyx; matches stream_bidirectional_codec
outbound_encoding=encoding, # Telnyx → Dograh; from media_format.encoding
inbound_encoding="PCMU", # Dograh → Telnyx; matches stream_bidirectional_codec
outbound_encoding=encoding, # Telnyx → Dograh; from media_format.encoding
)
mixer = await build_audio_out_mixer(