How I competed at Imperial’s hackathon by creating a fitness app

Jaafar Rammal
Terra
Published in
7 min readFeb 23, 2022

I’m Jaafar, an EIE student at Imperial College and SWE at Terra. Earlier this month, I participated in ICHack 22, one of the largest UK hackathons hosted, by Imperial students! Over a weekend, participants had to build something… cool.

Submissions ranged from web-based products to hardware or VR applications! These would then be qualified for and judged in one of the various prize categories (educational product, entertainment product, etc…).

We had to build something within a few hours, so my friend and I went with the Entrepreneurial category and focused on a health and fitness product.

The Idea: Hubby

My friend has an Apple Watch, and I have a Fitbit. We can track workouts and calories, set goals, and even get nudges to complete our daily targets. However, each device’s data and insights are isolated in their own ecosystem, which makes it hard for us to compare our activities or track challenges together.

Thus, we started building Hubby.

Hubby is the hub for workout buddies. Bearing in mind we were targeting the Entrepreneurial category prize, we planned for Hubby’s concept to have two main components:

  • From a UX perspective, we focused on a gamification approach to build the user base. As a user, you can connect your fitness wearable, set fitness score targets, and compete with your friends in various score-driven challenges to earn vouchers and discounts.
  • From a business perspective, vouchers and discounts would be sponsored by growing or existing fitness and health businesses e.g, a Huel protein shake or a PureGym day pass. These businesses would benefit from the access to a fitness-driven (and hence suitable) user base.

With a plan in place, we got started with hacking!

Building Hubby

To build Hubby, fitness data needed to be pulled and normalised from the different providers before we could even start building the user experience. Thus we decided to use Terra to save us time and focus more on the end-user actual features we had planned. Our system implementation started looking something like below, where Terra would provide us with the fitness data, and we would use it in Hubby to compute scores and present vouchers:

Hubby’s integration summary

I want to show you in the next few paragraphs how we executed the plan and the different steps we took as devs to build Hubby. I will not go through the full implementation details as we had multiple iterations, but I will still show how got started and achieved a presentable MVP within 20 minutes! This will include a few dev steps for those interested in replicating Hubby’s MVP.

MVP Implementation

We decided to start off with the backend, and went on using NodeJS. The backend had to handle users connecting their wearables, as well as pulling data from the different wearable providers.

We started with setting up an express server and creating the various endpoint in our index.js entry file:

mkdir server && cd server
npm install express body-parser dotenv

For a quick test, we ran the server with node index.js, and a GET request on localhost:3000 returned “Hello from Hubby” successfully!

Connecting Wearables

To connect fitness wearables to Hubby, we decided to use Terra, as the full connection workflow was handled through their API. After signing up on Terra’s dashboard and getting our API KEY and DEV ID credentials, we added those to the backend’s .env file and loaded them to the process environment using dotenv:

Getting Terra API credentials
Adding credentials to .env
Loading credentials into process environment using dotenv

With the credentials in place, we could now use Terra to connect the wearables to our backend. Terra’s API comes with an NPM package terra-api. After installing it, we initialised a connection instance:

npm install terra-api
Initialise Terra connection

To add a wearable, we had to use the API’s widget session endpoint, which would automatically manage connecting user wearables. We added this endpoint to our backend with a list of providers we wanted to support:

Session to connect a wearable

We tested it with a curl localhost:3000/session :

jaafarrammal@Sableur-Terra-Mac ~/D/D/T/server (master)> curl http://localhost:3000/sessionhttps://widget.tryterra.co/session/ff781505-87a6-465b-b7fe-55f71d611270

When we visit the URL provided by the API, we’re able to select a provider and go through a connection flow!

Prompt to select and connect a wearable
Prompt after connection is completed

BOOM! We had a connection flow to add wearables.

Pulling Fitness Data

The connection through the API would return us a unique user ID for that connection. With this user ID, we added an endpoint on the backend to pull fitness data using the API:

The fitnessSummary and fitnessScore functions are our custom implementations of computing a user fitness score or fitness summary. We decided to go with a simple summation, although a more scientific equations could have been formulated using additional metrics like sleep, activity intervals, or heart rate variability:

Fitness summary
Fitness score

And voilà! We now had a backend which could connect user wearables and return fitness scores and summaries!

Frontend: Connecting User Wearable

For the frontend, we decided to use ReactJS. We started by setting up with:

npx create-react-app terra-hubby --template typescript

We also added bootstrap to our public/index.html:

<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">

For the connection flow, we decided to simply cache the user IDs in a cookie instead of creating a full database (since it’s a hackathon, and we needed to get things done quick). The Terra API to connect a wearable had an option to return the user ID in the session URL after the connection was completed. Our frontend flow became the following:

  • Check if there is a user ID in the cookie
  • If yes, simply pull the fitness summary and score from the backend
  • If not, request and connection session from the backend, redirect the frontend to this session to connect a wearable, and write the user ID to a cookie when the connection is completed.

Our code on the frontend now looked something like this in App.tsx:

It seems a lot, but here is what’s happening in the App function:

  • Within useEffect we check if the URL is coming from a successful connection session redirect. If so, it will contain a user ID that we can save in a cookie
  • We then attempt to load a user ID from the cookie
  • If there isn’t a user in the cookie, we request a connection session and redirect the user to that session. When they complete the login, they are redirect to localhost:3000?user_id=.... which allows the code to fetch that user ID!
  • If there is a user in the cookie, we set it in the app state so we can pull data from the backend

Obviously, a more robust user auth handling could be added on the frontend side, but since it’s a hackathon… nobody cares about error handling :)

Testing again! We visit localhost:3000, and as expected we get redirected to the connection session, and once we finish connection, we could see the user ID on the screen!

Automatic redirect to widget to select wearable
Frontend has now authenticated the user

Displaying User Data

With the user ID in hand, we could query the backend for the fitness data and display it.

In our App.tsx, we created:

  • A card function to display the data
  • A handler to query the server for the fitness data

This ended up being out card function

Which gets us a card looking like this:

We then added the handler to query the data:

Finally, we added a card for each metric:

And here was the final result! Upon landing on the page, the user was redirect to connect their wearable. After connecting, they could see a fitness summary and their fitness score!

Data display screen on MVP
MVP in action

Hackathon outcome

After getting this simple flow working, we started added the other components (a nicer UI, a scores screen, a voucher screen, etc…). At the end, our app looked something like this:

The different app pages: Fitness Summary, Leaderboard, Wearable Connection, Prizes

Our final submission is also available to check on Devpost, with the following demo video!

Demo of Hubby’s concept and components

Although we did not end up winning the Entrepreneurial category prize (ouch :/), the learning experience itself was personally worth it, alongside the mini-events at the hackathon such as midnight pizza, or 3 AM karaoke! And, of course, a no-sleep weekend followed by 14 hours of sleep the next day :)

--

--