Add !votes command, fix vote tally timing, and improve Kosmi stability
- Add !votes command (IRC + Kosmi) showing per-session and all-time vote
breakdowns for the current game via new Jackbox API endpoints
(GET sessions/{id}/games, sessions/{id}/votes, games/{id})
- Fix vote tally broadcasting: remove debounce timer, announce tallies
only at game transitions or session end instead of after every vote
- Add !kreconnect IRC command to manually trigger Kosmi reconnection
- Add WebSocket ping/pong keepalive and write mutex to Kosmi client
for connection stability
- Add watchConnection() auto-reconnect on unexpected Kosmi disconnects
- Remove old 2025-10-31 chat summaries; add votes command design doc
Made-with: Cursor
This commit is contained in:
57
docs/plans/2026-03-16-votes-command-design.md
Normal file
57
docs/plans/2026-03-16-votes-command-design.md
Normal file
@@ -0,0 +1,57 @@
|
||||
# !votes Command Design
|
||||
|
||||
## Summary
|
||||
|
||||
Add a `!votes` IRC/Kosmi command that displays session and all-time vote data for the currently playing game. The response is broadcast to all connected chats via the gateway. If there is no active session, no playing game, or any API call fails, the command logs the reason and silently does nothing.
|
||||
|
||||
## Output Format
|
||||
|
||||
Matches the existing vote tally style:
|
||||
|
||||
```
|
||||
🗳️ Split the Room • 14👍 3👎 (Score: +11) | All-time: 127
|
||||
```
|
||||
|
||||
- Left side: session votes for the current game (upvotes, downvotes, net score)
|
||||
- Right side: all-time `popularity_score` from the game catalog
|
||||
|
||||
## Architecture
|
||||
|
||||
Uses the gateway-level event routing pattern (same as `!kreconnect`).
|
||||
|
||||
### Flow
|
||||
|
||||
1. User types `!votes` in IRC or Kosmi
|
||||
2. Bridge detects the command, sends `EventVotesQuery` on `b.Remote`, returns without relaying
|
||||
3. Gateway router catches the event in `handleReceive`
|
||||
4. `handleEventVotesQuery` fetches data from the Jackbox API:
|
||||
- `GetActiveSession()` to get session ID
|
||||
- `GetSessionGames(sessionID)` to find the game with status "playing"
|
||||
- `GetSessionVotes(sessionID)` to get per-game vote breakdown
|
||||
- `GetGame(gameID)` to get all-time `popularity_score`
|
||||
5. Formats the message and broadcasts via `broadcastJackboxMessage`
|
||||
|
||||
### Failure handling
|
||||
|
||||
All failures are logged at warn level and produce no chat output:
|
||||
- No Jackbox client configured
|
||||
- No active session
|
||||
- No game currently playing
|
||||
- API errors on any of the fetch calls
|
||||
- No vote data found for the current game
|
||||
|
||||
## Files Changed
|
||||
|
||||
- `bridge/config/config.go` -- add `EventVotesQuery` constant
|
||||
- `bridge/jackbox/client.go` -- add `GetSessionGames`, `GetSessionVotes`, `GetGame` methods and response structs
|
||||
- `bridge/irc/handlers.go` -- detect `!votes` command, emit event
|
||||
- `bridge/kosmi/kosmi.go` -- detect `!votes` command, emit event
|
||||
- `gateway/router.go` -- call `handleEventVotesQuery` in `handleReceive`
|
||||
- `gateway/handlers.go` -- implement `handleEventVotesQuery`
|
||||
|
||||
## API Endpoints Used
|
||||
|
||||
- `GET /api/sessions/active` (existing)
|
||||
- `GET /api/sessions/{id}/games` (new client method)
|
||||
- `GET /api/sessions/{id}/votes` (new client method)
|
||||
- `GET /api/games/{id}` (new client method)
|
||||
Reference in New Issue
Block a user