Rewrite README.md and all setup guides to reflect the current native GraphQL WebSocket architecture (replacing stale headless Chrome/WebSocket interception descriptions). Add new docs/IRC.md with complete IRC command reference, vote syntax, and ticker symbol table. Archive pre-edit docs to docs/archive/setup-backup-2026-05-10/ and move historical development notes from docs/ root into docs/archive/. Co-authored-by: Cursor <cursoragent@cursor.com>
7.8 KiB
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:
- Detects votes in chat (
thisgame++/thisgame--and ticker-symbol votes) and submits them to the API - Receives game events via WebSocket (or webhook fallback) and announces them to all bridges
- Responds to
!voteswith the current game's vote tally - Optionally generates room code images and uploads them to Kosmi
Configuration
Add the [jackbox] section to matterbridge.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://<APIURL>/api/sessions/live and authenticates with its JWT. Events are received in real-time with automatic reconnection.
Handled events:
session.started-- announces game night startgame.added-- announces next game with room codesession.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:
# 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
thisgamevotes can appear anywhere in the message- Ticker symbols are 2-4 alphanumeric characters that map to specific games (see 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:
- Generates an image of the room code
- Uploads it to the Kosmi CDN (
img.kosmi.io) - Sends the image + announcement message after
RoomCodeImageDelayseconds - Sends a plaintext room code follow-up after
RoomCodePlaintextDelayseconds
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 <pid>ordocker kill -s SIGUSR1 <container>
When muted:
- Announcements are suppressed
- Vote detection still works (votes are still sent to the API)
- Normal IRC/Kosmi message relay is unaffected
!votesstill works
See MUTE_CONTROL.md for full details.
How It Works
Vote Flow
- User sends a message containing
thisgame++(or similar) in IRC or Kosmi - The bridge detects the vote pattern (skipping relayed messages)
- The bridge submits
POST /api/votes/livewith username, vote type, and timestamp - The API records the vote against the currently playing game
Event Flow (WebSocket)
- The relay authenticates with the Jackbox API and opens a WebSocket
- When a session starts, the relay subscribes to that session's events
game.addedevents trigger game announcements broadcast to all bridgessession.endedtriggers 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=truein config - Check
APIURLis accessible andAdminPasswordis 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
!jreconnectfrom IRC to force an immediate reconnection - Check API server availability
Authentication Failures
# 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.