BlasterHacks is the new annual hackathon hosted by the Colorado School of Mines’ ACM chapter. This year was the inaugural year of this iteration of BlasterHacks; with over 50 people participating it could be considered a smaller hackathon but I would say it has the energy of 5 times that.
This also happened to be my first hackathon I officially participated in. I found the experience quite enjoyable! The team I participated with formed last semester already as Elijah Potter started asking people he wanted to write software with if they wanted to do BlasterHacks, naturally I said yes.
Come February 9th we all started piling into the newly opened Labriola Innovation Hub Building. However, at this point our team (Byron Sharman, Elijah Potter, Grant Lemons and I) hadn’t decided what to build. A few weeks prior we had discussed and started listing a decent number of ideas we thought could be worth exploring.
We ended up settling on an idea based on some research Elijah had read about exercise and sitting during the workday. The research talked about how any amount of exercise every 30 minutes would be sufficient to avoid the prolonged negative mental and physical effects of sitting. Our app which we ended up calling “StandUp” took this research and applied the pressures of social media to this as sort of enforcement mechanism. It was passionately nicknamed “BeReal for exercise.”
The software stack that we decided on was SvelteKit + Firebase. I don’t really have any major complaints about the tech stack that we chose other than my adventure with Firebase Cloud Messaging (FCM) but I’ll get into that later. I was really impressed with how quickly Elijah had logging in and viewing posts from the database working in Firebase with SvelteFire.
My role on the team was more of a free body on our team taking tasks that people were too swamped to deal with. The first major thing I worked on was getting our Apple Watch style rings working. I naively thought that this would be relatively simple to pull off… just a few CSS circular borders etc. Boy was I wrong!
Turns out the way to make circles inside other circles is to use an SVG. However, unbeknownst to the 10 or 11pm me you can use the Svelte compiler on not just HTML code but also SVGs. (Technically I did know this but I just forgot ok. It isn’t a common feature I use in my day-to-day) Stumbling my way along blogposts about making rings I eventually after 2 hours got close to the correct thing. But for some inexplicable reason they were not centering. :( I after enough incoherent frustration noises I ended up asking Elijah. He simply explained that I was using grouping wrong which was making its own origin which was why my circles were going to the top left of the SVG.
After getting some sleep, we decided that our goofy sleep deprived nickname for our project wouldn’t do and we ended up coming up with the name “StandUp.” I quickly threw together some ideas for what the logo could be and ended up with two semi-circles with a circle above. The goal of the two semi-circles was to evoke a sort of hourglass / timer feel and the circle above to help illustrate a face which would connect the whole shape as a person who is standing.
Not too much later we started getting to our critical feature: push notifications on a PWA. We expected this to be simple to implement client side, and to Firebase’s credit it was. Sadly Firebase’s push notification documentation leaves a lot to be desired. One way to send a push is that you can start a campaign in the Firebase console (which we found can take up to 5 minutes to actually deliver). The two other methods that Firebase provides are topic based push notification or an individual device notification. Since we were only interested in broadcasting globally to all out users we chose the former. But again sadly this wasn’t documented well and I accidentally led us down a hallucinated path on using the topic name “all.” Eventually we decided that I was going to setup a small service on the side. Its goal was to take every client’s identifying token and register it to a topic because for some reason the web client of Firebase doesn’t support doing that but the mobile clients do. (Yeah it probably has to do with security models but come on! Have some hackathon energy!)
I quickly cooked up a small Golang service using the Firebase SDK (That was
pretty nice to work with. Thank you Google Cloud & Golang). After what felt like
over 2 hours of building and debugging on fly.io’s remote builder. (I don’t have
enough space for full docker on my machine ok. sorry) We had a service that was
able to take a token and then push notifications out! I ended up also adding the
randomized 30 minutes on average scheduling to the push notifications in the
Golang service because it was already a long standing background worker so why
not 🤷. Heads up if you are using fly.io as a persistent runner make sure to set
the min_machines_running
to 1
not 0
. (That was at least a 30 minute
oppsie.)
// send notifications every 30 or so minutes on average
go func(msgr *messaging.Client) {
for {
randTime := (rand.Intn(20) - 10) + 30
l.Printf("sleep time %d\n", randTime)
time.Sleep(time.Duration(randTime) * time.Minute)
id, err := SendNotification(msgr, "StandUp", "Time to stand up and exercise", rand.Intn(100000000)) // pick and send a random exercise
if err != nil {
l.Printf("sending %s notification %s", id, err.Error())
} else {
l.Printf("sending %s notification %s", id, "no-error")
}
}
}(msgr)
According to our git history apparently I also built the page that allows you to
submit the workout but I have almost no recollection of this as I’m guessing
this was during the stretch of time I spent sleep deprived. In order to pull
information related to the exercise everyone is doing from the notification
service worker we used a side channel of the browser’s
localStorage
API. This allowed us to share state from the service worker that was receiving
the push and the page itself when loaded.
Judging
I almost ended up publishing this without mentioning how we did. lol.
We ended up fibbing the notification push service with a http endpoint where we could cause a notification to trigger during out discussion with the judges. This was incredibly useful in demonstrating what we had built to the judges who were on a few minute rotations. After judging had finished there was a call if more people would like to upgrade to the advanced bracket, which we ended up doing. Our team ended up winning the second place in the advanced bracket in the general track!
As a First Time Hackathon
I found BlasterHacks incredibly friendly towards beginners! Huge props to Hannah Harling and Tyler Wright for making such an amazing event and community around it. I also want to thank my teammates for making a great development environment that felt really collaborative and productive! One thing that I found curious as a first time hackathon goer is the culture of sleep deprivation in combination with caffeine products. I get why it is so common but I do not understand it, maybe I value sleep too much?
Overall it was an absolutely incredible experience but one that was backed with stress on completing homework over the next few days (which was 100% my fault for not prepping).
10⁄10 would hack again!
– Lukas