From 63058e979a8240404b0675f880ff89e7e6b677b1 Mon Sep 17 00:00:00 2001 From: Pigway Date: Fri, 2 Oct 2026 15:48:33 +0800 Subject: [PATCH] Document verified official widget RPC contracts from Android client --- .../research/KOKONNA_CONTENT_SUBSCRIPTIONS.md | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/docs/research/KOKONNA_CONTENT_SUBSCRIPTIONS.md b/docs/research/KOKONNA_CONTENT_SUBSCRIPTIONS.md index 9c545d8..b4f9db1 100644 --- a/docs/research/KOKONNA_CONTENT_SUBSCRIPTIONS.md +++ b/docs/research/KOKONNA_CONTENT_SUBSCRIPTIONS.md @@ -28,3 +28,25 @@ Further investigation after the user confirmed the mini-program can read the sel **Correct interpretation:** public API documentation does not list widget/subscription configuration endpoints. This is not evidence that the official client lacks internal APIs. Since the mini-program displays selected configuration, some official client/backend mechanism provides it; a separate authenticated internal API is plausible but remains an inference. No actual widget endpoint name, HTTP method, request/response schema or authorization model has yet been verified. Do not label the integration impossible merely because it is undocumented. Next verification should observe the user's own authorized mini-program read requests when opening widget selection/current-widget settings. Capture only the necessary request path, method and sanitized JSON; do not export login tokens, cookies or full network archives. Begin with read-only inspection and keep subscription mutations separate. The public device API key must not be assumed equivalent to mini-program user authentication. + +## Direct client evidence: official Android 1.6.5 + +The official download page https://kokonna.art/pages/download-app links `nightly_build_1.6.5.apk` from its own CDN. Downloaded for static inspection only; not installed or executed. APK bytes: 23,149,381. SHA256: `8f611bf74bbda70e7e7a5d087e4065dc6000849dcd2f12538d5ff5017c91e1c0`. Evidence resides in `assets/apps/__UNI__2C90476/www/app-service.js`. No vendor source or APK is committed to this repository. + +**Found transport:** `POST https://robot.galaxyguide.cn/api/rpc`, JSON-RPC 2.0, envelope `jsonrpc`, `method`, `params`, `id`; result at `result`. Authorization is Bearer **official user session token** from login/storage, not proven compatible with OpenAPI device key. + +| Client method | Parameters seen | Evidence / use | +| --- | --- | --- | +| `appFrame.getFrameCovers` | `robotId` | Widget selection page; reads `robot`, `rows`, `tags`, `frameCoverRobot`. | +| `appFrame.getFrame` | `id` | Device detail; reads `robot`, `frameImage`, `imageCount`, sync metadata. | +| `app.getRobots` | See client/device discovery; schema still to verify | User device discovery. | +| `appFrame.setFrameCover` | `robotId`, `coverId`, optional `args` | Selects/configures widget. WRITE: not executed. | +| `appFrame.setFrameCover` | `robotId`, `coverId: null` | Removes current widget. WRITE: not executed. | + +Current widget is explicitly determined from `frameCoverRobot.frameCover.id`; user configuration comes from `frameCoverRobot.args`. UI compares selected rows with `robot.frameCoverRobot.coverId`. Therefore the mini-program-style current-template capability has a concrete client contract, not merely an image-ID inference. + +Client category keys: Weather (天气), Lunar (农历), Calendar (单向历), Countdown (倒计时), Stopwatch (正计时), DailyRandom (推送), plus feature/current filters. Specific poems/news/etc. are server-provided `rows` names, not an exhaustive hardcoded list. The daily-poetry item cannot be mapped to a numeric cover ID until authenticated directory data is read. + +Authentication paths observed: `app.login` with username/password; `app.wxlogin` with WeChat login code returns user token. Frame Flow login account is unrelated. App code alone does not prove Android and WeChat versions use identical methods, nor guarantee this private API stays compatible. + +No authenticated requests or live widget writes were sent. Next step is official-account read-only verification of device discovery and `getFrameCovers`; requires legitimate official session/account access. Keep session secret server-side and out of logs, front-end, SQLite plaintext, and Git. Do not send existing OpenAPI key to this separately authenticated transport speculatively.