diff --git a/src/pipecat/frames/frames.py b/src/pipecat/frames/frames.py index 230fe9c8f..21780d6cb 100644 --- a/src/pipecat/frames/frames.py +++ b/src/pipecat/frames/frames.py @@ -745,11 +745,11 @@ class OutputDTMFFrame(DTMFFrame, DataFrame): """DTMF keypress output frame for transport queuing. 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 entry. Equivalent to ``buttons=[button]``. If both ``buttons`` 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 @@ -763,8 +763,7 @@ class OutputDTMFFrame(DTMFFrame, DataFrame): raise ValueError(f"{self.__class__.__name__} requires `buttons` or `button` to be set") def __str__(self): - buttons_str = "".join(b.value for b in self.buttons) if self.buttons else "" - return f"{self.name}(buttons: {buttons_str})" + return f"{self.name}(buttons: {self.to_string()})" @classmethod 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) + 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 @@ -1280,11 +1289,11 @@ class OutputDTMFUrgentFrame(DTMFFrame, SystemFrame): """DTMF keypress output frame for immediate sending. 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 entry. Equivalent to ``buttons=[button]``. If both ``buttons`` 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 @@ -1298,8 +1307,7 @@ class OutputDTMFUrgentFrame(DTMFFrame, SystemFrame): raise ValueError(f"{self.__class__.__name__} requires `buttons` or `button` to be set") def __str__(self): - buttons_str = "".join(b.value for b in self.buttons) if self.buttons else "" - return f"{self.name}(buttons: {buttons_str})" + return f"{self.name}(buttons: {self.to_string()})" @classmethod 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) + 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 class SpeechControlParamsFrame(SystemFrame): diff --git a/src/pipecat/transports/daily/transport.py b/src/pipecat/transports/daily/transport.py index 779a7e622..e96799b37 100644 --- a/src/pipecat/transports/daily/transport.py +++ b/src/pipecat/transports/daily/transport.py @@ -2185,14 +2185,12 @@ class DailyOutputTransport(BaseOutputTransport): if not frame.buttons: 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 frame.session_id is not None: settings["sessionId"] = frame.session_id if frame.digit_duration_ms is not None: settings["digitDurationMs"] = frame.digit_duration_ms - elif frame.transport_destination is not None: - settings["sessionId"] = frame.transport_destination await self._client.send_dtmf(settings)