The Discord bot that runs the Warriors United Clash of Clans family.
Recruiting and onboarding, FWA and CWL coordination, a full ticket desk, and a per-player to-do dashboard β 79 documented slash commands and six always-on background jobs behind a single bot account.
- What it does
- Background jobs
- How it's built
- Repository layout
- Getting started
- Testing
- Documentation
- Deployment
- Working on this repo
- Credits & disclaimer
WU Bot is the operational backbone of the Warriors United Discord server: members manage their own Clash accounts and obligations, recruiters run onboarding end to end, and leadership coordinates FWA wars, CWL, and clan administration β all through slash commands rendered with Discord's Components V2 UI (containers, sections, and media galleries rather than classic embeds).
Every public command lives in the in-app guide (/help) and is inventoried in
extensions/commands/help_catalog.py,
which is updated in the same change as any command it describes. The tables
below are drawn from that catalog.
Members help themselves without pinging leadership: /accounts shows every
Clash account linked to their Discord, /todo shows what those accounts still
owe β war attacks, CWL, raid weekend, and more β and /family-links manages
family roles and open clan links.
Command reference β Start Here (5 commands)
| Command | Description |
|---|---|
/help |
Open this command guide. |
/accounts |
Show every Clash account linked to your Discord. |
/todo |
Show what your linked Clash accounts still need to do. |
/family-links |
Manage your own family roles and open clan links. |
/slap |
Send a playful slap GIF to another member. |
Right-click a user β Apps β Get User ID, or a message β Apps β Get Message ID, to copy Discord IDs directly.
Recruiters get a complete pipeline: a questionnaire for new recruits, a full onboarding dashboard with a guided server walkthrough, one-off and bulk role management, and standing setup posts covering the family overview, war rules, and the strike system. A background task removes the temporary New Recruit role automatically two hours after assignment.
Command reference β Roles & Recruits (8 commands)
| Command | Description |
|---|---|
/role add |
Add one server role to a member. Recruiter/Admin only. |
/role remove |
Remove one server role from a member. Recruiter/Admin only. |
/role manage |
Open bulk role management for a member. Recruiter/Admin only. |
/recruit questions |
Send the recruitment questionnaire to a recruit. |
/recruit dashboard |
Open the complete new-member onboarding dashboard. |
/setup recruit-aboutus |
Post the family overview and onboarding flow. |
/setup recruit-familyparticulars |
Post family particulars and war rules. |
/setup recruit-strikesystem |
Post the strike-system rules. |
Clan administration and the family's FWA toolkit: clan dashboards and info hubs, logo and banner uploads, FWA base layouts, FWA Chocolate lookups, war weight calculation, Town Hall upgrade notes, and one-command war plans for win, loss, blacklist, and mismatch scenarios. The LazyCWL suite snapshots FWA rosters during CWL, pings players who still need to return for sync wars, and can run those pings automatically on a schedule.
Command reference β Clans & FWA (21 commands)
| Command | Description |
|---|---|
/clan dashboard |
Open clan administration and FWA data tools. |
/clan info |
View information about every family clan. |
/clan list |
Pick a clan to view or assign to a recruit. |
/clan upload-images |
Upload a clan logo and banner. |
/fwa bases |
Select and display an FWA base layout. |
/fwa chocolate |
Look up a player or clan on FWA Chocolate. |
/fwa links |
Open FWA verification and war-weight links. |
/fwa new-th-upgrade |
Display FWA Town Hall upgrade notes. |
/fwa points |
Show the latest stored FWA points verdicts. |
/fwa upload-images |
Upload FWA war and active base images. |
/fwa war-plans |
Generate a war plan for win, loss, blacklist, or mismatch. |
/fwa weight |
Calculate war weight from a storage value. |
/fwa lazycwl-snapshot |
Snapshot FWA rosters for LazyCWL tracking. |
/fwa lazycwl-ping |
Ping missing players to return for FWA sync. |
/fwa lazycwl-status |
List active LazyCWL snapshots. |
/fwa lazycwl-roster |
View a LazyCWL snapshot roster. |
/fwa lazycwl-reset |
Deactivate completed LazyCWL snapshots. |
/fwa lazycwl-autopings-start |
Start periodic missing-player pings. |
/fwa lazycwl-autopings-stop |
Stop periodic pings for a snapshot. |
/fwa lazycwl-autopings-status |
Show active auto-ping schedules. |
/fwa lazycwl-remove-player |
Remove players from snapshot tracking. |
A recruitment ticket desk with separate Main and FWA counters: an entry panel for applicants, claim/release/approve/deny for recruiters, a management dashboard, and a channel monitor that keeps ticket records honest. Maintenance commands diagnose drift between Discord channels and stored records, close ghost tickets, repair mismatches, and migrate legacy data.
Command reference β Tickets (14 commands)
| Command | Description |
|---|---|
/ticket claim |
Claim the current ticket. Recruiter only. |
/ticket release |
Release your claim on the current ticket. |
/ticket approve |
Approve the current ticket. Recruiter/Admin only. |
/ticket deny |
Deny the current ticket. Recruiter/Admin only. |
/ticket list |
List all currently open tickets. Recruiter only. |
/ticket dashboard |
Open the ticket management dashboard. Recruiter only. |
/ticket setup |
Post the ticket entry panel. Admin only. |
/ticket config |
Configure ticket roles and categories. Admin only. |
/ticket change-category |
Change the category used for new tickets. Admin only. |
/ticket reset-counter |
Reset Main/FWA ticket counters. Admin only. |
/ticket diagnostics |
Compare ticket channels and stored records. Admin only. |
/ticket cleanup-ghosts |
Close records whose Discord channel is gone. Admin only. |
/ticket fix-mismatched |
Repair status/channel-name mismatches. Admin only. |
/ticket migrate-store |
Copy legacy ticket rows to the tickets collection. Admin only. |
CWL logistics on autopilot: announcement posts, LazyCWL preparation notices, a bonus-medal lottery with named recipients, and a monthly reminder schedule with configurable follow-ups that survives bot restarts.
Command reference β CWL & Reminders (12 commands)
| Command | Description |
|---|---|
/cwl-announcement |
Post a CWL announcement. |
/lazycwl-bonuses |
Randomly select LazyCWL bonus recipients. |
/lazyprep |
Post LazyCWL preparation announcements. |
/cwl-reminder schedule |
Schedule the monthly CWL reminder. |
/cwl-reminder status |
Show the active reminder schedule. |
/cwl-reminder cancel |
Cancel the scheduled reminder. |
/cwl-reminder test |
Send a test reminder. |
/cwl-reminder add-followup |
Add or update a follow-up reminder. |
/cwl-reminder remove-followup |
Remove a follow-up reminder. |
/cwl-reminder list |
List every configured reminder. |
/cwl-reminder test-all |
Test all reminders in sequence. Admin only. |
/cwl-reminder send-now |
Send all reminders immediately. Admin only. |
Admin tooling for running the bot itself: timed polls with named votes, sending
messages as the bot, emoji management, an owner-only /reboot that DMs you when
the bot is back online, and full Discord-side configuration of the BAND sync
alert and FWA points monitors β no shell access required.
Command reference β Admin Tools (19 commands)
| Command | Description |
|---|---|
/poll create |
Create a timed poll with named votes. Admin only. |
/poll view |
View recent polls or named voters for one poll. Admin only. |
/poll active |
List polls that are currently open. Admin only. |
/say |
Send a message as the bot. Restricted role only. |
/steal |
Copy an emoji into the bot application. |
/reboot |
Restart the bot process. Owner only. |
/toggle-debug |
Toggle verbose BAND monitor logging. Admin only. |
/fwasync enable |
Enable BAND iCal sync alerts. Admin only. |
/fwasync disable |
Disable BAND iCal sync alerts. Admin only. |
/fwasync status |
Show BAND sync configuration and state. Admin only. |
/fwasync check |
Fetch feeds and report upcoming syncs without DMs. Admin only. |
/fwasync preview |
Preview the next sync alert in your DMs. Admin only. |
/fwasync set-recipients |
Replace sync-alert recipients. Admin only. |
/fwasync set-offsets |
Replace sync-alert timing offsets. Admin only. |
/fwapoints enable |
Enable the FWA points monitor. Admin only. |
/fwapoints disable |
Disable the FWA points monitor. Admin only. |
/fwapoints watch-add |
Add a clan to the points watch list. Admin only. |
/fwapoints watch-remove |
Remove a clan from the watch list. Admin only. |
/fwapoints status |
Show points-monitor status and records. Admin only. |
Six always-on tasks in extensions/tasks/ do the work
nobody should have to remember:
| Job | Module | What it does |
|---|---|---|
| BAND post monitor | band_monitor.py |
Polls the FWA sync BAND group every 10 minutes over the BAND Open API and announces war-sync posts in Discord. |
| BAND sync alerts | band_sync_ical.py |
Watches the BAND iCal calendar feeds and DMs configured members when a sync is scheduled, approaching, or rescheduled. Ships disabled; turn on with /fwasync enable. |
| Clan history tracker | clan_history_tracker.py |
Discovers cross-clan /todo obligations off the interaction path: roster departures, linked-account watches, and live war/CWL rosters. |
| CWL reminder scheduler | cwl_reminder.py |
Runs the monthly CWL reminder chain and its follow-ups, restoring pending reminders from MongoDB after a restart. |
| FWA points monitor | fwa_points_monitor.py |
Records FWA points verdicts for watched clans. Ships disabled β the upstream site blocks datacenter IPs β so /fwa points degrades gracefully to a link. |
| Recruit role cleanup | recruit_role_cleanup.py |
Removes the New Recruit role two hours after assignment, sweeping in rate-limit-friendly batches every 30 minutes. |
| Layer | Choice | Notes |
|---|---|---|
| Discord gateway | hikari 2.3.5 | Pinned deliberately β hikari and lightbulb are upgraded only as a coupled pair. See docs/hikari-lightbulb-versions.md. |
| Command framework | hikari-lightbulb 3.0.3 | Slash commands, dependency injection, and extension loading. |
| Clash of Clans API | coc.py 3.10.0 | Routed through a hosted API proxy, so no Clash developer key is needed. The pin rationale is documented line by line in requirements.txt. |
| Database | MongoDB via pymongo AsyncMongoClient |
Native async driver (not motor), remote deployment. Collection handles live in utils/mongo.py. |
| Scheduling | APScheduler + stored timestamps | Schedules and deadlines are persisted in MongoDB and re-seeded by a startup reconciler rather than held in memory. |
| Media | Cloudinary + Pillow | Uploaded clan logos, banners, and base images. |
| UI | Discord Components V2 | Containers, sections, separators, and media galleries throughout. See docs/components-v2-in-hikari.md. |
Design decisions worth knowing before reading the code:
- One entry point.
main.pybuilds the gateway bot, wires MongoDB, Cloudinary, and the Clash client into lightbulb's DI registry, then loads an explicit extension list plus everythingutils/startup.pydiscovers. Discovery is AST-based: a module is only treated as an extension if it actually binds a lightbulbloader, so renderers and helpers are never imported by accident. - One component dispatcher. Every button, select menu, and modal routes
through
extensions/components.pywith a shared error boundary. How routing works β and its known sharp edges β is written up indocs/component-dispatcher.md. - Restart safety as a rule. Deadlines are stored timestamps compared to now, never in-memory timers. The bot can be down for two days and settle everything overdue on its first pass.
- Load-bearing comments.
requirements.txtdocuments why each pin exists and what must move together;main.pyrefuses to start on anything older than Python 3.12.3.
WU_Python/
βββ main.py # Entry point: gateway bot, DI wiring, lifecycle hooks
βββ extensions/
β βββ commands/ # Slash commands, one module or package per feature
β β βββ help_catalog.py # the tested inventory of every public command path
β βββ components.py # Central dispatcher for every button, select, and modal
β βββ autocomplete.py # Preloaded autocomplete caches
β βββ context_menus/ # Right-click apps: Get User ID, Get Message ID
β βββ events/ # Channel and message event handlers
β βββ tasks/ # The always-on background jobs
βββ utils/ # Shared services: Mongo, Clash client, parsers, emoji, β¦
βββ tests/ # 42 pytest modules (~960 tests)
βββ tools/ # Read-only diagnosis scripts for live data
βββ docs/ # Project knowledge base β start at docs/README.md
βββ assets/ # Message accent art
Note
WU Bot is purpose-built for a single Discord server. Channel, role, and guild IDs for Warriors United live in configuration and source, so running it elsewhere means adjusting those values β but everything below applies to a development setup too.
Prerequisites
- Python 3.12.3 or newer (enforced at startup)
- A MongoDB deployment and its connection string
- A Discord application with the Server Members and Message Content privileged intents enabled
- A Cloudinary account for image-upload features
Install
git clone https://github.com/SirRuggie/WU_Python.git
cd WU_Python
python -m venv venv
venv/bin/pip install -r requirements.txtConfigure
Create a .env file in the repository root (loaded by python-dotenv):
| Variable | Required | Purpose |
|---|---|---|
DISCORD_TOKEN |
Yes | Discord bot token. |
MONGODB_URI |
Yes | MongoDB connection string. |
CLOUDINARY_API_KEY, CLOUDINARY_API_SECRET |
For image uploads | Cloudinary credentials. |
BAND_ICAL_SYNC1 β¦ BAND_ICAL_SYNC3 |
For sync alerts | BAND iCal feed URLs. Treat these as credentials β see docs/band-ical-feeds.md. |
SYNC_DM_USER_IDS, SYNC_DM_OFFSETS, SYNC_DM_ANNOUNCE_ON_DISCOVERY, SYNC_DM_SUMMARY_FILTER |
For sync alerts | Recipients and timing for sync-alert DMs. |
BAND_DEBUG |
No | Verbose BAND monitor logging (true/false). |
Run
venv/bin/python main.pyThe suite is pure pytest, covering the component dispatcher lifecycle,
schedulers, feed and points parsers, the ticket lifecycle, and more.
conftest.py puts the
repository root on sys.path, so it runs from any working directory:
venv/bin/pip install -r requirements.txt -r requirements-dev.txt
venv/bin/pytestdocs/ is the project's knowledge base β one file per subject, written
because it is fundamental, non-obvious, by-design, or was discovered the hard
way. Start at the index. Highlights:
editing-this-repo.mdβ read before any bulk edit. In-placesed/awk/perlediting is banned here, with the incident history to justify it.todo-dashboard.mdβ the/todofeature as built, including a coc.py enum trap that applies to every Clash state comparison in the repo.hikari-logging-and-warnings.mdβ whyGatewayBot.__init__silently ownsloggingand warning filters.deployment.mdβ the production host, systemd unit, and operator runbook.
Production runs on a Linux VPS under systemd as wu-bot.service, with
Restart=always (which /reboot relies on to come back up) and configuration
supplied by .env rather than the unit file. Deploys are performed manually by
the operator: pull, reinstall requirements into the venv, restart the service.
The full topology, runbook, and host baseline live in
docs/deployment.md.
A few standing rules keep the codebase healthy:
- No in-place stream editing.
sed -i,awk, andperl -piare banned β use a real editor or scripted file rewrite, then run the verification greps indocs/editing-this-repo.md. - Pins move together. hikari + lightbulb upgrade as one pair, and the
coc.py pin has a documented rationale β read the comments in
requirements.txtbefore touching versions. - The help catalog is part of the change. Adding, renaming, or removing a
public command updates
extensions/commands/help_catalog.pyin the same commit. - Durable knowledge goes to
docs/. One file per subject; the index indocs/README.mdlinks every entry. - Run the tests.
pytestbefore handing anything off.
- FWA and FWA Chocolate β the war communities and tools this bot coordinates with.
- Built with hikari, hikari-lightbulb, and coc.py.
This material is unofficial and is not endorsed by Supercell. For more information see Supercell's Fan Content Policy.
