This project displays the following statistics from WHOOP in a Notion database:
- Average sleep over the last 10 nights (doesn't include naps)
- Total Zone 2 cardio over the last 7 days
- Total Zone 5 cardio over the last 7 days
- Create a Firebase project with the Blaze pricing plan to enable Cloud Functions.
- Get your WHOOP client ID and client secret by setting up your developer account. You'll need a WHOOP membership & band to use the API. Set the redirect URI of your project to https://aamir.me/ for less code modification later (or any other URL you want - it doesn't matter for the purposes of the project)
- Obtain your Notion integration secret and database ID by setting up a private Notion integration for the database in your Notion workspace that you'd like to display the statistics in.
- Set these API credentials as environment variables on your local machine. Name them
WHOOP_CLIENT_ID,WHOOP_CLIENT_SECRET,NOTION_INTEGRATION_SECRET, andNOTION_DATABASE_ID. - Create a python 3.8+ virtual environment named
venvinsidefunctions/andpip install -r requirements.txt. Keep the virtual environment activated. - Navigate to the root directory of the project and run
testing/get_new_tokens.py. You may need to adjust the redirect URI in this file to match the one you provided to WHOOP. Follow the script's prompts to obtain your WHOOP access and refresh tokens. Set them as environment variables namedTEMP_WHOOP_ACCESS_TOKENandWHOOP_REFRESH_TOKEN. Note that the access token expires after about an hour, so if you're unable to deploy the Firebase Cloud Functions by then, you'll need to repeat this step later to get new tokens. - Install the
firebaseandgcloudCLIs. - Run
firebase initin the root directory of the project and follow the steps to connect the repo to your Firebase project. - Set
WHOOP_CLIENT_ID,WHOOP_CLIENT_SECRET,NOTION_INTEGRATION_SECRET,NOTION_DATABASE_ID,WHOOP_ACCESS_TOKEN, andWHOOP_REFRESH_TOKENas secrets usingfirebase functions:secrets:set SECRET_NAME. You'll need to repeat this step for the access and refresh tokens if they expire before you can deploy the cloud functions. - Run
firebase deploy --only functionsto deploy the Firebase Cloud Functions. When the deploy is successful, you should see an endpoint for thewhoop_webhook()function (located infunctions/main.pydisplayed in your terminal. Navigate back to the WHOOP developer dashboard and enter this URL as the webhook for your project. - If you've set up everything correctly, your Notion database should update whenever WHOOP detects a new sleep or workout, and once a day around 11:35pm.
Data flows from WHOOP to the deployed Firebase Cloud Functions to Notion.
More specifically:
- WHOOP triggers a webhook (implemented in this repo as a Firebase Cloud Function) whenever a workout or sleep activity is detected.
- The Firebase Cloud function queries the WHOOP API for the required data and calculates the desired statistics.
- The function then pings the Notion API to write the statistics into a Notion database.
- This process is also triggered by the daily reconciliation function (implemented as a scheduled Firebase Cloud Function).
- Finally, another cloud function runs every 45 minutes to refresh the WHOOP access token.
testing contains useful files to test the APIs used in the project.
functions/main.py contains the Firebase Cloud Functions. This file contains all code that interacts with Google services (Firebase Cloud Functions, Google Cloud Secret Manager)
functions/helpers is a local Python package that contains two helper files, notion.py and whoop.py. All code that interacts with each of WHOOP's and Notion's API is contained in these files.
A big thank you to Gordie White's whoop-order-ingestion project which informed the technical approach to this project.
