This bot connects to Questboard and provides assistance scheduling sessions, providing notifications, and transcribing sessions to create notes.
This repository has been archived on 2026-03-20. You can view files and clone it, but you cannot make any changes to its state, such as pushing and creating new issues, pull requests or comments.
  • Python 99.4%
  • Dockerfile 0.6%
Find a file
2026-03-20 14:41:30 +00:00
.claude Updated install documentation 2026-03-15 18:49:37 -05:00
bot fix: switch from discord.py to py-cord for voice sink support 2026-03-15 20:19:49 -05:00
docs docs: update configuration docs for production deployment 2026-03-15 19:56:49 -05:00
.env.example docs: update configuration docs for production deployment 2026-03-15 19:56:49 -05:00
.gitignore feat: initial scaffold for Quest Board Bot v0.1.0 2026-03-15 01:23:06 -05:00
.pre-commit-config.yaml chore(polish): startup settings fetch, pre-commit hooks, full README (v0.7.0) 2026-03-15 15:08:42 -05:00
BotBuildPlan.md feat: initial scaffold for Quest Board Bot v0.1.0 2026-03-15 01:23:06 -05:00
CHANGELOG.md feat(sessions): /next, /recap, /note, /ask commands + Q&A service (v0.9.0) 2026-03-15 18:31:39 -05:00
docker-compose.yml fix: use HTTP_PORT variable in healthcheck instead of hardcoded 8080 2026-03-17 10:23:27 -05:00
Dockerfile feat: initial scaffold for Quest Board Bot v0.1.0 2026-03-15 01:23:06 -05:00
README.md Archive notice 2026-03-20 14:41:30 +00:00
requirements-dev.txt feat: initial scaffold for Quest Board Bot v0.1.0 2026-03-15 01:23:06 -05:00
requirements.in fix: switch from discord.py to py-cord for voice sink support 2026-03-15 20:19:49 -05:00
requirements.txt fix: switch from discord.py to py-cord for voice sink support 2026-03-15 20:19:49 -05:00

Archiving Repository

2026/03/20: This repository has been moved under the Quest Board repository, and is being archived. Further bot work will continue there under the /bot directory.

Quest Board Bot

A Discord bot companion for Quest Board, the TTRPG session scheduler. It replaces plain webhook notifications with rich interactive Discord messages, records emoji reactions as scheduling votes, and joins voice channels to record, transcribe, and summarise game sessions.

Status

Version Feature Status
v0.1.0 Scaffold & API client Done
v0.2.0 Quest Board additions Done
v0.3.0 Discord notifications Done
v0.4.0 Account linking Done
v0.5.0 Reaction voting Done
v0.6.0 Recording & transcription Done
v0.7.0 Polish & hardening Done
v0.8.0 Attendance RSVP Done
v0.9.0 /next, /recap, /note, /ask Done (needs Quest Board v0.9.0+)

Prerequisites

Quick Start

# 1. Clone the repository
git clone https://github.com/10thTARDIS/Questboard-Bot.git
cd Questboard-Bot

# 2. Copy the example env file
cp .env.example .env

# 3. Fill in required values (see Configuration below)
$EDITOR .env

# 4. Start the bot
docker compose up -d

# Optional: also start the local Whisper transcription service
# (required for /record if WHISPER_MODE=local and no OpenAI key is set)
docker compose --profile whisper up -d

Configuration

All settings are documented in .env.example.

Required:

  • DISCORD_BOT_TOKEN — from Discord Developer Portal → Bot → Token
  • BOT_API_KEY — copy from Quest Board Admin → Bot Settings → Bot API Key

Optional overrides (can also be set in Quest Board Admin → Bot Settings):

  • WHISPER_MODElocal (default, uses bundled Whisper container) or api (OpenAI)
  • SUMMARISER_MODEollama (default) or api (Anthropic/OpenAI)
  • REDIS_URL — enables persistent message→session mapping across bot restarts

Discord Developer Portal Setup

  1. Go to discord.com/developers/applicationsNew Application
  2. Name it (e.g. "Quest Board Bot") and click Create
  3. Bot tab:
    • Click Add BotYes, do it!
    • Under Privileged Gateway Intents, enable:
      • Message Content Intent (required for message content access)
    • Click Reset Token → copy the token to DISCORD_BOT_TOKEN in .env
  4. OAuth2 → URL Generator:
    • Scopes: bot + applications.commands
    • Bot permissions:
      • Read Messages/View Channels — see channels and their content
      • Send Messages — post notification embeds and recording status
      • Send Messages in Threads — if your notification channel uses threads
      • Embed Links — required for rich embeds to render
      • Read Message History — required for reaction handling on older messages
      • Add Reactions — seed 🇦🇧🇨🇩🇪 on proposed sessions and on confirmed sessions
      • Connect — join voice channels to record sessions
      • Use Voice Activity — receive audio streams from participants
    • Copy the generated URL and open it in a browser to invite the bot to your server

Quest Board Admin Setup

After starting the bot, configure it in Quest Board's admin panel:

  1. Admin → Bot Settings:

    • Copy the Bot API Key shown here into BOT_API_KEY in the bot's .env
    • Set Bot URL to http://<bot-host>:8080 — the address Quest Board uses to reach the bot's HTTP server
    • Optionally configure Whisper and LLM endpoints (overrides .env values)
  2. Campaign Settings (per campaign):

    • Guild ID — your Discord server's ID (right-click server icon → Copy Server ID, requires Developer Mode enabled in Discord Settings → Advanced)
    • Notification Channel ID — the text channel where session embeds should appear (right-click channel → Copy Channel ID)

Once all three are set, Quest Board will route session notifications through the bot instead of plain webhooks.

Account Linking

Players connect their Discord identity to Quest Board so reactions are recorded as votes:

  1. Run /link in any server channel where the bot is present
  2. Click the link in the DM the bot sends (expires in 10 minutes)
  3. Log in to Quest Board if prompted, then confirm
  4. The bot sends a confirmation DM — reactions now count as votes

Reaction Voting

Once linked, players vote on proposed session times by reacting to the session embed with the regional indicator emojis (🇦, 🇧, 🇨 …). Adding a reaction records a yes vote; removing it records a no vote.

Attendance RSVP

When a session is confirmed, the bot posts a confirmation embed with and reactions. Players react to indicate whether they'll attend — this writes directly to Quest Board's attendance records. Reactions require a linked account (see Account Linking above).

Session Commands

Command Description
/next Show the next confirmed session with a countdown
/recap <session_id> Show the stored summary and GM notes for a session
/note <text> Add a private note to the next (or a specified) session
/ask <question> Ask a natural-language question about campaign history

/note and /ask require a linked account. /next, /recap, and /note require Quest Board v0.9.0 backend endpoints. /ask additionally requires the v0.10.0 history endpoint — see docs/questboard-improvements.md for what needs to be added on the Quest Board side.

The session_id for /recap and /note is the UUID shown in the Quest Board session URL.

Recording a Session

Recording requires a transcription backend. Choose one:

  • Local Whisper (default) — start the bundled container with docker compose --profile whisper up -d, or configure a URL in Quest Board Admin → Bot Settings
  • OpenAI API — set WHISPER_MODE=api and OPENAI_API_KEY in .env

Only the GM needs to run these commands:

/record start <session_id>   — join your voice channel and begin recording
/record stop                 — stop, transcribe, summarise, and upload

The session_id is the UUID shown in the Quest Board session URL. The bot auto-stops after MAX_RECORDING_HOURS (default: 6) if /record stop is not run manually.

After stopping, the bot:

  1. Mixes all participants' audio to a single mono MP3
  2. Transcribes it (Whisper local or OpenAI API)
  3. Summarises it (Ollama or Anthropic/OpenAI)
  4. Uploads the transcript and summary to Quest Board
  5. Posts a summary embed in the text channel

Whisper model trade-offs

Model Speed Accuracy RAM
base Fastest Good for clear audio ~1 GB
small Moderate Better with accents ~2 GB
medium Slow Most accurate ~5 GB

Set via ASR_MODEL in docker-compose.yml (whisper service). base is the default and works well for most home gaming groups.

Ollama model recommendations

Model Notes
llama3 Good general-purpose default
mistral Fast, good for shorter sessions
mixtral Higher quality, needs 16 GB+ VRAM

Set via OLLAMA_MODEL in .env or Quest Board Admin → Bot Settings.

Development

pip install -r requirements.txt -r requirements-dev.txt

# Install pre-commit hooks (runs pip-audit + linters on commit)
pre-commit install

# Re-pin dependencies after editing requirements.in
pip-compile requirements.in --output-file requirements.txt

# Manual security audit
pip-audit -r requirements.txt

# Run tests
pytest

Architecture

See BotBuildPlan.md for the full design specification.

Quest Board Backend
  │  Celery task fires on session event
  │  POST /notify  →  Bot HTTP server (:8080)
  ▼
questboard-bot
  ├── cogs/notifications.py  ← rich embeds + seed reactions + attendance RSVP
  ├── cogs/voting.py         ← reaction add/remove → votes & attendance API
  ├── cogs/linking.py        ← /link /unlink slash commands
  ├── cogs/recording.py      ← /record start|stop + voice pipeline
  └── cogs/sessions.py       ← /next /recap /note /ask slash commands
        │
        ▼
  services/transcription.py  ← Whisper (local container or OpenAI API)
  services/summarisation.py  ← Ollama, Anthropic, or OpenAI
  services/qa.py             ← campaign Q&A using session summaries as context
        │
        ▼
Quest Board API  (BOT_API_KEY auth via X-Bot-Key header)

Troubleshooting

Bot connects but no notifications appear

  • Confirm Bot URL is set in Quest Board Admin → Bot Settings and points to the bot's host/port
  • Confirm the campaign has Guild ID and Notification Channel ID set
  • Check BOT_API_KEY in .env matches the key in Quest Board Admin → Bot Settings
  • Check docker compose logs bot for any 401 Unauthorized or connection errors

Reactions aren't being recorded as votes

  • The user must run /link first — the bot will DM them a prompt if they react unlinked
  • Confirm REDIS_URL is set if you want vote mappings to survive bot restarts

/record start says "You need to be in a voice channel"

  • The GM running the command must already be connected to a voice channel in the server

Whisper transcription times out or returns empty

  • Check docker compose logs whisper — the container may still be loading the model
  • Try a smaller ASR_MODEL (e.g. base) if RAM is limited
  • For long sessions, the 10-minute transcription timeout may need increasing in bot/services/transcription.py (_TIMEOUT)

Ollama summarisation fails

  • Confirm Ollama is running and the model is pulled: ollama pull llama3
  • Check OLLAMA_URL points to the correct host

/next, /recap, or /note returns "Could not reach Quest Board"

  • These commands require Quest Board backend endpoints added in v0.9.0 (GET /api/bot/guilds/{guild_id}/next-session, GET /api/bot/sessions/{id}/summary, POST /api/bot/sessions/{id}/notes) — check the improvements backlog in docs/questboard-improvements.md for implementation details

/ask returns "No session recordings found"

  • /ask searches sessions that have a stored summary; summaries are only created when a session is recorded with /record start and the transcript is uploaded — run at least one recorded session first
  • /ask also requires the GET /api/bot/guilds/{guild_id}/sessions/history Quest Board endpoint (v0.10.0) to be deployed

/note says account isn't linked

  • Run /link first to connect your Discord account to Quest Board

License

MIT — see LICENSE.