# Jackbox Game Picker API Integration This document describes how the Kosmi/IRC relay integrates with the Jackbox Game Picker API for live voting, game announcements, and room code display. ## Overview When enabled, the relay: 1. **Detects votes** in chat (`thisgame++`/`thisgame--` and ticker-symbol votes) and submits them to the API 2. **Receives game events** via WebSocket (or webhook fallback) and announces them to all bridges 3. **Responds to `!votes`** with the current game's vote tally 4. **Optionally generates room code images** and uploads them to Kosmi ## Configuration Add the `[jackbox]` section to `matterbridge.toml`: ```toml [jackbox] # Enable Jackbox integration Enabled=true # Jackbox API URL APIURL="https://your-jackbox-api.example.com" # Admin password for API authentication (exchanged for JWT) AdminPassword="your_admin_password" # Use WebSocket for real-time game notifications (recommended, default: true) # Set to false to use webhook HTTP server instead UseWebSocket=true # --- Webhook settings (only if UseWebSocket=false) --- # Port for the webhook HTTP server WebhookPort=3001 # HMAC-SHA256 secret for webhook signature verification WebhookSecret="your_webhook_secret" # --- Room code image settings --- # Generate and upload a room code image to Kosmi chat EnableRoomCodeImage=true # Seconds to wait before sending the image announcement (default: 0) RoomCodeImageDelay=28 # Seconds to wait before sending the plaintext room code follow-up (default: 29) RoomCodePlaintextDelay=22 ``` ### Configuration Reference | Key | Type | Default | Description | |-----|------|---------|-------------| | `Enabled` | bool | `false` | Master switch for the integration | | `APIURL` | string | | Base URL of the Jackbox Game Picker API | | `AdminPassword` | string | | Admin password, exchanged for a JWT via `POST /api/auth/login` | | `UseWebSocket` | bool | `true` | Use WebSocket transport for events (recommended) | | `WebhookPort` | int | `3001` | HTTP listen port for webhook server | | `WebhookSecret` | string | | HMAC secret for webhook signature verification | | `EnableRoomCodeImage` | bool | `false` | Generate/upload room code images | | `RoomCodeImageDelay` | int | `0` | Seconds before image announcement | | `RoomCodePlaintextDelay` | int | `29` | Seconds before plaintext room code | ## Transport: WebSocket vs. Webhook ### WebSocket (Recommended) When `UseWebSocket=true`, the relay connects to `wss:///api/sessions/live` and authenticates with its JWT. Events are received in real-time with automatic reconnection. Handled events: - `session.started` -- announces game night start - `game.added` -- announces next game with room code - `session.ended` -- announces game night end No additional setup is required beyond the config above. ### Webhook (Fallback) When `UseWebSocket=false`, the relay starts an HTTP server on `WebhookPort` and listens for `POST /webhook/jackbox` requests from the API. You must register the webhook with the API: ```bash # Get JWT token TOKEN=$(curl -s -X POST "$API_URL/api/auth/login" \ -H "Content-Type: application/json" \ -d '{"key": "your_admin_password"}' | jq -r .token) # Register webhook curl -X POST "$API_URL/api/webhooks" \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{ "name": "Kosmi/IRC Relay", "url": "http://your-relay-host:3001/webhook/jackbox", "secret": "your_webhook_secret", "events": ["game.added"] }' ``` Webhook requests include an `X-Webhook-Signature` header with an HMAC-SHA256 signature for verification. ## Vote Detection The relay automatically detects vote patterns in non-relayed messages from both IRC and Kosmi. ### Supported Syntax | Pattern | Effect | |---------|--------| | `thisgame++` | Upvote currently playing game | | `thisgame--` | Downvote currently playing game | | `SYMBOL++` | Upvote game by ticker symbol | | `SYMBOL--` | Downvote game by ticker symbol | - All patterns are case-insensitive - `thisgame` votes can appear anywhere in the message - Ticker symbols are 2-4 alphanumeric characters that map to specific games (see [IRC.md](../IRC.md) for the full ticker table) - Messages prefixed with `[irc]` or `[kosmi]` are treated as relayed and skip vote detection Votes are submitted to `POST /api/votes/live` with the voter's username, vote type, timestamp, and optional ticker symbol. ### Deduplication The API rejects duplicate votes from the same user within 1 second. ## IRC/Kosmi Commands ### `!votes` Available in both IRC and Kosmi chat. Queries the current game's vote tally and broadcasts the result to all bridges: ``` 🗳️ Fibbage 4 • Today: 5👍 2👎 (Score: 3) • All-time: 46👍 3👎 (Score: 43) ``` Requires an active session with a game currently "playing". ### Reconnect Commands (IRC only) | Command | Effect | |---------|--------| | `!jreconnect` | Reconnect the Jackbox WebSocket | | `!kreconnect` | Reconnect the Kosmi bridge | | `!reconnect` | Reconnect all non-IRC services | ## Room Code Images When `EnableRoomCodeImage=true` and a `game.added` event includes a room code, the relay: 1. Generates an image of the room code 2. Uploads it to the Kosmi CDN (`img.kosmi.io`) 3. Sends the image + announcement message after `RoomCodeImageDelay` seconds 4. Sends a plaintext room code follow-up after `RoomCodePlaintextDelay` seconds If image generation or upload fails, the relay falls back to plaintext-only announcement. ## Mute Control Jackbox announcements (game start, game added, session end) can be suppressed without stopping the relay: - Start muted: `./matterbridge -conf matterbridge.toml -muted` - Toggle at runtime: `kill -SIGUSR1 ` or `docker kill -s SIGUSR1 ` When muted: - Announcements are suppressed - Vote detection still works (votes are still sent to the API) - Normal IRC/Kosmi message relay is unaffected - `!votes` still works See [MUTE_CONTROL.md](MUTE_CONTROL.md) for full details. ## How It Works ### Vote Flow 1. User sends a message containing `thisgame++` (or similar) in IRC or Kosmi 2. The bridge detects the vote pattern (skipping relayed messages) 3. The bridge submits `POST /api/votes/live` with username, vote type, and timestamp 4. The API records the vote against the currently playing game ### Event Flow (WebSocket) 1. The relay authenticates with the Jackbox API and opens a WebSocket 2. When a session starts, the relay subscribes to that session's events 3. `game.added` events trigger game announcements broadcast to all bridges 4. `session.ended` triggers the end-of-night message ### Authentication The relay authenticates with `POST /api/auth/login` using the `AdminPassword` to get a JWT. The token is cached in memory and refreshed automatically on 401 responses. ## Troubleshooting ### Votes Not Being Recorded - Verify an active session exists with games played - Check that the vote timestamp matches a played game's timeframe - Look for `"Detected vote from"` in debug logs - Look for `"Failed to send vote"` errors - Confirm the message isn't prefixed with `[irc]`/`[kosmi]` (relayed messages skip vote detection) ### Announcements Not Appearing - Verify `Enabled=true` in config - Check `APIURL` is accessible and `AdminPassword` is correct - Look for `"Jackbox WebSocket connected"` in logs (if using WebSocket) - If using webhooks, verify the webhook is registered and the port is accessible - Check mute state: look for `"MUTED"` in logs ### WebSocket Disconnects - The relay auto-reconnects with exponential backoff - Use `!jreconnect` from IRC to force an immediate reconnection - Check API server availability ### Authentication Failures ```bash # Test authentication manually curl -X POST "$API_URL/api/auth/login" \ -H "Content-Type: application/json" \ -d '{"key": "your_admin_password"}' ``` ## Disabling Set `Enabled=false` in the `[jackbox]` section and restart. The relay continues to function normally for IRC/Kosmi message relay without any Jackbox features.