The other day I joined a Telegram channel related to health and fitness. For accountability purposes, the channel had a bot which you could use to track your sleep, workouts, and other activities. You had to do it manually.
Considering that I already track my sleep and meditation minutes, I started to wonder why I had to do it manually. What if there was a way to automatically upload my health data to the Telegram bot? 🤔
Turned out, it is not quite straightforward as I expected. There are two caveats:
- Apple doesn’t provide a HTTP API to access your Health data
- Telegram doesn’t allow you to send messages between bots
To circumvent the first issue, I created an iOS app which would read Health data generated by other iOS apps and upload it to Telegram.
To enable HealthKit read access is pretty simple: just add a HealthKit capability and add Privacy — Health Share Usage Description to your app’s Info.plist.
We are going to make a very simple app which pulls your sleep and mindfulness data automatically in the background.
First, we need to authorize HealthKit. Let’s do that as soon as the app launches. Add the following code to your AppDelegate:
Now, let create the HealthKitManager class. Lets define datatypes which we want to read and write:
Now, let’s implement the HealthKit authorization request:
Once HealthKit authorization is granted, we want to set up background data delivery so that we can receive updates even when the app is in the background, making the whole process automatic.
For each HealthKit data type (mindfulness and sleep minutes in our case) we are going to setup a HKAnchoredObjectQuery, which would poll HealthKit store for new data. The key concept here is an anchor, which serves as a reference point for the query to identify what data was fetched the previous time to avoid redundant queries.
Since HealthKit doesn’t cache the anchor between launches, we are going to store it in UserDefaults.
The closure of HKAnchoredObjectQuery would be called once when we setup the query at the app launch, but the updateHandler will be called every time we receive new data from this long-running poll, i.e. when you reach nirvana or take your next nap.
We’d need to update the anchor in both cases to make sure we don’t pull the same data multiple times. Finally don’t forget to call enableBackgroundDelivery on the HealthKit store to make sure the query delivers updates when the app is in the background.
Once we get a sample, we process it like this:
Finally, you can create a Telegram channel, make your own bot and make it post to that Telegram channel. I wouldn’t go into details on how to do that, but if you want to make the bot send the message to Telegram, you can use the following API call:
Here is the full code for the app: https://github.com/nderkach/HealthKitTelegram
As I mentioned before, Telegram doesn’t allow to send messages between bots, and going back to my original goal of automatically tracking my fitness activity by sending the data from Apple Health to the Telegram bot, well… I couldn’t find a way to do that directly.
So I ended up quitting that Telegram group alltogether.