Advanced Technical Success Manager
André MartinsSignalWire's new AI Agent allows you to build innovative customer service tools into your applications with minimal coding. When creating an application with our Compatibility API, you can easily implement an AI agent for tasks such as rescheduling appointments to create your own virtual receptionist.
In this step-by-step guide, we will build an appointment reminder application with built-in AI answering machine detection and an AI-powered virtual assistant that can reschedule appointments.
We'll break down each piece of code to explain the functionality of machine detection and the integration with SignalWire’s AI virtual agent. By following this guide, you'll gain a clear understanding of how to leverage AI to take your customer experience to the next level.
Before we begin, we assume you have:
Basic knowledge of NodeJS
Basic knowledge of Git
Docker installed
A SignalWire Space with a Phone Number
Running the Application
Clone the signalwire-in-seconds repo and go to the ai-appointment-reminders folder.
Copy the .env.example file to a file named .env, and fill in the necessary information:
Build the container by running
And then start the container with
Your application is now ready to receive POST requests to the /startReminder endpoint. It expects the following data about the patient and their appointment:
The application will then make a call to the patient’s number, and transfer it to the AI Agent. Should a machine be detected, the virtual agent will be made aware of it and leave a voicemail instead of trying to interact.
If a machine is not detected, the magic happens! The AI agent starts interacting with the patient to confirm they’ll be attending the appointment, and if not, work with the patient to reschedule. While doing so, the agent will check available time slots and update them accordingly.
Breaking down the code
If you want to jump straight to the code, see our signalwire-in-seconds repository on GitHub.
Setting up dependencies
We start by importing all of our dependencies:
We load the .env file to get all of our credentials, import ngrok so we can have a tunnel to our machine, import Express so we can use it to expose the various routes, and finally, we import SignalWire’s RestClient so we can create or update calls and compose compatibility XML instructions so SignalWire can run them.
Mocking Time Slots
For simplicity, we use an object that uses days as keys and then has an array with the available times:
Ideally, you should build functions to fetch availability from your CRM or a database instead.
The /startReminder endpoint
This is where all calls to patients will start. Make a POST request to this endpoint with patient data and SignalWire will make a call that:
Gets XML Instructions from /agent
Runs Answering Machine Detection asynchronously and sends results to /amd so we can then make decisions to change the AI Agent’s behavior.
The /amd endpoint
As SignalWire listens to the callee’s audio, it may determine that the call was answered by a machine. If so, instead of the call continuing to run /agent’s XML instructions, we update it so it runs /leaveVoicemail’s.
The /leaveVoicemail endpoint
When this endpoint’s code runs, it means SignalWire detected a machine answered the phone, and it is now time to change from trying to interacting with the patient to leaving a message.
We create a new VoiceResponse to start crafting our XML instructions, and use the AI Noun to give the agent a prompt describing what it should do. Check out our AI best practices guide for more information on how to write effective prompts. Finally, we convert the instructions into a string and return them so SignalWire can run them on the call.
The /agent endpoint
This endpoint returns the instructions for all calls as they start, and tells the AI agent it should interact with the patient to confirm their availability. While the code might look daunting due to being extensive, most of it is setting up a prompt just as we did in the /leaveVoicemail endpoint, with the end goal being to get the conversational AI to behave exactly like we want it to.
We structure the tasks we want the AI agent to carry out in steps, as this ensures the agent will honor the call flow.
Then, we set up the get_available_times and update_appointment_schedule functions inside of the SignalWire AI Gateway with the appropriate name, argument, and purpose. We can leverage SignalWire’s AI Gateway to “break out” of the AI’s constraints and interface with other systems.
The functions we define will have a default Webhook URL they send POST requests to. In this case we use the /functionHandler endpoint, and the data the functions will send to it look like this:
The most important piece of our functions is the argument, as it tells SignalWire’s AI what to send in the POST request, and exactly in what format.
The /functionHandler endpoint
As the name suggests, this endpoint handles requests from SignalWire’s AI Gateway functions, and you can adapt it based on your requirements.
If the function that was triggered is get_available_times we get the day from the argument and return the array of available times.
If the function that was triggered is update_appointment_schedule we get new and old date/time combos, and update available time slots.
This code sets up a POST route for the /functionHandler endpoint. It extracts the functionName from the request body and handles different function names accordingly.
Congratulations! You have successfully built an appointment reminder app with answering machine detection and AI Agent integration! With this knowledge, you can customize and enhance the app to suit your specific requirements. Experiment and integrate SignalWire into your applications for seamless and efficient voice interactions by signing up for a free trial.
Explore developer.signalwire.com to learn more about SignalWire’s capabilities, and join our Community Slack and Forum to interact with the team. We can’t wait to see what you build!