My Experience With Twilio For Voice #
Overall, Twilio has had a great experience. It's easy to set up and use, and the documentation is comprehensive. However, there are a few critical aspects to consider when using Twilio for calls.
The good #
It's incredibly easy to make a call. #
Twilio uses TwiML to define the behavior of the call. TwiML is a simple XML-based language that allows you to define the behavior of the call, such as the audio to play, the actions to take, and the behavior of the call when it ends.
Creating an initial call is as simple as..
1package main
2
3import (
4 "fmt"
5 "os"
6
7 "github.com/twilio/twilio-go"
8 api "github.com/twilio/twilio-go/rest/api/v2010"
9)
10
11func MakeCall(toNumber string, twimlEndpoint string) (*string, error) {
12 client := twilio.NewRestClient()
13
14 params := &api.CreateCallParams{}
15 params.SetFrom(os.Getenv("TWILIO_NUMBER"))
16 params.SetTo(toNumber)
17 params.SetUrl(fmt.Sprintf("https://example.com/%s", twimlEndpoint))
18
19 resp, err := client.Api.CreateCall(params)
20 if err != nil {
21 return nil, err
22 }
23
24 return resp.Sid, nil
25}
Making that call DO things is simple, too. #
That endpoint as defined above, however, should return a TwiML response (...). Let's do it!
1type TwilioCallTWIML struct {
2 Database database.DatabaseAccessor
3}
4
5func (t TwilioCallTWIML) ServeHTTP(w http.ResponseWriter, r *http.Request) {
6 resp := []twiml.Element{
7 twiml.VoiceGather{
8 Timeout: "8",
9 NumDigits: "1",
10 Input: "dtmf",
11 Action: "http://example.com/ivr-key",
12 InnerElements: []twiml.Element{
13 twiml.VoiceSay{
14 Message: fmt.Sprintf("Wow, so simple! Press 1 to do something.", userInfo.FirstName),
15 },
16 },
17 },
18 twiml.VoiceSay{
19 Message: "WHY DID YOU NOT PRESS 1!?!",
20 },
21 }
22
23 twimlResult, err := twiml.Messages(resp)
24 if err != nil {
25 log.Errorf("Failed to generate TwiML: %s", err.Error())
26 api_helpers.WriteResponse(w, api_helpers.APIResponseError{
27 Reason: "failed to generate TwiML",
28 Details: err.Error(),
29 }, http.StatusInternalServerError)
30 return
31 }
32 w.Write([]byte(twimlResult))
33}
This code will:
- Play a message to the user
- Gather input from the user
- IF no input, play "WHY DID YOU NOT PRESS 1!?!" to the user
It's honestly quite simple. The /ivr-key endpoint can then do any processing required, and serve up more TwiML to finish up the call (or do whatever else you need). You can get the ivr key pressed by using FormValue:
1digits := r.FormValue("Digits")
At any time, you can also use VoiceRedirect to redirect the call to another TwiML endpoint:
1twiml.VoiceRedirect{
2 Url: "https://example.com/oh-my-a-redirect",
3},
Getting an Incoming Call #
It's nearly identical to the outgoing call example, but you need to register the webhook within the Twilio console.
The Not Great (TM) #
Answering Machine Detection (AMD) #
"Near 100% Detection" MY ASS. I had about 30% accurate detection, AFTER tweaking the settings.
I just couldn't get it to work properly. It's a shame, because it seems like it'd be a powerful feature. I reallllly wanted to be able to play a certain message to a voicemail, but I had to eventually say c'est la vie and have a gap in voicemail, prior to falling back to "WHY DID YOU NOT PRESS 1!?!" (nicer in production, of course).
Like so many things, from a Consumer POV, I love the idea of robots having a hard time detecting answering machines. From a developer POV, I hate the idea of robots having a hard time detecting answering machines.
No Terraform! #
What is this, 2013? I need Terraform.. EVERYWHERE! Ever since switching to Terraform for literally everything else, I've saved so much time and effort. It's a game changer for infrastructure management. Not touching a UI to configure things is my dream.
Conclusion #
Twilio is a powerful tool for building voice applications. It's easy to use and has a wide range of features. However, it's not perfect. There are some limitations, such as the lack of (good) support for answering machine detection. Despite these limitations, Twilio is a great tool for building voice applications.
give me some feedback on bluesky: @kv.codes