Building an Interactive Voice Response (IVR) System With Go and Twilio
Building an Interactive Voice Response (IVR) System with Go and Twilio
Interactive Voice Response (IVR) is a technology that allows users to interact with computer systems through voice and DTMF (Dual-Tone Multi-Frequency) tones using a telephone keypad. It serves as an automated telephony system that interacts with callers, gathers information, and routes calls to the appropriate recipient.
IVR systems offer a wide range of features designed to simplify communication processes and improve how things run. Some of these features include:
- Automated Call Routing: Direct calls to the appropriate individual based on code input or predefined rules
- Interactive Menus: Provide callers with menu options, such as "Press 1 for Sales" and "Press 2 for Support"
- Data Collection: Gather and process caller information, such as account details or feedback
- Integration with External Systems: Connect with databases, CRM systems, and other APIs to retrieve or update information
- Multi-language Support: Offer support in multiple languages to cater to a global audience
This tutorial will guide you through the process of building an IVR system using Go and Twilio. Specifically, the system will provide weather information, where users will be able to contact your Twilio phone number to obtain current weather conditions and forecasts for their area.
Prerequisites
Before moving on, it is important to ensure you have the following:
- A Twilio account (free or paid) with a Twilio phone number. If you're new, click here to create a free account.
- Go 1.22 or higher installed on your machine
- ngrok installed on your computer with an active account
- A phone number to make voice calls to your application to test your IVR system
The project's workflow
We will set up an endpoint in the application that dynamically generates TwiML (Twilio Markup Language), enabling users to select a city and receive the weather information for that city.
This route will be made accessible to the public internet (despite being hosted on our local development machine) using ngrok. We will then configure our Twilio number in the Twilio console to post to this ngrok endpoint.
Set up the core of the project
To get started, let’s create the project folder for the application. Open your terminal and navigate to the directory where you want to create the project. Then, run the command below to create the application core directory:
Next, initialise a new Go module inside the directory by running the following command:
In our IVR system, we will create and use three primary packages:
- handler: For handling HTTP endpoints
- models: Will contain a model for structuring our TwiML responses
- utils: For supported city list and getting weather information
Now, let's create these packages by running the following commands:
Next, create a new file named main.go in the root directory of your application. After creating the file, your project structure should look similar to the screenshot below:
Now, inside the main.go file add the following code.
The code above creates a simple HTTP server using the built-in net/http package. The main()
function:
- Initialises the server
- Defines routes for
/main_menu
and/handle_choice
- Launches the server on port 8083
The handlers for these routes are specified in the handlers
package, which we will develop in the next steps.
Build the IVR system
In this section, we will create the three packages we discussed: handlers
, models
, and utils
. Each package will play a significant role in our IVR system. We will begin with the handlers
package, which contains functions for handling HTTP requests and generating TwiML responses for Twilio.
Build HTTP handlers for TwiML response generation
Import the necessary packages
First, navigate to the handlers directory and create a handler.go file and add the necessary imports to it.
Here, we imported the necessary packages and dependencies from twilioIvr/models
and twilioIvr/utils
to handle HTTP requests and generate TwiML responses for our IVR system.
Now, let's move on to the main part of the handlers
package which is adding the MainMenuHandler
function, and the HandleChoiceHandler()
function which will present the caller with a list of available options to interact with the system.
Add the MainMenuHandler Function
Create a MainMenuHandler()
function in the handler.go file by adding the following code to the end of handler .go:
This code defines the MainMenuHandler()
function, which creates a Gather
object to collect a single-digit input from the caller, and presents a voice menu for selecting a city. Then, we create a new TwimlResponse
object containing the Gather
object to generate a TwiML response for the caller.
Next, let's proceed with handling the XML marshalling and response by adding the following code to the end of MainMenuHandler()
:
Marshalling the models.TwimlResponse
struct into XML format using xml.Marshal()
is essential. If an error occurs during marshalling, it writes an error message to the response with an HTTP 500 Internal Server Error code. If successful, it sets the response content type to application/xml
and writes the marshalled XML data to the response body.
Add the HandleChoiceHandler Function
Next, we define the HandleChoiceHandler()
function to manage user input and return appropriate weather reports. Paste the entire code, below, at the end of your handler.go file.
Here is the breakdown of the code above. It:
- Parses the form values from the request
- Retrieves the digit input by the user from the form values
- Processes different digit inputs using a switch case
- Marshalls the
models.TwimlResponse
object into XML format and sends the appropriate weather report or error message
You can view and copy the full content of the handler.go file from this GitHub Gist.
Set up TwiML response structs
Now, create a model.go file inside the models folder. This file will define three structs used for building TwiML responses in your Go application. Inside the model.go file, add the following code:
The import "encoding/xml"
statement imports Go's encoding/xml package, which provides support for parsing and generating XML documents. This package is essential for converting Go structs into XML format and vice versa. In this context, it is used to generate TwiML responses, which are XML-based instructions for Twilio's APIs.
Here is an explanation of each struct and its fields:
- The
TwimlResponse
struct, containing optionalGather
andSay
nested elements, serves as the root of a TwiML response. - The
Gather
struct collects keypad input withAction
,Method
, andNumDigits
attributes, and an optionalTimeout
, including a message. - The
Say
struct plays a message to the user with customizableText
,Voice
, andLanguage
attributes.
Add utility functions for weather reports and city data
The next step involves creating a mock.db.go file in the utils directory. This file acts as a database of weather reports and city data. The utils
package includes functions to provide random weather reports and city information.
These functions will be utilised later in the IVR flow to simulate responses for users who inquire about the weather in specific cities. They will call the GetCityWeather()
function and provide an index corresponding to the city of interest. The function will then return a formatted string containing the city's name and a weather report. Add the following code to the mock.db.go file created earlier:
This code defines two arrays: WeatherConditions
and Cities
. These store predefined weather reports and city names, respectively. The code also includes functions to retrieve weather reports for specific cities and to generate random weather reports.
Create a local tunnel with ngrok
Let's create a local tunnel to the application using ngrok, making our local server accessible over the internet. This is especially helpful for testing webhooks and integrating with services like Twilio which require access to a public URL for sending requests.
To create a tunnel, run the code below on your terminal:
This command will start ngrok and create a tunnel to your local server running on port 8083. You will see output similar to the screenshot below
Update the webhook URL
Copy the Forwarding URL generated by ngrok. Then, open your Twilio Console, and navigate to Phone Numbers > Manage > Active numbers > <Your Twilio phone number> > Voice Configuration.
There, update the URL field next to the "A call comes in" dropdown with your ngrok Forwarding URL and append the URL with /main_menu
(e.g., https://8d75-102-88-35-152.ngrok-free.app/main_menu
), as in the screenshot below. After that, click Save configuration.
With the local tunnel already set up, all that's left is to test our IVR system.
Test the IVR system
Then, open your terminal and run the command below in your application's top-level directory:
Next, place a call to your Twilio number and follow the instructions provided. Congratulations! You should now have your IVR system successfully communicating with you. You can find the entire code for this tutorial here.
That's how to build an Interactive Voice Response (IVR) system with Go and Twilio
Throughout this tutorial, we covered the step-by-step process of creating an IVR system using Go and Twilio. This project demonstrates the practical use of Go's fundamental principles such as structuring, managing HTTP requests, and XML conversion, in addition to Twilio's powerful communication APIs for building an interactive voice response system.
By following this guide, you've learned how to establish routes, handle user input, and generate dynamic responses, effectively merging Go and Twilio to construct a functional and interactive IVR application. You successfully built an IVR system!
Isijola Jeremiah is a developer who specialises in enhancing user experience on both the backend and frontend. Contact him on LinkedIn.
Related Posts
Related Resources
Twilio Docs
From APIs to SDKs to sample apps
API reference documentation, SDKs, helper libraries, quickstarts, and tutorials for your language and platform.
Resource Center
The latest ebooks, industry reports, and webinars
Learn from customer engagement experts to improve your own communication.
Ahoy
Twilio's developer community hub
Best practices, code samples, and inspiration to build communications and digital engagement experiences.