Add to_string helper on output DTMF frames
Mirrors the existing `from_string` classmethod and lets callers turn a frame's `buttons` list back into a dial string like `"123#"`. `__str__` and the Daily transport's native DTMF path reuse it.
This commit is contained in:
@@ -745,11 +745,11 @@ class OutputDTMFFrame(DTMFFrame, DataFrame):
|
|||||||
"""DTMF keypress output frame for transport queuing.
|
"""DTMF keypress output frame for transport queuing.
|
||||||
|
|
||||||
Parameters:
|
Parameters:
|
||||||
buttons: Sequence of one or more DTMF keypad buttons to send. Use
|
|
||||||
:meth:`from_string` to build this from a string like ``"123#"``.
|
|
||||||
button: Convenience shortcut for sending a single DTMF keypad
|
button: Convenience shortcut for sending a single DTMF keypad
|
||||||
entry. Equivalent to ``buttons=[button]``. If both ``buttons``
|
entry. Equivalent to ``buttons=[button]``. If both ``buttons``
|
||||||
and ``button`` are provided, ``buttons`` takes precedence.
|
and ``button`` are provided, ``buttons`` takes precedence.
|
||||||
|
buttons: Sequence of one or more DTMF keypad buttons to send. Use
|
||||||
|
:meth:`from_string` to build this from a string like ``"123#"``.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
button: Optional[KeypadEntry] = None
|
button: Optional[KeypadEntry] = None
|
||||||
@@ -763,8 +763,7 @@ class OutputDTMFFrame(DTMFFrame, DataFrame):
|
|||||||
raise ValueError(f"{self.__class__.__name__} requires `buttons` or `button` to be set")
|
raise ValueError(f"{self.__class__.__name__} requires `buttons` or `button` to be set")
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
buttons_str = "".join(b.value for b in self.buttons) if self.buttons else ""
|
return f"{self.name}(buttons: {self.to_string()})"
|
||||||
return f"{self.name}(buttons: {buttons_str})"
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_string(cls, buttons: str, **kwargs) -> "OutputDTMFFrame":
|
def from_string(cls, buttons: str, **kwargs) -> "OutputDTMFFrame":
|
||||||
@@ -782,6 +781,16 @@ class OutputDTMFFrame(DTMFFrame, DataFrame):
|
|||||||
"""
|
"""
|
||||||
return cls(buttons=[KeypadEntry(c) for c in buttons], **kwargs)
|
return cls(buttons=[KeypadEntry(c) for c in buttons], **kwargs)
|
||||||
|
|
||||||
|
def to_string(self) -> str:
|
||||||
|
"""Return the frame's ``buttons`` as a dial string.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
A string such as ``"123#"`` formed by concatenating the values
|
||||||
|
of each :class:`~pipecat.audio.dtmf.types.KeypadEntry` in
|
||||||
|
``buttons``, or an empty string if ``buttons`` is not set.
|
||||||
|
"""
|
||||||
|
return "".join(b.value for b in self.buttons) if self.buttons else ""
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# System frames
|
# System frames
|
||||||
@@ -1280,11 +1289,11 @@ class OutputDTMFUrgentFrame(DTMFFrame, SystemFrame):
|
|||||||
"""DTMF keypress output frame for immediate sending.
|
"""DTMF keypress output frame for immediate sending.
|
||||||
|
|
||||||
Parameters:
|
Parameters:
|
||||||
buttons: Sequence of one or more DTMF keypad buttons to send. Use
|
|
||||||
:meth:`from_string` to build this from a string like ``"123#"``.
|
|
||||||
button: Convenience shortcut for sending a single DTMF keypad
|
button: Convenience shortcut for sending a single DTMF keypad
|
||||||
entry. Equivalent to ``buttons=[button]``. If both ``buttons``
|
entry. Equivalent to ``buttons=[button]``. If both ``buttons``
|
||||||
and ``button`` are provided, ``buttons`` takes precedence.
|
and ``button`` are provided, ``buttons`` takes precedence.
|
||||||
|
buttons: Sequence of one or more DTMF keypad buttons to send. Use
|
||||||
|
:meth:`from_string` to build this from a string like ``"123#"``.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
button: Optional[KeypadEntry] = None
|
button: Optional[KeypadEntry] = None
|
||||||
@@ -1298,8 +1307,7 @@ class OutputDTMFUrgentFrame(DTMFFrame, SystemFrame):
|
|||||||
raise ValueError(f"{self.__class__.__name__} requires `buttons` or `button` to be set")
|
raise ValueError(f"{self.__class__.__name__} requires `buttons` or `button` to be set")
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
buttons_str = "".join(b.value for b in self.buttons) if self.buttons else ""
|
return f"{self.name}(buttons: {self.to_string()})"
|
||||||
return f"{self.name}(buttons: {buttons_str})"
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_string(cls, buttons: str, **kwargs) -> "OutputDTMFUrgentFrame":
|
def from_string(cls, buttons: str, **kwargs) -> "OutputDTMFUrgentFrame":
|
||||||
@@ -1317,6 +1325,16 @@ class OutputDTMFUrgentFrame(DTMFFrame, SystemFrame):
|
|||||||
"""
|
"""
|
||||||
return cls(buttons=[KeypadEntry(c) for c in buttons], **kwargs)
|
return cls(buttons=[KeypadEntry(c) for c in buttons], **kwargs)
|
||||||
|
|
||||||
|
def to_string(self) -> str:
|
||||||
|
"""Return the frame's ``buttons`` as a dial string.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
A string such as ``"123#"`` formed by concatenating the values
|
||||||
|
of each :class:`~pipecat.audio.dtmf.types.KeypadEntry` in
|
||||||
|
``buttons``, or an empty string if ``buttons`` is not set.
|
||||||
|
"""
|
||||||
|
return "".join(b.value for b in self.buttons) if self.buttons else ""
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class SpeechControlParamsFrame(SystemFrame):
|
class SpeechControlParamsFrame(SystemFrame):
|
||||||
|
|||||||
@@ -2185,14 +2185,12 @@ class DailyOutputTransport(BaseOutputTransport):
|
|||||||
if not frame.buttons:
|
if not frame.buttons:
|
||||||
return
|
return
|
||||||
|
|
||||||
settings: Dict[str, Any] = {"tones": "".join(b.value for b in frame.buttons)}
|
settings: Dict[str, Any] = {"tones": frame.to_string()}
|
||||||
if isinstance(frame, (DailyOutputDTMFFrame, DailyOutputDTMFUrgentFrame)):
|
if isinstance(frame, (DailyOutputDTMFFrame, DailyOutputDTMFUrgentFrame)):
|
||||||
if frame.session_id is not None:
|
if frame.session_id is not None:
|
||||||
settings["sessionId"] = frame.session_id
|
settings["sessionId"] = frame.session_id
|
||||||
if frame.digit_duration_ms is not None:
|
if frame.digit_duration_ms is not None:
|
||||||
settings["digitDurationMs"] = frame.digit_duration_ms
|
settings["digitDurationMs"] = frame.digit_duration_ms
|
||||||
elif frame.transport_destination is not None:
|
|
||||||
settings["sessionId"] = frame.transport_destination
|
|
||||||
|
|
||||||
await self._client.send_dtmf(settings)
|
await self._client.send_dtmf(settings)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user