A Discord bot built for the 7th Cavalry Gaming Regiment using Go and DiscordGo, enabling various functions for 7Cav members.
- Go 1.25.0 or higher (see
godirective ingo.mod) - golangci-lint 2.5.0+, built with Go 1.25 or newer
- A C compiler (gcc) if you want to run the tests with
-race
| Command | Purpose |
|---|---|
/milpac |
Return a user's milpac |
/zulu |
Current Zulu time |
/gamertag_search |
Find a user by gamertag |
/awol |
AWOL troopers for a position |
/loa |
Active and upcoming LOAs for a position |
/afsm |
Members eligible for the AFSM in a department |
/s3aar |
Attendance list for events and operations |
/promo |
Tools to gauge promotion eligibility across the regiment |
/billetaudit |
Several audit tools to flag discrepancies in MILPAC |
/apps_beta_deploy |
Deploy the Apps beta version |
/s6-it-check |
S6 IT members eligible for full status |
/warden |
Warden role management |
/warden-bulkadd-internal |
Add a validated unit roster to Verified Warden Internal |
/apps_beta_deploy |
Deploy the Apps beta version |
At https://discord.com/developers/applications:
- 'New Application', then open the 'Bot' tab.
- 'Reset Token' and copy it. This is
DISCORD_TOKEN. It is only shown once! - On the same tab, enable the 'Server Members Intent' under Privileged Gateway
Intents. The bot requests
IntentsGuildMembers; without this the gateway connection fails at startup. A guild is a Discord server. - Create (if you don't have one already) a Discord server that will serve as your test environment for the bot.
- Under 'OAuth2 -> URL Generator', select the
botandapplications.commandsscopes plus the 'View Channels', 'Send Messages', 'Attach Files' and 'Embed Links' permissions, then open the generated URL to invite the bot to your test environment server.
applications.commands is what allows slash commands to register.
Enable 'Developer Mode' in the Discord client ('User Settings' -> 'Advanced'), then right-click a server or channel and choose Copy ID.
Commands register per guild, so GUILD_ID must be the server you are testing in.
Guild commands appear immediately.
Rename .env.example to .env and fill it in.
Startup fails without these:
| Variable | Source |
|---|---|
DISCORD_TOKEN |
Developer Portal -> Bot -> Reset Token |
GUILD_ID |
Right-click the server -> Copy Server ID |
BM_TOKEN |
BattleMetrics -> Account -> Developers. Only /s3aar uses it; any non-empty placeholder works otherwise. |
Not checked at startup, but required in practice:
| Variable | Source |
|---|---|
BEARER |
API token for api.7cav.us. Every api call fails without it, and there is no startup error. Check this if lookups fail. |
When adding a new variable, add it to both .env.example and the
environment: block in docker-compose.yml. Compose does not pass through
variables that are not listed, so skipping the second step means the value never
reaches the container.
go build -o cavbot2 .
go run .A healthy startup logs Registering commands, then
Bot is now running. Press CTRL-C to exit.
| Symptom | Likely cause |
|---|---|
Panic naming DISCORD_TOKEN, GUILD_ID or BM_TOKEN |
Variable missing from .env |
| Gateway connection fails | Server Members Intent not enabled |
| Commands never appear | Bot invited without applications.commands, or GUILD_ID is not the server you are in |
| Every milpac lookup fails | BEARER missing or expired |
FORUM_DB_DSN not set warning |
Expected without a forum database; only affects LOA |
| golangci-lint reports a Go version mismatch | Binary was built with an older Go than go.mod targets; reinstall 2.5.0+ |
Run the tests:
go test ./...Run tests with the coverage floor check (matches CI):
go test ./... -race -cover | .github/scripts/check-coverage-floors.shCI enforces per-package coverage floors via .github/scripts/check-coverage-floors.sh. When a PR raises a package's coverage by more than a point or two, raise its floor in the same PR — that's how the suite ratchets up without the team having to think about it.
Contributions are welcome through issues and pull requests on our GitHub repository.
Licensed under the MIT License.