banner
Vinking

Vinking

你写下的每一个BUG 都是人类反抗被人工智能统治的一颗子弹

Sync Apple fitness records to display on the blog

Preface#

In the Shiro theme, there is a “Personal Status Display” feature that can showcase some custom statuses.

To make full use of this feature, I wanted to synchronize the fitness ring data from my phone to display in my personal status, as shown below:

Effect Image

Initially, I planned to implement this idea by writing a JavaScript script and using the Scriptable app. However, after trying, I found that Scriptable does not support HealthKit, making it impossible to access health data. On Apple devices, apps need to access health data through the HealthKit API, and Scriptable attempted to integrate HealthKit but was rejected by the Apple Store. Therefore, I had to settle for using Apple's built-in Shortcuts to achieve this functionality.

Status Display Settings#

By manually setting the personal status display, you can see that the page sends a request to https://{backend server}/api/v2/serverless/shiro/status via POST in the console:

Personal Status Display Request

The request body contains a JSON formatted like this:

{
	"emoji": "😴", // Emoji at the bottom right of the avatar
	"desc": "Consumed 0 kcal energy Exercised 0 minutes Stood 0 hours", // Expanded description
	"ttl": 60 // Duration of the status, in seconds
}

To complete the operation of updating the personal status, you need to first obtain an access token and construct the request header Authorization: bearer {token} for user permission verification.

There are two ways to obtain the access token. The first method is to initiate a login request before setting the status each time, and you can get an access token in the format xxxxx.xxxxxxxx from the JSON returned by the login request.

The second method is to create a new access token in the backend under Settings -> Security -> API Token in the format xxxxxxxxxxxxxx. This method is recommended.

After obtaining the access token, verify it in the console:

const token = "xxxxxxxxx";
fetch("https://server.vinking.top/api/v2/serverless/shiro/status", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    Authorization: token,
  },
  body: JSON.stringify({
    emoji: "✌️",
    desc: "Test",
    ttl: 60,
  }),
})
  .then((response) => {
    if (response.ok) {
      return response.text().then(() => {
        console.log(`User status set successfully, status code: ${response.status}`);
      });
    }
  })
  .catch((error) => console.error("Error setting user status:", error));

Status set successfully.

Set Successfully

Designing Shortcuts#

To automatically synchronize health data to the personal status display, a shortcut needs to be designed that can retrieve health data, construct requests, and call the API. The design concept is as follows:

Concept

There are a few pitfalls to note when converting the flowchart into a shortcut:

  1. If a certain type of data has no records for the day (e.g., no exercise), the shortcut will return a null value instead of 0. An initial value of 0 needs to be set in advance to avoid issues with subsequent concatenation of description text.
  2. If you want the data to be consistent with the fitness record panel data in Apple Health, special attention must be paid to the statistics for "Stand Hours." It reflects the number of times the goal was met, not the actual standing duration. The calculation logic is: as long as the cumulative standing time reaches or exceeds 1 minute within an hour, it counts as 1 hour met. For example, standing from 08:00 to 08:01 and from 09:30 to 09:31 will be recorded as 2 hours met. In contrast, the "Stand Time" retrieved by the shortcut is the actual minutes of standing each time. Therefore, to count "Stand x Hours," you need to count whether the goal was met each hour instead of directly summing the standing minutes. The instruction is expressed as follows:

Count Met Instances

  1. When the interface successfully sets the status, it only returns a 204 status code without any content, and since the shortcut itself does not support detailed judgment of HTTP status codes, you can only confirm whether the setting was successful by checking if the returned file size is 0.

Since the shortcut is too long, I will place the shortcut at the beginning:

The complete process of the shortcut is as follows (super long image warning):

::: masonry
image
:::

This article is synchronized and updated to xLog by Mix Space. The original link is https://www.vinking.top/posts/codes/sync-fitness-records-to-blog-status

Loading...
Ownership of this post data is guaranteed by blockchain and smart contracts to the creator alone.