XKCD posted about Bun Alert, I thought it'd be a quick build, and it was.
What Does It Do?
Users subscribe their phone number to the Bun Alert system, and receive new SMS alerts when a Bun is spotted. In other words, it functions exactly as described in the original webcomic:
I plan on also having alerts include an image link to a photo of the spotted Bun, since not everyone subscribed will actually be nearby whenever a Bun is found. But one can hope.
Can I Use This? Can I Build My Own?
Yes, you can subscribe here! https://bunalert.jgreenemi.com/ It looks like this on mobile:
Also, yes, you can build your own using the Github repo here! https://github.com/jgreenemi/BunAlert
How Is This Built?
While this did involve a little more effort than I'd originally anticipated, building Bun Alert remained an afternoon-length project as almost everything is done quite simply via multiple services in AWS. The diagram above gives an overview of what services are involved.
- The user first opens the webpage for subscribing to the Bun Alert system. The domain is hosted in Route 53, so that's the first AWS service we hit.
- The domain name for the site is an A Alias (or AAAA Alias if you have IPv6 enabled on your device) for the Cloudfront distribution that fronts the API Gateway resource. (This distribution is provided when you set up API Gateway.)
- API Gateway is set up to invoke a Lambda function when new requests arrive.
- Lambda holds our Flask app. This is where we have our page routes defined. In a traditional architecture this would be a webserver running our Python code, but this is a serverless build, so the webpage response and the request processing is all done in Lambda.
- At this point one of two things will happen: if the user accesses the main page and subscribes a new phone number, the Flask app will hit SNS and add a new subscriber to the SNS Topic for Bun Alert. If it doesn't error out, the user is given a success page to confirm. Alternatively, if the user is the operator of the app and accesses the alert page, they can push out a new message to the SNS topic. When a new message is published, an SMS message is sent to all the subscribers on the Bun Alert topic.
- The user receives the SMS message, is then aware of the existence of a Bun, and our loop has completed.
In addition to the above architecture description, there is an IAM policy on the SNS topic for Bun Alert to allow the Lambda function to manage subscribers and to publish new messages to the topic, otherwise the Lambda function would fail. There is also an ACM certificate on the API Gateway's custom domain name - you can't set up a friendly URL for your API without a certificate.
If this sounds like a lot, it can seem like it. Luckily, the project was sped up greatly by using zappa for the creation of the necessary AWS dependencies, and for automating the actual deployment process. I make my code changes and then
zappa update and it's live a minute or two later.
To dive into the actual build, take a look over the Github repo here.
Things I'd Like To Improve
- I'd really like a confirmation message to be kicked to the new number so they can confirm that they've been subscribed, and to give them their opt-out choices. At present, they have to wait until an alert is pushed to them before they can opt-out as Bun Alert doesn't have a dedicated short code number they can hit ahead of time.
- Additionally, I've no webform option for unsubscribing numbers on the site itself. They'd have to contact me directly to have their number unsubscribed, or else wait for an alert and respond to it to opt-out.
- When subscribing new numbers, a valid number will always return a success message to the webform, even if the number is already a subscriber. This means if someone didn't remember if they'd already subscribed, and punched in their number, it'd look as though they'd subscribed for the first time, possibly creating user confusion.
- The webform page to send new alerts relies on an IP address whitelist to prevent world-wide access to make publish new messages. This is not robust, as it means I have to do a code push every time I want to allow another IP address to reach the alert page, and means I can't make new alerts while I'm out and about as cell phones get new public-facing IPv4 addresses all the time when you're not on Wifi.
It's Bun Alert - does what it says on the tin. Give it a try if you haven't already!