Grabbing a restaurant table with Google Cloud
My family were paying a visit to London earlier this year, and it seemed like a good opportunity to show them the London institution of Dishoom.
Famously this restaurant isn’t big on prebooking preferring to keep most of their tables for walk-up diners, who are often found queuing for hours outside each location. This isn’t something that gels well with a day trip to London when there might be a better way to spend the day!
With so few tables and my poor planning, there was no availability at all when trying to reserve a table earlier this week. After checking back a few times without luck, it seemed like a good opportunity to try and automate the process, and maybe learn a little more about using a public cloud in the process.
The API
The reservation website seems pretty simple. With the Chrome developer inspector we can see that the simple form makes an API call for each enquiry:
https://loyaltystagingapi.wisely.io/v2/web/reservations/inventory?merchant_id=273918&party_size=2&search_ts=1554555600000&show_reservation_types=1&limit=3
With parameters for merchant_id
(this varies per restaurant), party_size
and search_ts
as a Unix timestamp for
the query. Neat!
For my search, this was returning a JSON response with an array named times
that was empty, but it was easy enough to
inspect this response by checking a different date far enough in advance.
Design
At a high level I wanted to poll this API to continually check for availability of a table. If one became available it would be necessary to book it pretty quickly before it was taken. Automated booking is pretty tricky, so I’ll settle just to receive a notification instead!
[ Scheduled event ] -- [ API query ] -- [ Notification ] -- [ Booking ]
I wanted to build something in Google Cloud, mainly because I was slightly more familiar with it than AWS.
Scheduled events
Google Cloud provides a Cloud Scheduler as a managed cron job service - exactly what we need to initiate scheduled events. It also integrates with Google Pub/Sub, which leads to…
Cloud functions
Google Cloud Functions allow some simple code to be run serverless in the Cloud Platform. They can be triggered by a number of events, including HTTP calls, but more relevantly by events in the Pub/Sub stream. These kick off background compute events to run our own functions.
Notifications
There are a few options here depending mainly on how I wanted to receive the notification itself!. SMS would be a good old-fashioned approach, but obviously has associated costs. However unlike Amazon’s SNS GCP doesn’t include this capability, instead recommending hooking out into Twilio.
Sending email would be possible, but this still needs to be routed through an email service. Then I’d also have to make sure that my email provider was giving them a high enough priority!
Finally push notifications are an obvious choice, but they require a companion app to be installed on the mobile device - which might be a bit overkill for a short evening project.
Step in IFTTT
IFTTT is a great platform for building small projects that integrate together. Already having the app installed, it was only necessary to build a new applet and that could translate a trigger into a pretty (and actionable!) push notification.
Building it out
It took an extended evening to get everything working.
First I created the cloud function thinking that it would be easiest to get this running locally. I chose to use the node engine rather than Go because it still seems significantly better documented on Google’s side! However, I still had problems running the engine locally, so ended up making pretty frequent deployments of the function.
When this was mostly working, I added a webhook to fire the push notification to my phone using IFTTT. Because I was happy with a range of times and restaurants I played around with parameterising the webhook to make the notification more immediately actionable.
Using cloud scheduler, I configured scheduled a polling event to run once every five minutes. I hoped to not require the script for too long, so a relatively high frequency didn’t seem too problematic. Then the cloud function was set up to be triggered by the an event being published to the same topic that the scheduler was publishing to.
Result
🥳