Over the last month I’ve had a new project that integrates Twilio call handling with an appointment booking service. This is my first time working with Twilio, and I am very impressed by the complex systems that can be pieced together with Twilio’s functionality. In this case we are creating a way to retrieve the caller’s existing appointments from SimplyBookMe and ask them which one they want to cancel. They input the appointment number they want to cancel and we hit the SimplyBookMe API to cancel the appointment. I want to dive into some of the cool parts of Twilio and a few things that I would like to see improved.
The Good things about Twilio Studio
It’s super easy to get started with Twilio studio.
You set up a phone number and then can create Twilio flows based on three potential starting triggers: a phone call, a text message, or an API request. In my situation, I am working on a phone call flow, but I also played around with a text message flow that responds to a specific message with a reply.
Studio has dozens of widgets that can be dragged into your flow and configured without needing any code. One widget can transition to the next. Widgets can do things like say some text, send a SMS message, gather input from the caller, make HTTP requests, and run JavaScript functions.
Twilio has a hosted area for custom code called “Services”. Each service can have multiple endpoints, code dependencies, and environmental settings (great for storing config details). The Services area has a built-in code editor, deployment process, and debugging tools. You can write JavaScript functionality without ever needing to work locally.
The Great features of Twilio services
TwiML is Twilio’s unique XML document that tells the service how to handle a call. With a few lines of code you can do some really cool things like:
Have a voice say “Hello World” to the caller:response.say('Hello World');
Plan an audio file:
response.play({}, 'https://api.twilio.com/cowbell.mp3');
Gather input from the caller (digits or even speech-to-text recognition):
const gather = response.gather({
input: 'speech',
action: '/handlelanguage'
});
gather.say('Press 1 for English or 2 for Francais');
Receive payment from the caller:response.pay();
It feels a little magical to me that I can write lines of code that are outputting words over the phone to a caller. And that can happen with complex logic, branching, and looping.
Another really great thing I found about working with Twilio is that they have developer friendly documentation and tools. When I was having some problems with my JavaScript functionality, I was able to use the twilio-run package to work on my functionality locally before putting it back onto Twilio’s servers. They even have a game for learning how to code for Twilio called TwilioQuest.
The Ugly side of Twilio
While the Twilio services offer so many great features, there is definitely some room for improvement. Deploying our services to the Twilio server was taking around 15 seconds, and it would be nice if that was closer to 5 seconds so the development and testing flow doesn’t have to be so tedious.
Testing a voice flow on Twilio requires calling into the set phone number and working your way through the flow. If you are developing on a function or widget in the bottom parts of your flow this means going through the top sections of the flow over and over again. It may not be possible in all use cases but it would be pretty great if we could click a button to test a flow in the browser (instead of calling) and even test a flow from a particular point. Even being able to have a flow process pause and rerun widgets (using the already inputted values again) would be great. If the deployment was faster and I could hit a button to just run a specific widget again it would speed up development significantly.
Another improvement that may be more realistic is having the “Enable live logs” toggle stay enabled for a longer period of time. It seems to turn off automatically after a few minutes and if I forget to turn it back on, I miss out on the debugging messages I have in place. The final change that I would hope for is regarding the Gather
function in TWiML. Right now to handle the users input after using Gather we have to redirect to another function (or URL); we can’t just get their input in our current function and perform the next steps. This means complex functions with a lot of Gather’ing would require a lot of endpoints for handling what to do after the Gather. I’m not sure if I’m missing a better way of doing this, but I did reach out to support and they did not offer a simpler process.
The Wrap
I am almost done work on this project and would definitely be interested in more Twilio projects in the future, but I would keep in mind that there are a few aspects of the Twilio development process that could be smoothed out for faster development times.