Custom SMS Webhooks with Amazon Lambda

We use Uptime Robot to warn us if sites are down or unreachable from the public side to help us diagnose edge network issues. While we all love Slack, we also like being able to turn on Do Not Disturb for it… so classic SMS messages became the best way to get our attention, even though very expensive. Since I didn’t want to keep paying so much to Uptime Robot for SMS credits, and because running out of credits and not knowing about an outage is the worst, I decided to bake my own SMS-sending-API with Lambda and Twilio.

Part 1: Web Hook Code

The web hook code is pretty simple – it takes JSON body from the incoming web request as well as some environmental variables set up in Lambda, and blasts out the SMS. Here’s the code:

You’ll need to create a virtualenv and use pip to install the twilio library. To package the function for upload to Lambda, we’ll need to include not just the code in main.py but also the libraries needed. They all need to be at the TOP LEVEL of the zip, and not inside another folder – this is a common hangup that I got caught by too!

This is the GitLab CI YAML that I’m using. You can see how I’m adding the libraries from the virtualenv to the top level of the zip folder.

 

Part 2: Twilio

If you don’t already have one, create a Twilio account and fund it. You’ll need to buy a phone number if you don’t have one already. Note both your Account SID and Auth Token on the Dashboard – you’ll need then in the next step.

Part 3: Lambda and API

If you’re not familiar with it, Lambda is an AWS service that allows you to run custom code that is called by defined triggers. It is ludicrously flexible – you can set other AWS events to trigger it, or as in our case, use the AWS API service to make a front end.

Log in to your AWS account and navigate to the Lambda service. Create a new function from scratch for Python 2.7, giving it a meaningful name. Creating the role from template is ok in this case since we don’t want the Lambda user to have access to our other services.

Next, upload the zip file with your function and all the libraries in it. Note that I haven’t been able to figure out a good way to pass tests with the built-in AWS function yet – the WYSIWYG editor doesn’t like nested JSON.

Add the two environmental variables to your Lambda function – TWILIO_AUTH_TOKEN and TWILIO_ACCOUNT_SID.

Next, add the API Gateway as a trigger. The basic setup will give you an unrestricted API, which is good for testing, but you’ll probably want to add an API key for some basic protection if you put this into production.

Publish your API when you’re happy it is working properly – the “Test” button will let you pass the JSON array in. The script above expects a to phone number including country code, the URL that is being alerted on, a friendly name for that URL, details of the alert (e.g. what the alert is checking), as well as an Alert Type integer. This is an example payload that I use to test the API:

 

Part 4: Uptime Robot Integration

Finally, we get to the reason we started the project. Log in to your Uptime Robot account and go to the settings page. Under Alert Contacts, create a new one with Web Hook type. Paste in your API url for the AWS API Gateway under the “URL to Notify” box, and include something like the below JSON for the POST Value. Ensure the “Send as JSON” box right below the value is checked.

Add this contact to the alerts you want to be, well, alerted on – and you should now receive some significantly cheaper SMS whenever your sites have a problem!