Monitor your Twilio applications with SMS alerts using the Twilio App Monitor, Python and webhooks.

October 14, 2014
Written by
Paul Hallett
Contributor
Opinions expressed by Twilio contributors are their own

featured-alerts

2094749782_4f5f003c49_b
When you are using Twilio to power communications in your business or your software applications, you want to know what is going on all the time, especially if things go wrong. There are plenty of tools in the Twilio cloud to help you dissect these errors and figure out what went wrong. One particularly useful tool is the Twilio App Monitor.

The App Monitor will log every single error that Twilio encounters talking to your application- failing to validate or parse a TwiML document, or not being able to get a response back from a url. If any of these operations (and many others) go wrong, Twilio logs it in the App Monitor for you.

imageA

Please don’t make fun of how many mistakes I make

One of my favourite features of the App Monitor is the App Monitor Triggers:

imageB

There are three triggers created by default in every account that are fired on the first, tenth and one hundredth error each day. By default these triggers will send an email to you telling you about the error. You can make your own triggers for specific errors or a certain number of errors in a time period. For example: you could make an App Monitor Trigger that fires every single time a 13266 Invalid Country Code error is triggered.

We’re software people and we don’t always want to be told via email that something has gone wrong. We want to be told fast, in a more convenient way, and right now! Especially if we’re deploying some critical code and we want to make sure it works efficiently.

imageC

App Monitor Triggers can send an HTTP POST request to a URL of your choice instead of an email. This is a mechanism often referred to as a webhook. The webhook request will contain a bunch of useful information about the error that just occurred as POST data, which you can then extract from the request and manipulate in software as you chose. Maybe you’ll want to log it in a database, or send a hipchat notification to your developers warning them that the world is ending and they need to fix it.

I was recently building an application that used the App Monitor Trigger webhooks, and I realised – what is the best real time communication platform that I can use to alert myself when things go wrong? Why SMS of course and I had heard of this thing called Twilio. I decided to put a Twilio inside my Twilio, so I could Twilio whilst I Twilio’d.

What you’ll learn

Let’s build an SMS alert system that sends us an SMS message when we get App Monitor Error using the App Monitor Trigger webhooks.
In this blog post you will learn to:

  • Set up a new App Monitor Trigger with a configured webhook
  • Use hurl.it to receive mock HTTP requests to your web server with mock error information.
  • Use the Twilio REST API to send an SMS message

The only thing that you will need for this (other than your favourite programming language, we’re going to demonstrate with Python) is a Twilio Trial Account, which you can sign up to for free. It only takes 30 seconds to sign up.

Creating a new Twilio App Monitor trigger with a configured webhook

This part of the tutorial is very easy, we’re just going to go to the Twilio App Monitor in our User Account on twilio.com and click on “Triggers“:

imageD

By default, each account is given three App Monitor Triggers but we want to create a new one. Let’s go ahead and click on Create New Trigger on the right:

imageE

We’re going to make a trigger that fires whenever a HTTP retrieval error occurs. This is a fairly common error that can occur when developing with Twilio so it makes a good example. In production, I’d recommend setting up App Monitor Triggers for the most likely errors that will happen with you Twilio application. If you’re unsure what these are, check the App Monitor for a list of errors you already have – it’s likely they’ll occur again!

imageF

Here we are setting the Friendly Name to HTTP retrieval error, this is a human-readable name that will be useful for your debug team later on, so make sure it is descriptive. The Error Code we’re monitoring is 11200 – HTTP retrieval failure, which occurs when Twilio makes an HTTP request and receives a HTTP 404 status code back. We want the Trigger Value to be 1 (every 1 times, the trigger will fire) and we want to set the Recurring value to Daily.

What does this give us? An App Monitor Trigger that fires on the occurrence of an HTTP retrieval error, the first time it happens, every day.

Now for the little trick, instead of adding an email address into the field below, click on the Trigger a Webhook link on the right to turn this into a programmatic trigger:

imageG

We need to add a URL to the new field that appears.

imageH

This URL will receive an HTTP POST request when this Trigger is fired, with information on the error. The HTTP Request will send us the following parameters:

imageI

You can read more about Twilio App Monitor Triggers on the documentation page.

Finally, we can save the new App Monitor Trigger by clicking on Save.

Receiving the App Monitor Triggers in our application

Now that we have an App Monitor Trigger ready to fire, we need to write some code on our server that will receive the HTTP requests and diagnose them.

In this example I’m going to use Python and Flask (a micro web framework) to build a simple server that receives the request and creates SMS messages from them.

If you do not yet have Flask installed, you can install it with pip using this terminal command:

 

$ pip install Flask twilio

 

We’ve also installed the Twilio Python helper library at the same time.
The boilerplate Flask code we need, which will be familiar to all Flask developers, is going to be saved in a file called app.py:

 

from flask import Flask
app = Flask(__name__)

if __name__ == "__main__":
    app.run(debug=True)

We need to add a URL route on the server for the HTTP requests to go to. In Flask, we can do that pretty easily:

 


from flask import Flask
app = Flask(__name__)

@app.route('/error_trigger', methods=['POST'])
def error_triggers():
    return 'Hello Twilio!'

if __name__ == "__main__":
    app.run(debug=True)

 

The new code we’re adding on line 4 registers a new URL route in our Flask app called /error_trigger, just like the configuration we have above in our App Monitor Trigger. We’re also accepting HTTP POST methods on this line with the second parameter.

This route is linked to a function we’ve called error_triggers, which takes no parameters, and just returns a string ‘Hello Twilio’ for now. This is currently useless to us, so let’s actually intercept the request coming in and print something from it:

 


from flask import Flask, request
app = Flask(__name__)

@app.route('/error_trigger', methods=['POST'])
def error_triggers():
    error_code = request.values.get('ErrorCode', None)
    return 'The error is {0}'.format(error_code)

if __name__ == "__main__":
    app.run(debug=True)

 

The new code (on lines 6 and 7) replaces the simple Hello Twilio print statement. Instead we are getting a value out of the HTTP request (in this case, ErrorCode) and storing it in a variable. On line 7, we’re returning out the error code.

Using hurl.it to test out our application

We’ve got our application to the point where we probably want to start testing that it works. It is impractical and bad practice to force errors from a Twilio application. Instead, I discovered a great tool for sending HTTP requests called hurl.it, which lets you make HTTP requests, add headers or parameters to them, and change the HTTP methods too. It also displays the responses nicely.

Oh, and it has an awesome vomiting unicorn as a mascot, so why not use it?

Let’s go to hurl.it and configure a simple HTTP POST request, with a single parameter, ErrorCode, and fire it at our webserver:

imageJ

It’s very simple to set up a request with hurl.it, let’s click Launch Request and check out the response we get:

imageK

The HTTP response is successful (we get a 200 OK response) and the body shows us the code we wanted to return based on the value we sent to it.

Nice! We can get our application to talk to us. Let’s change the code to print out a useful statement based on some of the parameters a Twilio App Monitor Trigger might send:

 


from flask import Flask, request
app = Flask(__name__)

@app.route('/error_trigger', methods=['POST'])
def error_triggers():
    error_code = request.values.get('ErrorCode', None)
    description = request.values.get('Description', None)
    if error_code:
        msg = 'An error on your Twilio app occurred! {0}'.format(description)
        doc_url = ' https://twilio.com/docs/errors/{0}'.format(error_code)
        msg += doc_url

        return msg

if __name__ == "__main__":
    app.run(debug=True)

The new code (on lines 8 to 13) is retrieving the Description and ErrorCode value from the HTTP request and formatting it to make a nice message, including a URL link to the Twilio documentation on that error. Note that the URL won’t work on an “any error” trigger.

Let’s send another hurl.it request to our application and see what the response looks like now. I’ve modified the parameters to simulate a real error, the HTTP retrieval failure error:

imageL

and let’s look at the response we get:

imageM

Sending SMS with the Twilio REST API

This is now looking good, but we’re not actually sending any SMS messages yet, so let’s add the final bit of code to turn this message into a Twilio SMS and actually make it useful.

 


from flask import Flask, request
app = Flask(__name__)

from twilio.rest import TwilioRestClient
client = TwilioRestClient('TWILIO_ACCOUNT_SID', 'TWILIO_AUTH_TOKEN')

@app.route('/error_trigger', methods=['POST'])
def error_triggers():
    error_code = request.values.get('ErrorCode', None)
    description = request.values.get('Description', None)
    if error_code:
        msg = 'An error on your Twilio app occurred! {0}'.format(description)
        doc_url = ' https://twilio.com/docs/errors/{0}'.format(error_code)
        msg += doc_url

        client.messages.create(
            to='YOUR_NUMBER',
            from_='TWILIO_NUMBER',
            body=msg
        )

        return msg

if __name__ == "__main__":
     app.run(debug=True)

 

There is a lot of new stuff happening here, so let’s step through it all one bit at a time.
On line 4 we are importing the TwilioRestClient, which is a Python helper library for Twilio. On line 5 we instantiate the helper library with our Account Sid and Authentication Token. Our ACCOUNT_SID and AUTH_TOKEN can be found on our Twilio dashboard.

The only other code we’re adding is a few lines starting on line 16, which creates a new SMS message. The parameters given to this function include the to phone number, which is the number you want to send the message to (your phone, if you’re not sure) and the from number, which should be a Twilio number. If you do not have a Twilio number (every trial account has one), you can get a new one in the numbers panel on your account page. Finally, the message we want to send is the same message that we’re printing out.

Now, when we make the same HTTP request, we should also receive an SMS message to the phone number that we entered:

imageN

Mathematical!

What’s next?

Now if you deploy this code onto your server, your developer team will always know what is up as soon as a problem occurs.

What have we learned here? We’ve just covered the advanced topic of monitoring application errors in your Twilio Apps, setting up a webhook trigger, and using Twilio SMS through the REST API by building this nice little app.

I think it is good at this point to look at some of the best triggers to monitor in your application. Here are my suggestions:

  • 11200 – HTTP retrieval failure – Great for checking new endpoints, you will want to monitor this as soon as it happens, so set the trigger value to 1.
  • 13226 – Dial: Invalid Country Code – Occasionally users might format a number wrong and this is a good way to check if that is happening. Unless this is essential, I’d set the trigger value quite low, to catch it early.
  • 13520 – Say: Invalid Text – If you’re automatically generating text to speech, this trigger is a must-have. You’ll always get some random gibberish breaking the TTS engine.

Twilio has an extensive list of App Monitor Errors that might occur, so it is worth checking them out. Don’t forget to read the full App Monitor Triggers documentation too.