A lightweight, multi-server Discord bot that runs an ongoing flag quiz game: it posts a flag image with three button choices, tracks unique correct answers, then automatically posts the next quiz once the server hits a configurable answer threshold.
Built with discord.py 2.4.0 and SQLite.
- Posts a flag quiz card (embed + image attachment + 3 button options)
- Accepts answers via Discord buttons (no message spam, no parsing)
- Counts unique correct users per quiz
- When the count reaches a configurable threshold, it:
- disables the current quiz buttons
- immediately posts the next flag
- Supports multiple guilds with independent settings and rotation state
All commands live under the !flag group (aliases: !ff, !flagfrenzy).
!flag set-channel <#channel|id|name>
Sets where quizzes will be posted.!flag set-threshold <int>
Number of unique correct users required to trigger the next quiz.!flag set-poll <seconds>
Background loop polling interval (minimum 5s).!flag view-settings
Shows current server settings.
!flag start(Manage Server)
Starts the background loop for this server.!flag stop(Manage Server)
Stops the loop.!flag status
Shows whether the loop is running and prints settings.!flag resend(Manage Server)
Immediately posts a quiz (also disables the previous quiz’s buttons).!flag clear-answers [current|all](Manage Server)
Clears recorded correct answers.!flag set-index <number>(Manage Server)
Manually set which index in the shuffled rotation is next.
Using
!flagwith no subcommand shows the built-in help embed.
- The bot chooses the next flag code from a shuffled rotation per guild.
- It attaches the image file (from the DB’s
image_path) and posts an embed. - It creates 3 button options:
- the correct country name
- 2 deterministic “wrong” names chosen from the pool of active flags
- When a user clicks a button:
- if incorrect: they get an ephemeral “try again” response
- if correct: the bot records one correct answer per user per quiz
- Once
thresholdunique users have answered correctly, the bot disables the buttons and posts the next quiz.
The bot also posts an “Answer to Previous Quiz” embed when it moves to the next flag.
- Python 3.10+ recommended
- A Discord application + bot token
discord.py==2.4.0python-dotenv==1.0.1- An SQLite database with the expected tables (schema below)
- Flag images stored locally on disk (paths referenced from the DB)
git clone <your-repo-url>
cd flag-frenzy
python -m venv .venv
# Windows: .venv\Scripts\activate
# macOS/Linux: source .venv/bin/activate
pip install -r requirements.txtCopy .env.example to .env and fill it in:
DISCORD_TOKEN="your_bot_token_here"
DB_PATH=data/flagfrenzy.db
LOG_LEVEL=INFO
COMMAND_PREFIX=!flagNotes:
- The bot code currently uses a hard-coded prefix of
!for the command group (!flag ...), even thoughCOMMAND_PREFIXexists in.env.example. DB_PATHshould point at a writable location. The bot will create directories as needed.
This repo includes the DB access layer (db.py), but the schema migration/creation script is not present in the tree you shared. You’ll need to create the tables yourself once.
Here is a reference schema that matches the queries in db.py:
PRAGMA foreign_keys=ON;
CREATE TABLE IF NOT EXISTS settings (
guild_id INTEGER PRIMARY KEY,
channel_id INTEGER,
answer_threshold INTEGER NOT NULL DEFAULT 5,
poll_seconds INTEGER NOT NULL DEFAULT 60
);
CREATE TABLE IF NOT EXISTS flags (
code TEXT PRIMARY KEY,
name TEXT NOT NULL,
image_path TEXT NOT NULL,
active INTEGER NOT NULL DEFAULT 1
);
CREATE TABLE IF NOT EXISTS rotations (
guild_id INTEGER PRIMARY KEY,
shuffled TEXT NOT NULL DEFAULT '[]',
idx INTEGER NOT NULL DEFAULT 0
);
CREATE TABLE IF NOT EXISTS quizzes (
guild_id INTEGER NOT NULL,
quiz_id TEXT NOT NULL,
code TEXT,
message_id INTEGER,
PRIMARY KEY (guild_id, quiz_id)
);
CREATE TABLE IF NOT EXISTS answers (
guild_id INTEGER NOT NULL,
quiz_id TEXT NOT NULL,
user_id INTEGER NOT NULL,
PRIMARY KEY (guild_id, quiz_id, user_id)
);
CREATE TABLE IF NOT EXISTS app_state (
guild_id INTEGER NOT NULL,
key TEXT NOT NULL,
value TEXT,
PRIMARY KEY (guild_id, key)
);Populate the flags table with rows like:
INSERT INTO flags(code, name, image_path, active)
VALUES ('us', 'United States', 'data/flags/us.png', 1);Make sure image_path points to a real file on disk where the bot runs.
python bot.py- Invite the bot with permissions to send messages and embed links in your chosen channel.
- Run setup:
!flag set-channel #your-channel
!flag set-threshold 5
!flag set-poll 60
- Start the loop:
!flag start
- The bot enables
message_contentintent in code, but the gameplay itself uses slash-free, button-based interactions. - Required channel permissions (recommended):
- View Channel
- Send Messages
- Embed Links
- Attach Files
- Read Message History (to disable previous quiz buttons via fetch/edit)
Admin commands require the invoker to have Manage Server (manage_guild=True).
MIT. See LICENSE.