# Kosmi WebSocket Protocol Findings ## Key Discoveries from Browser Monitoring ### Room ID Format - Browser uses `"@hyperspaceout"` (WITH @ symbol) for all operations - Our script was using `"hyperspaceout"` (WITHOUT @) - this is why `joinRoom` failed with `ROOM_NOT_FOUND` ### Page Load Sequence The browser does NOT call `joinRoom` mutation. Instead, it: 1. **Connects to WebSocket** at `wss://engine.kosmi.io/gql-ws` 2. **Sends `connection_init`** with auth token 3. **Immediately starts subscribing** to various topics: - `OnNewMessage(roomId: "@hyperspaceout")` - for chat messages - `OnLinkedMembers(roomId: "@hyperspaceout")` - for room members - `OnMediaPlayerUpdateState(roomId: "@hyperspaceout")` - for media player - `OnMediaPlayerUpdateSubtitles(roomId: "@hyperspaceout")` - for subtitles - `OnMediasoupUpdate(roomId: "@hyperspaceout")` - for WebRTC - `OnRoomUpdate(roomId: "@hyperspaceout")` - for room state - `OnMessageReadersUpdate(roomId: "@hyperspaceout")` - for read receipts ### Sending Messages To send a message, the browser likely uses: ```graphql mutation SendMessage($body: String!, $roomId: String!) { sendMessage(body: $body, roomId: $roomId) { ok } } ``` With variables: ```json { "body": "message text", "roomId": "@hyperspaceout" } ``` ### Authentication The `connection_init` payload includes: - `token`: JWT from `anonLogin` mutation - `ua`: Base64-encoded User-Agent - `v`: App version "4364" - `r`: Empty string for anonymous users ## Next Steps 1. ✅ Use `"@hyperspaceout"` (with @) instead of `"hyperspaceout"` 2. ✅ Skip the `joinRoom` mutation entirely 3. ✅ Just send the `sendMessage` mutation directly after `connection_ack` 4. Test if the message appears in chat ## Important Note The `sendMessage` mutation returns `{ ok: true }` even when the message doesn't appear in chat. This suggests that: - The mutation succeeds on the server side - But the message might be filtered or not broadcast - Possibly because we're not "subscribed" to the room's message feed - Or because anonymous users have restrictions We should subscribe to `OnNewMessage` to see if our sent messages come back through the subscription.