lynixfur / LynxVR

15 stars 2 forks source link

[Implementation Details] Stromno App support #6

Open Zetaphor opened 1 year ago

Zetaphor commented 1 year ago

I'm working on an implementation for a friend who owns the Stromno app for Apple/Samsung/WearOS in Logix and I figured I'd share my findings here since it's a fairly simple implementation.

When you setup the app for OBS integration it gives you a URL. The UUID on this URL appears to be static and tied to the users account.

Ex: https://app.stromno.com/widget/view/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

That page connects to the makes a POST request to the API URL:

https://api.stromno.com/v1/api/public/rpc

And sends along this payload:

{
  "method": "getWidget",
  "jsonrpc": "2.0",
  "params": {
    "widgetId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
  },
  "id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}

Note that widgetId is the same UUID from the URL. The id field doesn't seem to matter for our purposes.

That request responds with the following JSON:

{
  "jsonrpc": "2.0",
  "result": {
    "metaId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
    "predefinedWidgetId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
    "id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
    "profileId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
    "createdAt": "2022-12-31T11:54:54.165929Z",
    "premium": false,
    "note": {
      "name": "default",
      "description": "Stromno bpm widget"
    },
    "configuration": {
      "bpmConfiguration": {
        "font": "Audiowide",
        "fontColor": "#ff00ffff"
      },
      "imageConfiguration": {
        "animated": true,
        "colorMode": "Static",
        "imageColor": "#ff00ffff"
      }
    },
    "ramielUrl": "wss://ramiel.pulsoid.net/listen/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
    "premiumUpdate": false
  },
  "id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}

The property of interest here is the ramielUrl, which is the secure websocket URL that provides the actual heart rate data. This URL also appears to be static and tied to the user account. As the saying goes, the S in IoT stands for security!

Once you connect to the websocket you get back the following messages:

{
  "timestamp": 1674140760017,
  "data": {
    "heartRate": 87
  }
}

Since it appears all of these URL's are static, once you setup the websocket URL you should be able to set it and forget it. Alternatively I would not be surprised to learn this API doesn't have any kind of CORS or other restrictions that would stop you from just pasting the URL into your app and getting the requests yourself.