Files
pigway-frame-flow/docs/research/KOKONNA_CONTENT_SUBSCRIPTIONS.md
T

13 KiB

KoKonna official content and subscriptions

Checked 2026-10-02 against official public sources:

Official product materials list calendar/local weather, word of the day, traditional almanac, global travel recommendations and daily news. FAQ also lists image rotation and AI art modes (voice, text, sketch, photo style transformation). These product/widget categories are not a verified complete catalog of current mainland WeChat mini-program subscriptions. The user's daily-poetry subscription is firsthand evidence of that option; public materials reviewed do not document its subscription contract.

The current OpenAPI documents device, upload, listImages, deleteImage, image retrieval, displayImageById and displayImageByName. Device metadata includes rotation mode/interval and current image/cover; it does not document selected subscription IDs or original template data. No subscription catalog/read/create/update/cancel interface is listed. Therefore an official subscription integration is blocked on a documented provider contract, not on a Frame Flow rendering limitation.

Frame Flow displays official categories and explicit unsupported status, with links to original docs. It does not present its own poetry provider as the official subscription, fabricate endpoints, infer subscription from an image, or alter existing official subscriptions. A future documented API should be implemented in the KoKonna driver, preserving the public capability model, rather than through vendor-specific core behavior.

To complete official integration: obtain a current mini-program subscription-page screenshot/catalog and official subscription API documentation (endpoint, auth type, schema, effect of writes). Credentials or session tokens must not appear in screenshots or documentation. No private endpoint guesses or authenticated cloud writes were used in this investigation.

Follow-up: widgets versus public API (2026-10-02)

Further investigation after the user confirmed the mini-program can read the selected widget:

  • Official usage guide https://kokonna.art/pages/how-to-use calls these Smart Widgets. Step 04 describes selecting Weather, News or Calendars and automatic midnight refresh. This confirms official selection/refresh functionality; it does not document the underlying request paths or authentication.
  • Manufacturer site https://www.galaxyguide.cn/ confirms weather/calendar widgets and slideshows.
  • Additional reference https://kokonna.art/zh-hans/pages/openapi_cn fetched HTTP 200. Its documented device/image endpoints contain no widget/subscription configuration contract.
  • GitHub patrickchen914/kokonna, inspected custom_components/kokonna/const.py, __init__.py, select.py: uses galaxyguide OpenAPI gallery/image switching. No widget configuration implementation found in these files.
  • GitHub nixihz/kokonna-skill, inspected kokonna/client.py and README: exposes public image/device endpoints; no widget/subscription calls found.
  • NPM lookup for @guooscar/kokonna-frame returned HTTP 404 during this follow-up; it cannot provide current independently retrievable endpoint evidence. Earlier protocol-reference findings remain historical.

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. Device-key compatibility was subsequently tested with explicit user authorization; see the verification below.

Live WeChat verification (2026-10-02)

With explicit user authorization, a temporary localhost observer chained through the existing VPN proxy at 127.0.0.1:7890. Only robot/api.galaxyguide.cn were routed to the observer; other domains and original bypass entries retained their prior routing. Mutating RPC calls were blocked. An automatic three-minute rollback disabled/removed the PAC configuration and removed certificate trust.

Observed the user's own WeChat mini-program send appFrame.getFrame (parameter key id) and appFrame.getFrameCovers (parameter key robotId) to the RPC transport. The latter returned frameCoverRobot, tags, rows, robot. 75 widgets were returned; sanitized IDs/names/categories and argument names are retained in KOKONNA_WIDGET_CATALOG.json. No user session, device key, account credentials, photos, device IDs or actual argument values are retained.

The selected-widget metadata extractor returned null for cover ID/name during this session. This alone is insufficient to conclude the device has no widget: current-selection shape/actual state requires another focused verification. The directory's 古诗词名句 has ID 29; this must not be assumed equivalent to the user's described 每天一首诗词 without checking the actual selected item.

Cleanup verified: PAC URL (null), disabled; zero observer CA certificate entries in System keychain; observer terminated; private CA files removed; user session only existed in process memory and was discarded. Original HTTP/HTTPS/SOCKS proxy remains 127.0.0.1:7890. No official subscription/upload/display/delete writes were sent. Other NAS services and VPN application configuration were untouched.

Integration is now technically supported by live read evidence, not blocked on interface discovery. Remaining work is authenticated current-selection verification and an explicit maintainable official-session login/renewal strategy. Do not silently persist the captured WeChat session or commit it as configuration. Official RPC is undocumented and may change independently of OpenAPI.

Read-only integration implemented

GET /api/v1/devices/{device_id}/widgets returns a typed catalog, source (live, snapshot, mock), configuration status and verified current selection. The template page provides searchable official widgets, separately from local Frame Flow templates. Missing credentials show the 2026-10-02 observed catalog of 75 entries; this is explicitly a snapshot, never a live subscription claim.

For an authorized official session, configure a device in config/devices.yml:

devices:
  living-room:
    driver: kokonna
    api_key_env: KOKONNA_API_KEY
    widget_token_env: KOKONNA_WIDGET_TOKEN
    widget_robot_id: 123 # replace with the official internal robot ID
    enabled: true

Supply KOKONNA_WIDGET_TOKEN_FILE pointing to a protected mounted secret file, or inject KOKONNA_WIDGET_TOKEN. This credential is a separate official user session, not the OpenAPI device key or Frame Flow login password. No observed WeChat session has been persisted. Sessions may expire; there is no automatic WeChat login or refresh implementation yet. Successful reads are cached for 60 seconds. Raw robot data, token-bearing URLs and argument values are omitted.

Only appFrame.getFrameCovers is callable by this integration. Widget selection, subscription mutation and cancellation are not implemented or executed. A null or unmatched current selection returns CURRENT_UNVERIFIED, not “no subscription”. This private RPC contract is unofficial and may change independently of OpenAPI.

Device API Key compatibility verification (2026-10-02)

At the user's explicit request, performed exactly three read-only calls from the NAS using the configured device API Key, without logging or persisting the key:

Query HTTP Result
OpenAPI /device 200 Device key accepted
RPC app.getRobots 500 JSON-RPC error code -1, 请重新登陆
RPC appFrame.getFrameCovers 500 JSON-RPC error code -1, 请重新登陆

No RPC result was returned, and no uploads, display changes or subscription mutations were performed. The valid OpenAPI device key was not accepted as an official account session by these RPC methods. This confirms the distinction for the currently observed endpoints; it does not prove all future widget APIs will require a WeChat-specific session. An official account login session may also be supported, but has not been verified here.

QR authorization feasibility review (2026-10-02)

Rechecked the official 1.6.5 client artifact. Its observed WeChat login flow obtains a code through the WeChat provider and submits app.wxlogin with code. The account/password flow calls app.login with username and password. No QR-login creation, confirmation polling or authorization callback contract has been identified in that artifact or the public KoKonna documentation. Absence in this client does not establish that no server-side QR API exists.

A QR code opening the official mini-program does not transfer its session to Frame Flow. A functional connect-by-scan integration requires an official third-party authorization handoff (challenge, user confirmation, callback/polling and an authorized credential exchange). Generating a decorative QR or registering Frame Flow's own WeChat login is not evidence of access to KoKonna account data. Do not advertise scan-to-connect until that complete contract has been verified.

An official-account login connection is a possible alternative, pending a legitimate account and verification that it accesses the user's existing mini-program device. Frame Flow credentials are unrelated; do not ask users to enter their Frame Flow password as an official credential. The current integration only accepts an explicitly provisioned official session secret. No login attempts, new proxy changes or credential persistence were performed during this review.