Skip to content

ucsits/ctfbot

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

104 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

CTFBot 🚩

UCS's specialized Discord bot for managing Capture The Flag (CTF) competitions, now with blockchain-backed task tracking, reputation, and document anchoring powered by Luce.

License: MIT Node.js Version Discord.js

Features

  • πŸ“… Event Scheduling β€” Schedule CTF events with timezone support
  • πŸ—οΈ Channel Management β€” Automatically create dedicated CTF channels
  • πŸ‘₯ User Registration β€” Track team member participation
  • πŸ—„οΈ Database Storage β€” Persistent storage of CTF data and registrations
  • πŸ”— CTFd Integration β€” Ready for CTFd platform integration (coming soon)
  • ⛓️ Blockchain-Backed Tasks β€” Create and track tasks with immutable audit trail
  • πŸ‘ Reputation System β€” Give +1/-1 rep via reactions, replies, or /rep command
  • πŸ“„ Document Anchoring β€” Permanently store documents on the blockchain
  • ⏰ Automatic Reminders β€” Task deadline reminders sent to a dedicated channel

Commands

CTF Commands

  • /schedule β€” Schedule custom events with timezone support
  • /createctf β€” Create a CTF text channel and schedule its event
  • /registerctf β€” Register your participation for the CTF in the current channel
  • /addchalctf β€” Add challenges to a CTF
  • /solvectf β€” Mark a challenge as solved
  • /archivectf β€” Archive a completed CTF
  • /chalpts β€” View challenge points
  • /summarizectf β€” View CTF summary
  • /syncchallenges β€” Sync challenges from CTFd
  • /pact β€” Manage pacts

Task Commands

  • /task add β€” Create a new task (title, description, assignee, deadline)
  • /task list [period] β€” View remaining tasks for this week/month/quarter/year
  • /task done β€” Mark a task as completed

Reputation Commands

  • /rep [downvote] β€” Give +1 or -1 rep (must reply to someone's message; response is ephemeral)
  • /repleaderboard [limit] β€” View the reputation leaderboard

You can also give rep by:

  • Reacting with πŸ‘ or πŸ‘Ž to someone's message
  • Replying to someone with +1, -1, πŸ‘, or πŸ‘Ž

Document Commands

  • /document add β€” Anchor a document to the blockchain
  • /document get β€” Retrieve an anchored document

Utility Commands

  • /ping β€” Check bot responsiveness
  • /help β€” List all available commands

Quick Start

Prerequisites

Installation

  1. Clone the repository

    git clone https://github.com/ucsits/ctfbot.git
    cd ctfbot
  2. Install dependencies

    pnpm install
  3. Configure environment variables

    cp .env.example .env

    Edit .env and fill in the required values:

    • DISCORD_TOKEN β€” Your Discord bot token
    • GUILD_ID β€” Your Discord server ID (for development)
    • CTF_CATEGORY_ID β€” Category ID where CTF channels will be created
    • CTFD_API_TOKEN β€” Your CTFd API token (optional)
    • LUCE_PORT β€” Luce blockchain RPC port (default: 5500)
  4. Run the bot

    Development mode (with auto-reload):

    pnpm dev

    Production mode:

    pnpm start

Setting Up Your Discord Server

  1. Create a CTF Category

    • Right-click in your server's channel list
    • Select "Create Category"
    • Name it "CTF" or similar
    • Right-click the category β†’ Copy ID
    • Paste the ID in .env as CTF_CATEGORY_ID
  2. Invite the Bot

    • Go to Discord Developer Portal
    • Select your application
    • Go to OAuth2 β†’ URL Generator
    • Select scopes: bot, applications.commands
    • Select permissions: Manage Channels, Manage Events, Send Messages, Embed Links, Add Reactions, Read Message History
    • Copy and visit the generated URL

Architecture

src/
β”œβ”€β”€ commands/              # Slash command implementations
β”‚   β”œβ”€β”€ createctf.js       # Create CTF channels and events
β”‚   β”œβ”€β”€ registerctf.js     # User registration for CTFs
β”‚   β”œβ”€β”€ schedule.js        # Generic event scheduling
β”‚   β”œβ”€β”€ task.js            # Blockchain-backed task management
β”‚   β”œβ”€β”€ rep.js             # Reputation command (ephemeral)
β”‚   β”œβ”€β”€ repleaderboard.js  # Reputation leaderboard
β”‚   β”œβ”€β”€ document.js        # Document anchoring
β”‚   β”œβ”€β”€ help.js            # List all commands
β”‚   └── ping.js            # Health check
β”œβ”€β”€ listeners/             # Event listeners
β”‚   β”œβ”€β”€ ready.js           # Bot ready event (starts reminder service)
β”‚   β”œβ”€β”€ messageCreate.js   # Detects reply-based +1/-1/πŸ‘/πŸ‘Ž
β”‚   β”œβ”€β”€ messageReactionAdd.js  # Detects πŸ‘/πŸ‘Ž reaction rep
β”‚   └── applicationCommandRegistriesRegistered.js
β”œβ”€β”€ services/
β”‚   └── reminder.js        # Background reminder poller (every 30s)
β”œβ”€β”€ lib/
β”‚   β”œβ”€β”€ luce/
β”‚   β”‚   └── index.js       # Luce blockchain RPC client
β”‚   β”œβ”€β”€ constants/
β”‚   β”œβ”€β”€ embeds/
β”‚   β”œβ”€β”€ errors/
β”‚   β”œβ”€β”€ helpers/
β”‚   β”œβ”€β”€ middleware/
β”‚   β”œβ”€β”€ utils/
β”‚   └── validators/
β”œβ”€β”€ database/
β”‚   β”œβ”€β”€ repositories/
β”‚   β”‚   β”œβ”€β”€ task.repository.js       # Tasks + reminders queries
β”‚   β”‚   β”œβ”€β”€ reputation.repository.js # Reputation ledger queries
β”‚   β”‚   └── document.repository.js   # Document queries
β”‚   β”œβ”€β”€ connection.js
β”‚   β”œβ”€β”€ index.js
β”‚   └── migrations.js
β”œβ”€β”€ migrations/            # SQL migration files
└── index.js               # Main entry point

Database Schema

Core tables (existing):

  • ctfs β€” Stores CTF competition details
  • ctf_registrations β€” Stores user registrations
  • ctf_challenges β€” Stores CTF challenges
  • ctf_challenge_solves β€” Tracks challenge solves
  • pacts β€” Pact agreements
  • admins β€” Admin user IDs

Blockchain-backed tables (new):

  • tasks β€” Tasks with reference to blockchain block height
  • task_reminders β€” Scheduled reminders for task deadlines
  • reputations β€” Reputation ledger (one entry per giver per day)
  • documents β€” Anchored documents with blockchain reference

Blockchain Block Data Schema

Every block stored on the Luce blockchain has a data field containing a JSON string. Below are the supported schemas with their type discriminator.

πŸ”Ή Task (type: "task")

Created when a user runs /task add.

{
  "type": "task",
  "v": 1,
  "taskId": "a1b2c3d4-...",
  "title": "Implement login page",
  "description": "Build the user authentication UI",
  "assignedTo": "123456789012345678",
  "createdBy": "987654321098765432",
  "deadline": 1740000000
}
Field Type Description
type string Always "task"
v number Schema version (currently 1)
taskId string UUID v4
title string Task title
description string Task description (may be empty)
assignedTo string Discord user ID of assignee
createdBy string Discord user ID of creator
deadline number Unix timestamp (seconds)

βœ… Task Completion (type: "task_done")

Created when a user runs /task done.

{
  "type": "task_done",
  "v": 1,
  "taskId": "a1b2c3d4-...",
  "completedBy": "123456789012345678"
}
Field Type Description
type string Always "task_done"
v number Schema version (currently 1)
taskId string UUID of the completed task
completedBy string Discord user ID of completer

πŸ‘ Reputation (type: "rep")

Created via reaction (πŸ‘/πŸ‘Ž), reply (+1/-1/πŸ‘/πŸ‘Ž), or /rep command.

{
  "type": "rep",
  "v": 1,
  "toUser": "123456789012345678",
  "fromUser": "987654321098765432",
  "amount": 1,
  "reason": "reaction",
  "date": "2026-07-10"
}
Field Type Description
type string Always "rep"
v number Schema version (currently 1)
toUser string Discord user ID of recipient
fromUser string Discord user ID of giver
amount number 1 (upvote) or -1 (downvote)
reason string Trigger source: "reaction", "reply", or "" (slash command)
date string UTC date in YYYY-MM-DD format (enforces daily limit)

Daily limit: A user may only give rep once per UTC calendar day, regardless of target or sign. This is enforced at both the application and database level.

πŸ“„ Document (type: "document")

Created when a user runs /document add.

{
  "type": "document",
  "v": 1,
  "docId": "a1b2c3d4-...",
  "title": "Meeting Notes 2026-07-10",
  "content": "Discussed sprint goals for Q3...",
  "author": "123456789012345678",
  "mimeType": "text/plain"
}
Field Type Description
type string Always "document"
v number Schema version (currently 1)
docId string UUID v4
title string Document title
content string Document content (plain text; base64 for binary in future versions)
author string Discord user ID of author
mimeType string MIME type (default: "text/plain")

Schema Versioning

The v field allows future schema evolution without breaking existing blocks. When introducing a breaking change, increment v and handle both versions in your parser.


Reminder System

A background service (src/services/reminder.js) polls every 30 seconds for unsent task reminders. When a reminder is due (set to 1 hour before the task deadline), it sends a message to the channel ID 1524933314119467200.

Flow:

  1. /task add β†’ creates blockchain block + DB row + reminder schedule
  2. Reminder service polls task_reminders table every 30s
  3. Due reminders are sent to channel 1524933314119467200
  4. Reminder is marked sent = 1 to prevent duplicates

Development

Project Structure

The bot is built using the @sapphire/framework which provides:

  • Structured command handling
  • Event listener system
  • Plugin support
  • TypeScript-ready architecture

Running Tests

pnpm test

Code Style

This project uses tabs for indentation. Please ensure your editor is configured accordingly.

Logging

The bot includes a unified logging system built on top of the Sapphire framework's logger.

Log Levels

Set the LOG_LEVEL environment variable to control verbosity:

Level Usage
error Fatal errors and exceptions only
warn Warnings + errors
info Normal operational messages (default)
debug Detailed debugging information
trace Everything, including individual HTTP request logs
LOG_LEVEL=info

Where Logs Go

All logs are output to stdout (info/debug/trace) and stderr (error/warn). There is no file-based logging β€” use your process manager (e.g., systemd, Docker, PM2) to capture and rotate stdout/stderr.

Logger Architecture

The logger (src/lib/logger.js) works in two modes:

  1. Pre-init mode: Before the bot has logged into Discord, the logger falls back to raw console calls with ISO timestamps.
  2. Post-init mode: Once the SapphireClient is ready, the logger delegates to Sapphire's structured logger for consistent formatting across all commands and listeners.

Context Prefixes

Child loggers with a context prefix are used throughout the codebase:

Prefix Module
[ErrorHandler] src/lib/errorHandler.js
[CTFd] src/lib/ctfd/index.js
[DB] src/database/index.js
[Migration] src/database/migrations.js
[Luce] src/lib/luce/index.js

Adding Logging to a New Module

const { logger } = require('./lib/logger');
const myLog = logger.child('MyModule');

myLog.info('Operation completed successfully');
myLog.error('Something went wrong', error);
myLog.debug('Detailed info: %s', detail);

Logger methods follow the same signature as console.log: logger.info(message, ...optionalArgs).

Contributing

Contributions are welcome! Please read our comprehensive guides:

Quick Start for Contributors

  1. Fork the repository
  2. Clone your fork: git clone https://github.com/YOUR_USERNAME/ctfbot.git
  3. Install dependencies: pnpm install
  4. Create a branch: git checkout -b feature/your-feature
  5. Make your changes
  6. Run linting: pnpm run lint:fix
  7. Commit: git commit -m "feat: add your feature"
  8. Push: git push origin feature/your-feature
  9. Open a Pull Request

See CONTRIBUTING.md for detailed guidelines.

Roadmap

  • Blockchain-backed task management
  • Reputation system (+1/-1 with daily limit)
  • Document anchoring
  • Additional rep triggers (message content, reactions on other platforms)
  • Web dashboard for blockchain explorer
  • Multi-chain support

License

This project is licensed under the MIT License β€” see the LICENSE file for details.

Support

  • Issues: GitHub Issues
  • Discord: Join our server for support and discussions

Acknowledgments


Made with ❀️ by UCS ITS

About

UCS's specialized Discord bot for CTF

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors