I want to send DTMF signals to my Voice Agent. Whe...
# ask-ai
m
I want to send DTMF signals to my Voice Agent. When the agent is initialized and having conversation with the user, I want the user to enter the validation code(6 digits). Then I want the agent to read these numbers and use function tool to process and validate the user input
t
Thanks for reaching out, Mridul. I'm an AI assistant and I'm here to help. Give me a moment while I research this topic.
To send DTMF signals to your Voice Agent and process user input, you can follow these steps: Sending DTMF Signals You can use the
send_dtmf_code
function to send DTMF codes. Here is an example implementation:
Copy code
@function_tool()
async def send_dtmf_code(
    self,
    code: Annotated[int, Field(description="The DTMF code to send to the phone number for the current step.")],
    context: RunContext_T
) -> None:
    # Cooldown check to prevent rapid presses
    current_time = time.time()
    if current_time - context.userdata.last_dtmf_press < 3:
        <http://logger.info|logger.info>("DTMF code rejected due to cooldown")
        return None

    # Send the DTMF code
    context.userdata.last_dtmf_press = current_time
    room = context.session.room
    await room.local_participant.publish_dtmf(
        code=code,
        digit=str(code)
    )
    await room.local_participant.publish_data(
        f"{code}",
        topic="dtmf_code"
    )
Processing DTMF Input To handle incoming DTMF signals, you can set up handlers. Here is an example:
Copy code
def setup_dtmf_handlers(room: rtc.Room, phone_assistant: PhoneAssistant):
    async def _async_handle_dtmf(dtmf_event: rtc.SipDTMF):
        await phone_assistant.session.interrupt()
        <http://logger.info|logger.info>("Interrupted agent due to DTMF")

        code = dtmf_event.code
        digit = dtmf_event.digit
        identity = dtmf_event.participant.identity

        # Example of processing different DTMF inputs
        department_numbers = {
            "1": ("BILLING_PHONE_NUMBER", "Billing"),
            "2": ("TECH_SUPPORT_PHONE_NUMBER", "Tech Support"),
            "3": ("CUSTOMER_SERVICE_PHONE_NUMBER", "Customer Service")
        }

        if digit in department_numbers:
            # Process valid input
            env_var, dept_name = department_numbers[digit]
            transfer_number = f"tel:{os.getenv(env_var)}"
            userdata = phone_assistant.session.userdata
            userdata.selected_department = dept_name
            await phone_assistant._handle_transfer(identity, transfer_number, dept_name)
        else:
            # Handle invalid input
            await phone_assistant.session.generate_reply(user_input="I'm sorry, please choose one of the options I mentioned earlier.")

    @room.on("sip_dtmf_received")
    def handle_dtmf(dtmf_event: rtc.SipDTMF):
        asyncio.create_task(_async_handle_dtmf(dtmf_event))
This implementation allows you to send DTMF signals with a cooldown mechanism and process incoming DTMF signals to trigger specific actions like call transfers based on the user’s input. Sources: Building an Automated IVR Menu Caller | LiveKit Docs | Company directory phone assistant | LiveKit Docs
m
So basically, the agent will run the function tool 'send_dtmf_code' which will then start noting down the user input? The DTMF signals are handeled by setup_dtmf_handlers?
t
Yes, that's correct! The process works as follows: • The
send_dtmf_code
function is used to send DTMF signals. This function ensures that the signals are sent with a cooldown mechanism to prevent rapid presses. • The
setup_dtmf_handlers
is responsible for handling the incoming DTMF signals. It processes the user input and triggers specific actions based on the received DTMF codes. For example, it can interrupt the agent, validate the input, or perform other operations like transferring calls. Let me know if you need further clarification or assistance!
m
What I want is that, user should be able to enter 6 digits. These 6 digits should be then passed on to the agent, which will then process them (by passing it in function tool and getting the responce back)
t
I'm sorry, but I don't have the information you need at the moment. If you would like a member of the LiveKit team to respond, please ask your question in one of the other channels.