o
    iq)                     @   s   d Z ddlZddlZddlmZ ddlZddlmZ ddlm	Z	 ddl
mZ ddlmZmZmZmZmZ ddlmZmZmZmZmZmZmZmZ dd	lmZ G d
d deZdS )z.Telnyx WebSocket frame serializer for Pipecat.    N)Optional)logger)	BaseModel)KeypadEntry)alaw_to_pcmcreate_stream_resamplerpcm_to_alawpcm_to_ulawulaw_to_pcm)AudioRawFrameCancelFrameEndFrameFrameInputAudioRawFrameInputDTMFFrameInterruptionFrame
StartFrame)FrameSerializerc                   @   s   e Zd ZdZG dd deZ			ddedededee d	ee d
ee fddZde	fddZ
dedeeB dB fddZdd ZdeeB dedB fddZdS )TelnyxFrameSerializera  Serializer for Telnyx WebSocket protocol.

    This serializer handles converting between Pipecat frames and Telnyx's WebSocket
    media streams protocol. It supports audio conversion, DTMF events, and automatic
    call termination.

    When auto_hang_up is enabled (default), the serializer will automatically terminate
    the Telnyx call when an EndFrame or CancelFrame is processed, but requires Telnyx
    credentials to be provided.
    c                   @   sR   e Zd ZU dZdZeed< dZee ed< dZ	e
ed< dZe
ed< d	Zeed
< dS )z!TelnyxFrameSerializer.InputParamsa  Configuration parameters for TelnyxFrameSerializer.

        Parameters:
            telnyx_sample_rate: Sample rate used by Telnyx, defaults to 8000 Hz.
            sample_rate: Optional override for pipeline input sample rate.
            inbound_encoding: Audio encoding for data sent to Telnyx (e.g., "PCMU").
            outbound_encoding: Audio encoding for data received from Telnyx (e.g., "PCMU").
            auto_hang_up: Whether to automatically terminate call on EndFrame.
        i@  telnyx_sample_rateNsample_ratePCMUinbound_encodingoutbound_encodingTauto_hang_up)__name__
__module____qualname____doc__r   int__annotations__r   r   r   strr   r   bool r#   r#   N/home/ubuntu/.local/lib/python3.10/site-packages/pipecat/serializers/telnyx.pyInputParams2   s   
 
r%   N	stream_idr   r   call_control_idapi_keyparamsc                 C   sZ   || _ || _|| _|pt | _|| j_|| j_| jj| _	d| _
t | _t | _d| _dS )a  Initialize the TelnyxFrameSerializer.

        Args:
            stream_id: The Stream ID for Telnyx.
            outbound_encoding: The encoding type for outbound audio (e.g., "PCMU").
            inbound_encoding: The encoding type for inbound audio (e.g., "PCMU").
            call_control_id: The Call Control ID for the Telnyx call (optional, but required for auto hang-up).
            api_key: Your Telnyx API key (required for auto hang-up).
            params: Configuration parameters.
        r   FN)
_stream_id_call_control_id_api_keyr   r%   _paramsr   r   r   _telnyx_sample_rate_sample_rater   _input_resampler_output_resampler_hangup_attempted)selfr&   r   r   r'   r(   r)   r#   r#   r$   __init__C   s   

zTelnyxFrameSerializer.__init__framec                    s   | j jp|j| _dS )zSets up the serializer with pipeline configuration.

        Args:
            frame: The StartFrame containing pipeline configuration.
        N)r-   r   audio_in_sample_rater/   )r3   r5   r#   r#   r$   setupd   s   zTelnyxFrameSerializer.setupreturnc                    s  | j jr| jst|ttfrd| _|  I dH  dS t|tr)ddi}t	|S t|t
r|j}| j jdkrEt||j| j| jI dH }n| j jdkrYt||j| j| jI dH }n	td| j j |du slt|dkrndS t|d	}d
d|id}t	|S dS )a  Serializes a Pipecat frame to Telnyx WebSocket format.

        Handles conversion of various frame types to Telnyx WebSocket messages.
        For EndFrames and CancelFrames, initiates call termination if auto_hang_up is enabled.

        Args:
            frame: The Pipecat frame to serialize.

        Returns:
            Serialized data as string or bytes, or None if the frame isn't handled.

        Raises:
            ValueError: If an unsupported encoding is specified.
        TNeventclearr   PCMAUnsupported encoding: r   zutf-8mediapayload)r9   r=   )r-   r   r2   
isinstancer   r   _hang_up_callr   jsondumpsr   audior   r	   r   r.   r1   r   
ValueErrorlenbase64	b64encodedecode)r3   r5   answerdataserialized_datar>   r#   r#   r$   	serializel   s@   



zTelnyxFrameSerializer.serializec           
   
      s   z| j }| j}|r|std W dS d| d}dd| d}t 4 I dH }|j||d4 I dH }|jd	krEtd
|  nq|jdkrz5|	 I dH }t
dd |dg D r~td| d W W d  I dH  W d  I dH  W dS W n	 ty   Y nw | I dH }td| d|j d|  n| I dH }td| d|j d|  W d  I dH  n1 I dH sw   Y  W d  I dH  W dS 1 I dH sw   Y  W dS  ty }	 ztd|	  W Y d}	~	dS d}	~	ww )z0Hang up the Telnyx call using Telnyx's REST API.zHCannot hang up Telnyx call: call_control_id and api_key must be providedNz https://api.telnyx.com/v2/calls/z/actions/hangupzapplication/jsonzBearer )zContent-TypeAuthorization)headers   z$Successfully terminated Telnyx call i  c                 s   s    | ]
}| d dkV  qdS )code90018N)get).0errorr#   r#   r$   	<genexpr>   s
    
z6TelnyxFrameSerializer._hang_up_call.<locals>.<genexpr>errorszTelnyx call z was already terminatedz Failed to terminate Telnyx call z	: Status z, Response: zFailed to hang up Telnyx call: )r+   r,   r   warningaiohttpClientSessionpoststatusinforA   anyrR   debug	ExceptiontextrT   )
r3   r'   r(   endpointrN   sessionresponse
error_data
error_texter#   r#   r$   r@      sl   




*2#z#TelnyxFrameSerializer._hang_up_callrJ   c           	   
      s  t |}|d dkr^|d d }t|}| jjdkr+t|| j| j| j	I dH }n| jjdkr?t
|| j| j| j	I dH }n	td| jj |du sRt|dkrTdS t|d	| jd
}|S |d dkr|di d}ztt|W S  ty } zW Y d}~dS d}~ww dS )a  Deserializes Telnyx WebSocket data to Pipecat frames.

        Handles conversion of Telnyx media events to appropriate Pipecat frames,
        including audio data and DTMF keypresses.

        Args:
            data: The raw WebSocket data from Telnyx.

        Returns:
            A Pipecat frame corresponding to the Telnyx event, or None if unhandled.

        Raises:
            ValueError: If an unsupported encoding is specified.
        r9   r=   r>   r   Nr;   r<   r      )rC   num_channelsr   dtmfdigit)rA   loadsrF   	b64decoder-   r   r
   r.   r/   r0   r   rD   rE   r   rR   r   r   )	r3   rJ   messagepayload_base64r>   deserialized_dataaudio_framerj   rf   r#   r#   r$   deserialize   sF   

z!TelnyxFrameSerializer.deserialize)NNN)r   r   r   r   r   r%   r!   r   r4   r   r7   r   bytesrL   r@   rq   r#   r#   r#   r$   r   &   s.    
!89r   )r   rF   rA   typingr   rX   logurur   pydanticr   pipecat.audio.dtmf.typesr   pipecat.audio.utilsr   r   r   r	   r
   pipecat.frames.framesr   r   r   r   r   r   r   r   #pipecat.serializers.base_serializerr   r   r#   r#   r#   r$   <module>   s   (
