Recently, younger residents of British Columbia (BC) became eligible to get vaccinated against COVID-19, which is awesome news! If you live in BC, I encourage you to register to get vaccinated as soon as possible.
As I was getting ready to register myself, I quickly learned that all of the appointments that were available near me were all the way in June, which is still some time out. Not terribly bad, but I was wondering if I can get my first shot sooner. I’ve heard about folks who were cancelling their existing appointments and therefore making their previous time slots available, but I had no visibility into the process on the vaccination registration site. Another tricky part with the local vaccination appointment website was that once I registered, I could not easily switch appointments without cancelling the existing one that I had, which meant that I could potentially delay my vaccination even further.
For me to find the right time slot using the site, I needed to constantly re-type nearby city names, select one of the available facilities, then select the day, and finally - see if there are any times that fit my schedule.
As you can see - not the most efficient workflow for finding up-to-date appointments that are in the near future quickly. As any engineering would do, I decided that I was too lazy to spend time mindlessly clicking around, so instead I thought that maybe I can use my programming chops to automate this process.
What I wrote does not do anything with registration - it merely finds available appointments for a location using the same Application Programming Interface (API) that the website is using. To register for a vaccine, you will need a valid registration key and your Personal Health Number (PHN), both managed by the Government of BC.
My first step was to look at how the registration site works. Using the network inspector in my web browser, I realized that there are three things happening when entering a city in the search box:
- The service gets a list of facilities for the location if the city/town is valid.
- For a selected facility, the service then gets a list of available days.
- Lastly, for a selected day, the service gets a list of appointment time blocks.
All of these steps were done through their own, separate HTTP API calls. Through the network inspector in the web browser, I saw that the requests were all going to the same URL:
Looked fairly simple -
POST requests that sent
application/x-www-form-urlencoded content, that in turn contained three key components:
- A JSON message, that tells the service what information it needs to get.
aura.contextJSON blob, that contains application information.
aura.tokenvalue, that is undefined.
None of the requests required any authentication or credentials. What that meant is that I can wrap them in some C# code, and issue the calls in bulk instead of clicking around on every single facility on the web page. I could also substitute city values and search for another location near me to get the latest vaccine appointment.
My entire console application ended up looking like this:
Keep in mind that because the program is so simple and I had very little time to put this all together, there is no proper exception handling or any kind of performance optimizations. I just wanted to get a working prototype going.
You might’ve noticed that the heavy lifting here is done by the
BCVaccinationAPIHelper class, that wraps the messages that need to be sent to the appointment service. It ended up being much less complex than I expected:
Remember the three calls that I outlined above? This class implements all of them. For each method, a special string is used, that is formatted on the fly with the information from the program snippet I outlined above, such as the facility ID or the day ID. Classes such as
AuthoritativeVaccinationFacility are nothing more than a nicely wrapped object for the JSON that is being returned by the vaccination appointment service. And those can be generated automatically with Visual Studio if you copy and paste the JSON content you see flowing from your browser to the service through the Paste Special functionality.
I intentionally did not include application context in the request above, since I am not certain whether it includes my own information, but it can be read if you look in your web browser network inspector, under the
aura.context field being passed to the service.
Running the simple console application, the calls to the service were sequentially executed, and I got a full list of available appointments at the time when the application ran.
Now this is time-efficient, and really making my skills useful for something - finding when someone cancelled an appointment, which allowed me to cancel my existing appointment and book one closer time-wise. You can check out the project on GitHub.
The big question - did it work? Indeed - I managed to find an earlier appointment that was made available by someone cancelling, and I got my first shot just the other day.
Finally feeling hopeful about where we’re going with the pandemic.
Instead of some conclusion, I just want to say thank you to all the healthcare and essential workers, the scientists, and the many people that did and continue to do their part in helping us get through this, hardly easy, time. A special shout-out to my wife Tiffany, who helped me properly inspect the data.