Gate Automation with Twilio


January 31, 2014Alex Guerra

My girlfriend has one of those apartment gates that doesn't have a code. Most nights that I head over to her place, I sit at the gate for five minutes in the company of two or three other cars all waiting patiently for someone to come out. If I get there at 2 AM on a weeknight I might wait 20 minutes.

An easy solution would be to just get my girlfriend to set up her phone for buzzing people in, but she's spotty on picking up anyway and what fun would that be? I had heard a while back that it was possible to use Twilio to automate this kind of thing, so tonight I thought I'd see how fast I could throw something together.

I was pleasantly surprised to find that Twilio is like the coolest most magical thing ever. Less than 30 minutes and I was live.

This is pretty simple as far as the possibilities go (maybe someday I'll make people answer random math problems to gain entry), but it works. All together it's just a basic flask app and a few static xml files. Twilio makes requests to the endpoint you specify and you return instructions in TwiMl, their own little markup language.

Here's prompt.xml. Very straightforward; it prompts and waits for the user to enter four digits. If they do, it sends a POST request to the same url with the digits as form data. If the user doesn't begin entering numbers within 5 seconds of the prompt finishing, I'll laugh in their face and the call will end.

<?xml version="1.0" encoding="UTF-8"?>
<Response>
    <Gather numDigits="4">
        <Say>This is Kristin's apartment.</Say>
        <Say>Please enter the password.</Say>
    </Gather>
    <Say>Too slow hahahahaha. Goodbye.</Say>
</Response>

Next is success.xml, which lets the user know they gained entry and then buzzes them in by playing the DTMF signal for 9 (what the gate uses).

<?xml version="1.0" encoding="UTF-8"?>
<Response>
    <Say>Nice!</Say>
    <Play digits="9"></Play>
</Response>

Then failure.xml, which lets the user know that they entered the wrong password and prompts them to try again.

<?xml version="1.0" encoding="UTF-8"?>
<Response>
    <Say>No dice. Sorry, try again.</Say>
    <Gather numDigits="4">
        <Say>Please enter the password.</Say>
    </Gather>
    <Say>Too slow hahahahaha. Goodbye.</Say>
</Response>

And finally here's the flask app that ties it all together. I was kind of bummed to find that Twilio didn't have a way to insert basic logic into TwiML; instead of just hosting a few static xml files I had to actually run a tiny webapp, but my deploy system is streamlined and I got it up quick.

from flask import Flask, request

app = Flask(__name__)
app.config['GATE_CODE'] = '5555'

@app.route('/', methods=['GET', 'POST'])
def krisgate():
    if request.method == 'GET':
        return app.send_static_file('prompt.xml')
    elif request.form['Digits'] == app.config['GATE_CODE']:
        return app.send_static_file('success.xml')
    else:
        return app.send_static_file('failure.xml')

And that's it.

This has to have been the shortest project with the least surprises I've built in a long long time; if you've been wanting to try something like this, get on it. The possibilities for the types of things you can do with Twilio seem endless and overall I was very impressed with the service.

With that my days of waiting at the gate are hopefully over. Now if I could just get my girlfriend set up the number...